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 pip
installation 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 assert
the 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.py
and test_*.py
documents.
In these files, all test
prefixed methods or functions are executed . Among them, if the class method needs to Test
start 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 TestClassOne
two tests in execution can use commands:
pytest test_class2.py::TestClassOne
Only the running TestClassOne
test test_one
can use the command:
pytest test_class2.py::TestClassOne::testone
5. Display print information
When testing, print
statements may be added to the code to generate some information. You can use parameters -s
to pytest
output 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 num
is 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 num
is the number of retries:
pytest test_*.py -reruns num
8. Affirmation
8.1 Affirmation
assert
For determining an expression, the expression condition is False
triggered when abnormal. The syntax format is:
assert Expression
Equivalent to
if not expression:
raise AssertionError
assert
You can also follow the parameters to start the corresponding error type. It will also be pytest
correspondingly 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.approx
to 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.testing
to assist in comparison. For details, please refer to its documentation .