在介紹一中簡單介紹了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_function class 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 items unittest_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 items pytest_lean1.py::TestClass::test_3 setup_method() - test_3() PASSED teardown_method() pytest_lean1.py::TestClass::test_4 setup_method() - test_4() PASSED teardown_method() teardown_class()