pytest
一、安装
pip install pytest
安装完成之后查看版本
pytest --verson
【注】如果因为pip不是最新的安装失败,可以移步ModuleNotFoundError: No module named ‘pip‘
二、使用规则
要想pytest在不同函数或者包中发现测试用例,需要按照下述规则来定义文件名、类名或者函数名:
- 文件名以test_开头的py文件 ;
- 以test_开头的函数 ;
- 以Test开头的类;
Pytest会在test_*.py 或者 *_test.py 文件中,寻找class外边的test_开头的函数,或者Test开头的class里面的test_开头的方法,将这些函数和方法作为测试用例来管理;
三、示例
# 文件名为 test_firstcase.py
def func(x):
return x+1
def test_one():
assert func(1) == 2
上述即为一个简单的例子,终端执行 pytest test_firstcase.py
,出现如下图所示即测试通过
来一个测试失败的示例:
def func(x):
return x+1
def test_one():
assert func(1) == 4
很显然,1+1 ≠ 4,测试失败,运行结果如下:
四、pytest各种参数的使用
使用pytest --help
可以看到pytest常用的参数,依次举例试一下前面常用的几个
1、 -k EXPRESSION
即:只运行与给定字符串表达式匹配的测试用例
#文件名为 testcase.py
class TestClass(object):
def test_one(self):
assert 3 == 5
def test_two(self):
assert 'h' in 'hello'
执行pytest -k "test_one and not test_two" testcase.py
,即只执行test-one而不执行test-two,运行结果如下:
如图显示,1failed,1 deselected,一个运行失败,一个没有被选择执行
2、 -m MARKEXPR
即:只运行有相应标识的测试用例,使用这个参数,测试用例要使用@pytest.mark.marker修饰
#文件名为 testcase.py
import pytest
class TestClass(object):
def test_one(self):
assert 1 == 1
def test_two(self):
assert 'h' in 'hello'
@pytest.mark.slow
def test_three(self):
assert 3 == 3
def test_four(self):
assert 3 < 5
@pytest.mark.faster
def test_five(self):
assert 'a' == 'a'
如上面代码所示,总共定义了五个测试用例,标记了两个,执行pytest -m "slow and faster" testcase.py
,则会执行被标记的用例,执行结果如下:
出现上图情况,百度之后发现是缺少pytest.ini文件,在文件里添加
[pytest]
markers = slow
faster
运行后重新执行pytest -m slow testcase.py
,结果如下:
3、–maxfail=num
即:当错误个数达到num时,停止测试,示例:
from operator import add
import pytest
class TestClass(object):
def test_one(self):
assert 1 == 2
def test_two(self):
assert 'h' in 'ello'
@pytest.mark.slow
def test_three(self):
assert 3 == 4
def test_four(self):
assert 3 < 5
# @pytest.mark.faster
def test_five(self):
assert add(1, 2) == 3
执行pytest --maxfail=2 testcase.py
如上图可以看出,当失败用例等于2时,停止执行后面的测试用例;
同理:
pytest -x #遇到失败直接停止,不详细举例
4、-v
即:输出更加详细的用例执行信息,包括用例所在的文件名、类名和函数名等
执行 pytest -v testcase.py
,结果如下:
5、-s
即:会显示在代码中的print内容
from operator import add
import pytest
class TestClass(object):
def test_one(self):
# assert 1 == 2
print('just a test')
def test_two(self):
assert 'h' in 'hello'
@pytest.mark.slow
def test_three(self):
assert 3 == 4
def test_four(self):
assert 3 < 5
# @pytest.mark.faster
def test_five(self):
assert add(1, 2) == 3
执行 pytest -s testcase.py
,运行结果为
6、–collect-only
即:查看pytest 收集到哪些测试用例:
执行 pytest --collect-only 可以看到,总共收集到6个测试用例,且在不同的.py文件中
7、fixtures 之 tmpdir
pytest内置fixtures 之 tmpdir 的作用是: 在本地生成临时文件夹,并返回文件对象
代码示例:
# 内置 fixtures 之 tmpdir 的作用是:在本地生成临时文件夹,并返回文件对象
# 文件名为 test_tmdir.py
def test_needsfiles(tmpdir):
print(tmpdir)
assert 0
执行 pytest test_tmdir.py
结果显示如下:
如图显示的路径,可以在C盘找到创建的文件夹
8、-r
即可以用来在测试结束后展示一份“测试概要信息,常用的**-r**后追加的参数有:
f - failed
E - error
s - skipped
x - xfailed
X - xpassed
p - passed
P - passed with output
a - all except pP
代码示例:
# test_example.py
import pytest
@pytest.fixture
def error_fixture():
assert 0
def test_ok():
print('ok')
def test_fail():
assert 0
def test_error(error_fixture):
pass
def test_skip():
pytest.skip("skipping this test")
def test_xfail():
pytest.xfail("xfail this test")
@pytest.mark.xfail(reason = 'always xfail')
def test_xpass():
pass
执行pytest test_example.py -ra
,结果如下,可以看到 a 表示"除了passes的所有信息;
如果想看**“failed"和"skipped”**的测试结果,可以执行pytest test_example.py -rfs
,结果如下:
9、–durations
即统计用例运行时间,使用方法是 –durations=N ,当 N=0 的时候显示全部用例的运行时间;–
如果我们只需要筛选出运行时间最慢的3条用例,可以设置–durations=3
代码示例:
from operator import add
from time import sleep
import pytest
class TestClass(object):
def test_one(self):
# assert 1 == 2
sleep(3)
print('11111111111111')
def test_two(self):
sleep(2)
assert 'h' in 'hello'
def test_three(self):
sleep(1)
print('33333333333')
assert 3 == 4
def test_four(self):
assert 3 < 5
def test_five(self):
assert add(1, 2) == 3
执行pytest test_case.py --durations=0 -vv
,结果如下:
可以看到,显示了每个测试用例持续的运行时间;
运行pytest test_case.py --durations=2 -vv
,我们看一下持续运行时间最长的两个用例,按照代码显示,应为test_one和test_two,运行结果如下:
五、pytest 运行方式
1、单独执行某个测试文件
pytest testcase.py
2、执行改目录下的所有测试用例
pytest testcases
3、单独执行某个测试用例
# 以函数形式的用例
pytest test_firstcase.py::test_one
# 以类形式的用例
pytest testcase.py::TestClass::test_one
【注】Pytest之paramtrize参数化请移步paramtrize