在中简单介绍了pytest的安装和简单使用,接下来我们就要实际了解pytest了
一、pytest的用例发现规则
pytest可以在不同的函数、包中发现用例,发现的规则如下
- 文件名以test_开头的py文件
- 以test_开头的函数
- 以Test开头的类
- 以test_开头的方法(与2类似)
- 要注意的是所有的包必须要有init.py文件(在使用各种编辑器时会自动生成)
二、pytest运行方式
1、单独执行某一个py文件里所有的用例
pytest test_mod.py
2、执行目录下所有的用例
pytest testing/
会按发现规则执行该目录下符合的用例
3、单独执行某一个用例
以函数形式的用例pytest test_mod.py::testfunc以类形式的用例pytest testmod.py::testclass::test_method
三、pytest的测试框架(fixture)模式---xUnit格式
pytest支持以xUnit格式型的测试模型(setup/teardown),但还与python自带的unittest还是有一点差别,如下
- 模块形式----使用setup_module/teardown_module
- 函数形式----使用setup_function/teardown_function
- 类形式----使用setup_class/teardown_class
- 方法形式---使用setup_method/teardown_method
说了还是不好理解,我们还是通过例子还呈现
1、pytest以函数形式形成测试用例
from __future__ import print_function def setup_module(module): print('\nsetup_module()') def teardown_module(module): print('teardown_module()') def setup_function(function): print('\nsetup_function()') def teardown_function(function): print('\nteardown_function()') def test_1(): print('- test_1()') def test_2(): print('- test_2()')
运行结果如下:
通过结果可以看出,各顺序如下
setup_module()----->setup_function()----->test_1----->teardown_function()----->setup_function()----->test_2--->teardown_function()---->teardown_module()
setup_module()和teardown_module只会在开始测试及测试结束时各运行一次
而setup_function()和teardwon_function会在每个用例开始前及结束后各运行一次
2、pytest以类形式的测试用例
from __future__ import print_functionclass TestClass: @classmethod def setup_class(cls): print ('\nsetup_class()') @classmethod def teardown_class(cls): print ('teardown_class()') def setup_method(self, method): print ('\nsetup_method()') def teardown_method(self, method): print ('\nteardown_method()') def test_3(self): print('- test_3()') def test_4(self): print('- test_4()')
运行结果如下
从结果可以看出,类形式的执行顺序如下
setup_class()--->setup_method()---->test_3()---->teardown_method()--->setup_mothod()-->test_4()---->teardown_method()---->teardonw_class()
setup_class和teardown_class只会在类调用前及结束后各运行一次
setup_method和teardown_method会在每个用例时都会运行
以类形式运行时,类里的用例执行顺序是不会变的,这点比unittest好
3、运行unittest框架模式
pytest也可以直接运行unittest模式的测试用例,如下
class my(unittest.TestCase): def delf(self,a): print a @classmethod def set_resource(self): bb='setUpclass' print bb @classmethod def setUpClass(cls): print "setUpclass" cls.set_resource() def setUp(self): print "setUp" floating_ip = ('setUptoTearDwon',) self.addCleanup(self.delf, floating_ip[0]) def test_1(self): '''i dont konw''' a='1111' print "test_1" floating_ip = ('bbbbb',) self.addCleanup(self.delf, floating_ip[0]) print "2222" self.addCleanup(self.delf, a) def tearDown(self): print 'this is tearDown' def test_2(self): print "test_2" @classmethod def tearDownClass(cls): print "teardown...."
使用pytest运行该文件,结果如下
collected 2 itemsunittest_fomater.py ..========================== 2 passed in 0.19 seconds ===========================
可以看出,pytest也支持unittest的addCleanup功能等
需要注意的是,如果你在pytest模式中使用setupClass()函数是不行的,不会识别,但如果用例类继承之unittest.Testcase,还是可以识别的
class TestClass: @classmethod def setUpClass(cls): print ('\nsetup_class()') @classmethod def teardown_class(cls): print ('teardown_class()') def setup(self): print ('\nsetup_method()') def teardown_method(self, method): print ('\nteardown_method()') def test_3(self): print('- test_3()') def test_4(self): print('- test_4()')
用pytest运行时,结果如下,没有识别到setUpclass
collected 2 itemspytest_lean1.py::TestClass::test_3setup_method()- test_3()PASSEDteardown_method()pytest_lean1.py::TestClass::test_4setup_method()- test_4()PASSEDteardown_method()teardown_class()