使用pytest框架执行测试样例的方法很多种,我们可以看下pytest的帮助命令
C:\Users\DELL>pytest-h
usage: pytest[options] [file_or_dir] [file_or_dir] [...]
positionalarguments:
file_or_dir
general:
-k EXPRESSION only run tests which match the givensubstring
expression. Anexpression is a python evaluatable
expression where allnames are substring-matched
against test names andtheir parent classes. Example:
-k 'test_method ortest_other' matches all test
functions and classes whose namecontains
'test_method' or'test_other', while -k 'not
test_method' matchesthose that don't contain
'test_method' in theirnames. -k 'not test_method and
not test_other' willeliminate the matches.
Additionally keywordsare matched to classes and
functions containingextra names in their
'extra_keyword_matches'set, as well as functions
which have namesassigned directly to them.
-m MARKEXPR only run tests matching given markexpression.
example: -m 'mark1 andnot mark2'.
….
pytest 有时也被称为 py.test,是因为它使用的执行命令是 py.test。本文中我们使用 pytest 指代这个测试框架,py.test 特指运行命令。
假如在D:\pytestwork目录下存在两个测试文件,分别为
#D:\pytestwork\test_1.py
def test_f1():
assert 1==1
def notest_f1():
assert 2==2
#D:\pytestwork\test_2.py
def test_f2():
assert3==3
def notest_f2():
assert4==4
#D:\pytestwork\subdir
class Test_c1:
deftest_instr(self):
x="in china"
assert 'china' in x
defnotest_instr(self):
x="in china"
assert 'chinese' in x
def test_sub1():
assert 3==1
以上述文件为例,看一下测试执行情况
直接执行pytest
这种方式pytest(或用py.test)程序默认从当前目录中搜集测试用例,即在哪个目录下运行pytest命令,则从哪个目录及其子目录当中搜索测试脚本。事先配置好环境变量。格式命令如
py.test # run all tests below current dir
切换到测试文件所在路径,执行pytest
C:\Users\DELL>D:
D:\>cd pytestwork
D:\pytestwork>pytest
=================================================test session starts ================================================= #一段会话就是pytest的一次调用
platform win32 -- Python 3.6.4,pytest-5.0.1, py-1.8.0, pluggy-0.12.0 #测试平台、python版本、pytest版本
rootdir: D:\pytestwork #当前执行目录
collected 4 items #表示收集到4个测试条目
test_1.py . #文件名+测试结果,点代表测试通过,F表示测试失败,百分数表示执行到该文件时所执行的测试条目占总测试条目的百分比 [ 25%]
test_2.py . [ 50%]
subdir\test_s1.py .F [100%]
=============================================================FAILURES ==============================================================
_____________________________________________________________test_sub1 _____________________________________________________________
def test_sub1():
> assert 3==1
E assert 3 ==1
subdir\test_s1.py:11: AssertionError #断言异常所在的行数
================================================ 1failed, 3 passed in 0.22 seconds=================================================
D:\pytestwork>
注意这种情况下,文件名称必须以“test_”开头或“_test”结尾,否则失败,仅仅test开头或结尾也不行。
指定路径
pytest命令后接测试文件路径运行特定路径下的测试文件,格式
py.test somepath # run all tests below somepath
如
D:\pytestwork>pytest subdir
…
collected 2 items
subdir\test_s1.py .F [100%]
=============================================================FAILURES ==============================================================
_____________________________________________________________test_sub1 _____________________________________________________________
deftest_sub1():
> assert 3==1
E assert 3 == 1
subdir\test_s1.py:11:AssertionError
================================================1 failed, 1 passed in 0.04 seconds=================================================
D:\pytestwork>
更进一步,可以指定到具体执行的某个文件。这种情况下,文件的名字就可以不以test_作为前缀或以_test作为后缀,但文件内部的测试例仍需要按照规范书写。如在subdir下增加一个文件
D:\pytestwork\subdir\notest_s2.py
def test_f3():
assert3==3
def notest_f3():
assert4==4
运行
D:\pytestwork>pytest subdir\notest_s2.py
…..
collected 1 item
subdir\notest_s2.py . [100%]
=====================================================1 passed in 0.13 seconds ======================================================
D:\pytestwork>
-k表达式
这将运行包含与给定字符串表达式匹配的名称的测试,表达式中使用文件名,类名和函数名作为变量,使用and、or、not作为运算符,格式
py.test -k stringexpr # only run tests with namesthat match the
# the "stringexpression", e.g. "MyClass and not method"
# will select TestMyClass.test_something
# but notTestMyClass.test_method_simple
如
D:\pytestwork>pytest subdir\test_s1.py -k"not instr and sub1"
….
collected 2 items / 1 deselected / 1 selected
subdir\test_s1.py F [100%]
=============================================================FAILURES ==============================================================
_____________________________________________________________test_sub1 _____________________________________________________________
deftest_sub1():
> assert 3==1
E assert 3 == 1
subdir\test_s1.py:11:AssertionError
==============================================1 failed, 1 deselected in 0.05 seconds===============================================
D:\pytestwork>
上述"not instr and
sub1"表达式需要使用双引号,不能使用单引号。该表达式的意思是pytest收集到的两个测试项(Test_c1::test_instr、test_sub1)只有test_sub1匹配该表达式。
又如" instr and sub1"将不会匹配到任何测试项,因为没有那个测试项的名称中同时存在instr和sub1字符串。
D:\pytestwork>pytest subdir\test_s1.py -k "instr and sub1"
….
collected 2 items / 2 deselected
===================================================2 deselected in 0.01 seconds====================================================
D:\pytestwork>
nodeid
每个收集的测试都分配了一个唯一的nodeid,它由模块文件名和后跟说明符组成,这些说明符来自参数化的类名,函数名,由::分隔,格式
py.test test_mod.py::test_func # only run teststhat match the "node ID",
# e.g "test_mod.py::test_func"will select
# only test_funcin test_mod.py
如,
D:\pytestwork>py.test "subdir\test_s1.py::Test_c1::test_instr"
….
collected 1 item
subdir\test_s1.py . [100%]
=====================================================1 passed in 0.02 seconds ======================================================
D:\pytestwork>
上述命令就是执行test_s1模块中Test_cl类中的test_instr方法。
main()方法
前面介绍的运行方法,都需要指定使用“pytest文件名”去运行,实际上我们可以直接运行某个文件,只不过需要在测试文件中倒入pytest,即声明使用pytest框架运行这个文件,然后,使用main()方法调用。如修改test_s1.py文件
import pytest
class Test_c1:
deftest_instr(self):
x="in china"
assert 'china' in x
defnotest_instr(self):
x="in china"
assert 'chinese' in x
def test_sub1():
assert3==1
if __name__ == "__main__":
pytest.main(["-q", "test_s1.py"]) #-q表示减少冗余的输出
测试如下
D:\pytestwork\subdir>test_s1.py
.F [100%]
=============================================================FAILURES ==============================================================
_____________________________________________________________test_sub1 _____________________________________________________________
deftest_sub1():
> assert 3==1
E assert 3 == 1
test_s1.py:13:AssertionError
1 failed, 1 passed in 0.17 seconds
D:\pytestwork\subdir>
使用这种方法一个最大的好处是可以在命令行中传入参数。