pytest tutorial (2): how to call pytest and create a test demo

1. Install pytest

pytest requires: Python 3.6, 3.7, 3.8, 3.9 or PyPy3.
(1) Execute the following command on the command line:

pip install -U pytest

Results of the:
insert image description here

(2) Check if you have the correct version installed:

(venv) E:\auto_pytest>pytest --version
pytest 6.2.3

2. Create the first test

Create a new file called test_sample.py containing a function and a test:

#!/usr/bin/env python 
# encoding: utf-8 
"""
@author: 九九的金金子
@file: test_sample.py.py
@time: 2021/4/12 11:56
"""
# content of test_sample.py
def func(x):
    return x + 1


def test_answer():
    assert func(3) == 5

Execution and results:

(venv) E:\auto_pytest>pytest test_sample.py
========================================================================== test session starts ==========================================================================
platform win32 -- Python 3.7.9, pytest-6.2.3, py-1.10.0, pluggy-0.13.1
rootdir: E:\auto_pytest
plugins: allure-pytest-2.8.32
collected 1 item                                                                                                                                                         

test_sample.py F                                                                                                                                                   [100%]

=============================================================================== FAILURES ================================================================================
______________________________________________________________________________ test_answer ______________________________________________________________________________

    def test_answer():
>       assert func(3) == 5
E       assert 4 == 5
E        +  where 4 = func(3)

test_sample.py:14: AssertionError
======================================================================== short test summary info ========================================================================
FAILED test_sample.py::test_answer - assert 4 == 5
=========================================================================== 1 failed in 0.13s ===========================================================================

[100%] refers to the overall progress of running all test cases. Upon completion, pytest displays a failure report because func(3) does not return 5.

Note:
You can use assert statements to verify test expectations. Intermediate values ​​of assert expressions will be intelligently reported within pytest's advanced assertions.

3. Run multiple tests

pytest will run all files of the form test_.py or _test.py in the current directory and its subdirectories. More generally, it follows standard test discovery rules.
Assert that an exception was raised
Use the raises helper to assert that some code raised an exception:

#!/usr/bin/env python 
# encoding: utf-8 
"""
@author: 九九的金金子
@file: test_sysexit.py
@time: 2021/4/12 13:49
"""
# content of test_sysexit.py
import pytest


def f():
    raise SystemExit(1)


def test_mytest():
    with pytest.raises(SystemExit):
        f()

Execution and results:

(venv) E:\auto_pytest>pytest -q test_sysexit.py
.                                                                                                                                                                  [100%]
1 passed in 0.12s

The q/ --quiet flag keeps the output short in this and the following examples.

4. Group multiple tests into a class

Once you have developed multiple tests, you may wish to group them into a class. pytest makes it easy to create classes containing multiple tests:

#!/usr/bin/env python 
# encoding: utf-8 
"""
@author: 九九的金金子
@file: test_class.py
@time: 2021/4/12 13:52
"""
# content of test_class.py
class TestClass:
    def test_one(self):
        x = "this"
        assert "h" in x

    def test_two(self):
        x = "hello"
        assert hasattr(x, "check")

pytest discovers all tests that follow the Python test discovery convention, so it discovers two functions prefixed with test_. No need to subclass anything, but make sure to prefix the class with Test, otherwise the class will be skipped. We can run a module simply by passing its filename:
execute with result:

(venv) E:\auto_pytest>pytest -q test_class.py
.F                                                                                                                                                                 [100%]
=============================================================================== FAILURES ================================================================================
__________________________________________________________________________ TestClass.test_two ___________________________________________________________________________

self = <test_class.TestClass object at 0x000001934888F248>

    def test_two(self):
        x = "hello"
>       assert hasattr(x, "check")
E       AssertionError: assert False
E        +  where False = hasattr('hello', 'check')

test_class.py:16: AssertionError
======================================================================== short test summary info ========================================================================
FAILED test_class.py::TestClass::test_two - AssertionError: assert False
1 failed, 1 passed in 0.12s

The first test passed, the second failed. You can easily see intermediate values ​​in the assertion to help you understand why it failed.

Grouping tests in classes is beneficial for the following reasons:

  • test organization
  • Only share fixtures for tests in that particular class
  • Applies tags at the class level and implicitly applies them to all tests into the translation page

When grouping tests into classes, it is important to note that each test has a unique instance of the class. Having every test share the same class instance is very bad for test isolation and promotes poor testing practices. This is outlined as follows:

#!/usr/bin/env python 
# encoding: utf-8 
"""
@author: 九九的金金子
@file: test_class_demo.py
@time: 2021/4/12 13:56
"""
# content of test_class_demo.py
class TestClassDemoInstance:
    def test_one(self):
        assert 0

    def test_two(self):
        assert 0

Execution and results:

(venv) E:\auto_pytest>pytest -k TestClassDemoInstance -q
FF                                                                                                                                                                 [100%]
=============================================================================== FAILURES ================================================================================
____________________________________________________________________ TestClassDemoInstance.test_one _____________________________________________________________________

self = <test_class_demo.TestClassDemoInstance object at 0x00000228F08E27C8>

    def test_one(self):
>       assert 0
E       assert 0

test_class_demo.py:11: AssertionError
____________________________________________________________________ TestClassDemoInstance.test_two _____________________________________________________________________

self = <test_class_demo.TestClassDemoInstance object at 0x00000228F08DE748>

    def test_two(self):
>       assert 0
E       assert 0

test_class_demo.py:14: AssertionError
======================================================================== short test summary info ========================================================================
FAILED test_class_demo.py::TestClassDemoInstance::test_one - assert 0
FAILED test_class_demo.py::TestClassDemoInstance::test_two - assert 0
2 failed, 5 deselected in 0.19s

Note that attributes added at the class level are class attributes, so they will be shared between tests.

5. Request a unique temporary directory for functional tests

pytest provides built-in fixture/function arguments to request arbitrary resources, such as a unique temporary directory:

#!/usr/bin/env python 
# encoding: utf-8 
"""
@author: 九九的金金子
@file: test_tmp_path.py
@time: 2021/4/12 13:58
"""
# content of test_tmp_path.py
def test_needsfiles(tmp_path):
    print(tmp_path)
    assert 0

List the name tmp_path in the test function signature, and pytest will look up and call the fixture factory to create the resource before executing the test function call. Before running the tests, pytest creates a temporary directory unique to each invocation of the test:
execution and results:

(venv) E:\auto_pytest>pytest -q test_tmp_path.py
F                                                                                                                                                                  [100%]
=============================================================================== FAILURES ================================================================================
____________________________________________________________________________ test_needsfiles ____________________________________________________________________________

tmp_path = WindowsPath('C:/Users/01399256/AppData/Local/Temp/pytest-of-01399256/pytest-2/test_needsfiles0')

    def test_needsfiles(tmp_path):
        print(tmp_path)
>       assert 0
E       assert 0

test_tmp_path.py:11: AssertionError
------------------------------------------------------------------------- Captured stdout call --------------------------------------------------------------------------
C:\Users\01399256\AppData\Local\Temp\pytest-of-01399256\pytest-2\test_needsfiles0
======================================================================== short test summary info ========================================================================
FAILED test_tmp_path.py::test_needsfiles - assert 0
1 failed in 0.19s

More information on temporary directory handling can be found in Temporary Directories and Files.

Find out what type of built-in pytest fixture exists for that command:

pytest --fixtures   # shows builtin and custom fixtures

Note that unless the -v option is added, this command will omit fixtures starting with _.

Guess you like

Origin blog.csdn.net/daxiangaifashi/article/details/115620126