Python debugging test-pytest

pytest

In engineering and practical applications, we often encounter places where we need to test. And pytest is a very convenient and easy-to-use tool for small tests.
For details, please refer to the official document

1. Installation

You can use the pipinstallation directly , enter the following command:

pip install -U pytest

You can check the corresponding version number through the following command:

pytest --version

2 write a test

Using pytest is essentially searching for the corresponding file in the directory, and executing and checking whether there is an error. The following is a simple example:

# content of test_sample.py
def func(x):
    return x + 1
def test_answer():
    assert func(3) == 5 # 该测试会失败,func(3)应该为4

After writing the program, type in the command line in the directory:

pytest ./test_sample.py

Then it will detect assertthe authenticity of the asserted content and display the corresponding information:

========================================== test session starts ========================================== 
platform win32 -- Python 3.7.7, pytest-6.0.1, py-1.9.0, pluggy-0.13.1
rootdir: C:\Users\dell\Desktop\TEST\py_tmp
collected 1 item

test_sample.py F                                                                                  [100%]

=============================================== FAILURES ================================================
______________________________________________ test_answer ______________________________________________

    def test_answer():
>       assert func(3) == 5 # 该测试会失败,func(3)应该为4
E       assert 4 == 5
E        +  where 4 = func(3)

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

Where [100%] means that all test cases have been tested. After the test is completed, pytest will display a failure report because func(3) does not return 5 but 4.

3. pytest conventions

pytest will test the current directory as all forms *_test.pyand test_*.pydocuments.
In these files, all testprefixed methods or functions are executed . Among them, if the class method needs to Teststart with the class and there is no __init__()method.

4. Categorize tests

You can use classes to distinguish different tests, for example:

# 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")

At this point pytest will test two tests in the Test class. You can use command parameters -q( -quite) to indicate simplified output. The test will pass one and fail one. The specific results are:

pytest -q test_class.py
.F                                                                   [100%]
================================= FAILURES =================================
____________________________ TestClass.test_two ____________________________

self = <test_class.TestClass object at 0xdeadbeef>

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

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

When there are multiple test classes in a file, as follows:

# content of test_class2.py
class TestClassOne(object):
    def test_one(self):
        x = "this"
        assert 't'in x

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


class TestClassTwo(object):
    def test_one(self):
        x = "iphone"
        assert 'p'in x

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

You can use commands to specify tests within a certain class:
only TestClassOnetwo tests in execution can use commands:

pytest test_class2.py::TestClassOne

Only the running TestClassOnetest test_onecan use the command:

pytest test_class2.py::TestClassOne::testone

5. Display print information

When testing, printstatements may be added to the code to generate some information. You can use parameters -sto pytestoutput this information at runtime :

pytest test_se.py -s

6. Multi-process running test

When the number of tests is large, the running time will be longer. At this time, multiple processes can be used for testing. Need to download and install first pytest-xdist:

pip install -U pytest-xdist

When using pytest, just specify the parameters -n num, which numis the number of processes:

pytest test_*.py -n num

7. Retry running the test

Sometimes the test may fail due to other reasons, and you need to retry to run a test multiple times. Need to download and install pytest-rerunfailures:

pip install -U pytest-rerunfailures

When using pytest, specify the parameters --reruns num, which numis the number of retries:

pytest test_*.py -reruns num 

8. Affirmation

8.1 Affirmation

assertFor determining an expression, the expression condition is Falsetriggered when abnormal. The syntax format is:

assert Expression

Equivalent to

if not expression:
    raise AssertionError

assertYou can also follow the parameters to start the corresponding error type. It will also be pytestcorrespondingly displayed in the error message in use .

assert expression [, arguments]

8.2 Assertions are almost equal

When using assertions, floating-point numbers cannot directly use assertions to make judgments, and the result will generally be failure. The reason is that the truncation of floating-point numbers results in a slight deviation from the actual value.
Several common writing methods are:

assert x - esp <= y <= x + esp		# esp = 1e-6
assert abs(x-y) < esp				# esp = 1e-6

But for arrays, tuples, dictionaries, etc., data needs to be extracted for comparison. In fact, we can use pytest.approxto assert that they are almost equal. An example is as follows:

assert 2.2 == pytest.approx(2.3)		
# 失败,默认允许2.3e-6的误差
assert 2.2 == pytest.approx(2.3, 0.1)	
# 成功,指定误差是0.1
assert [0.1 + 0.2, 0.2 + 0.4] == pytest.approx([0.3, 0.6])
# 成功,适用于断言一维数组
assert {
    
    'a': 0.1+0.2} == pytest.approx({
    
    'a': 0.3})
# 成功,适用于断言字典
assert [[0.1 + 0.2], [0.2 + 0.4]] == pytest.approx([[0.3], [0.6]])
# 失败,目前pytest不支持多维数组等类型

In fact, we can also use it numpy.testingto assist in comparison. For details, please refer to its documentation .

Guess you like

Origin blog.csdn.net/weixin_43762938/article/details/108094778