本文鏈接:https://blog.csdn.net/yxxxiao/article/details/94591174
目錄
一、安裝
二、第一個測試例子
三、pytest參數
1、-K EXPRESSION
3、--maxfail=num
4、-m MARKEXPR
5、 -v, --verbose
6、-q, --quiet
7、--junit-xml=path
8、 --result-log=path
四、pytest 用例規則
五、pytest運行方式
1.單獨執行某一個py文件里所有的用例
2.執行目錄下所有用例
3.單獨執行某個用例
六、fixture
1、fixture scope的范圍參數
2、調用fixture的三種方法
2.1函數或類里面方法直接傳fixture的函數參數名稱
2.2使用裝飾器@pytest.mark.usefixtures()修飾需要運行的用例
2.3疊加usefixtures
3.usefixtures與傳fixture區別
4.fixture自動使用autouse=True
5.conftest.py的作用范圍
5.1conftest在不同的層級間的作用域不一樣
5.2conftest是不能跨模塊調用的(這里沒有使用模塊調用)
一、安裝
pytest不是python默認的package,需要手動安裝。
pytest支持python 2.6--3.5之間的版本,同時可以在windows、unix系統上安裝
安裝方式:
pip install pytest
安裝完成后,可以查看版本:
pytest --version
二、第一個測試例子
1.創建test_sample.py文件,創建一個方法、一個用例
# content of test_sample.py def func(x): return x + 1
def test_answer(): assert func(3) == 5
2.執行
$ pytest =========================== test session starts ============================ platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y cachedir: $PYTHON_PREFIX/.pytest_cache rootdir: $REGENDOC_TMPDIR collected 1 item test_sample.py F [100%] ================================= FAILURES ================================= _______________________________ test_answer ________________________________ def test_answer(): > assert func(3) == 5 E assert 4 == 5 E + where 4 = func(3) test_sample.py:5: AssertionError ========================= 1 failed in 0.12 seconds =========================
此測試返回失敗報告,因為func(3)不返回5。
三、pytest參數
1、-K EXPRESSION
執行某個關鍵字的用例
用例要匹配給出的表達式;使用python的語法,匹配的范圍是文件名、類名、函數名為變量,用and來區分
如下面一段測試用例
# content of test.py class TestClass(object): def test_zne(self): x = "this" assert 'h' in x def test_two(self): x = "hello" assert hasattr(x, 'check') def test_a(self): assert 1==2
運行pytest時帶-k參數
pytest -k "test and TestClass and not test_a" test.py
結果如下:
可以看出,test_a這個用例被取消選擇了,沒有運行了
3、--maxfail=num
當錯誤個數到達給定數時,退出測試,這里就不列舉實例了,結果與-x類似
4、-m MARKEXPR
只能運行有相應標識的測試用例,使用這個參數,測試用例要使用@pytest.mark.marker修飾
如下實例
# content of test.py import pytest class TestClass(object): def test_one(self): '''new_etests''' x = "this" assert 'h' in x @pytest.mark.slow def test_two(self): '''new_sssetests''' x = "hello" assert hasattr(x, 'check') def test_a(self): assert 1==2
teste_two使用了@pytest.mark.slow來修飾
在使用時,使用如下參數
pytest –m slow test.py
結果如下:
從上圖中可以看出,只運行了一個我們帶有標識的用例。
注意,-m后面不能帶''號(單引號),只能帶“”(雙引號),不然識別不到
如果要運行多個標識的話,用表達式,如下
pytest -m "slow or faster" 運行有slow標識或 faster標識用例 pytest -m "slow and faster" 運行有slow和faster標識的用例 pytest -m "slow and not faster" 運行有slow和沒有faster標識的用例
5、 -v, --verbose
詳細結果
6、-q, --quiet
極簡結果顯示,簡化控制台的輸出,可以看出輸出信息和之前不添加-q不信息不一樣, 下圖中有兩個..點代替了pass結果
7、-s
輸入我們用例中的調式信息,比如print的打印信息等,我們在用例中加上一句 print(driver.title),我們再運行一下我們的用例看看,調試信息輸出
8、-V
可以輸出用例更加詳細的執行信息,比如用例所在的文件及用例名稱等
9、--junit-xml=path
輸出xml文件格式,在與jenkins做集成時使用
10、 --result-log=path
將最后的結果保存到本地文件中
注意:標黃的是經常使用的
四、pytest 用例規則
pytest可以在不同的函數、包中發現用例,發現的規則如下
文件名以test_開頭的py文件
以test_開頭的函數
以Test開頭的類
以test_開頭的方法(與2類似)
要注意的是所有的包必須要有init.py文件(在使用各種編輯器時會自動生成)
五、pytest運行方式
1.單獨執行某一個py文件里所有的用例
pytest test.py
2.執行目錄下所有用例
pytest testcase/
3.單獨執行某個用例
以函數形式的用例
pytest test_login.py::test_1
以類形式的用例
pytest test_login.py::TestClass::test_1
六、pytest fixture
pytest支持以xUnit格式型的測試模型(setup/teardown),但還與python自帶的unittest還是有一點差別,如下
模塊形式----使用setup_module/teardown_module
函數形式----使用setup_function/teardown_function
類形式----使用setup_class/teardown_class
方法形式---使用setup_method/teardown_method
注意:
1.pytest也可以直接運行unittest模式的測試用例
2.如果你在pytest模式中使用setupClass()函數是不行的,不會識別,但如果用例類繼承之unittest.Testcase,還是可以識別的
1、fixture scope的范圍參數
之前使用@pytest.fixture(scope='module')來定義框架,scope的參數有以下幾種
function 每一個用例都執行
class 每個類執行
module 每個模塊執行(函數形式的用例)
session 每個session只運行一次,在自動化測試時,登錄步驟可以使用該session
2、調用fixture的三種方法
2.1函數或類里面方法直接傳fixture的函數參數名稱
from __future__ import print_function import pytest @pytest.fixture(scope='module') def resource_a_setup(request): print('\nresources_a_setup()') def resource_a_teardown(): print('\nresources_a_teardown()') request.addfinalizer(resource_a_teardown) def test_1(resource_a_setup): print('test_1()') def test_2(): print('\ntest_2()') def test_3(resource_a_setup): print('\ntest_3()')
使用-s -v運行查看詳情如下
2.2使用裝飾器@pytest.mark.usefixtures()修飾需要運行的用例
import pytest # test_fixture1.py @pytest.fixture() def test1(): print('\n開始執行function') @pytest.mark.usefixtures('test1') def test_a(): print('---用例a執行---') @pytest.mark.usefixtures('test1') class TestCase: def test_b(self): print('---用例b執行---') def test_c(self): print('---用例c執行---') if __name__ == '__main__': pytest.main(['-s', 'test_fixture1.py'])
輸出結果:
platform win32 -- Python 3.7.0, pytest-4.0.2, py-1.7.0, pluggy-0.8.0 rootdir: C:\Program Files\PycharmProjects\exercise, inifile:collected 3 items test_fixture1.py 開始執行function .---用例a執行--- 開始執行function .---用例b執行--- 開始執行function .---用例c執行--- [100%] ========================== 3 passed in 0.06 seconds =========================== Process finished with exit code 0
2.3疊加usefixtures
如果一個方法或者一個class用例想要同時調用多個fixture,可以使用@pytest.mark.usefixture()進行疊加。注意疊加順序,先執行的放底層,后執行的放上層
import pytest # test_fixture1.py @pytest.fixture() def test1(): print('\n開始執行function1') @pytest.fixture() def test2(): print('\n開始執行function2') @pytest.mark.usefixtures('test1') @pytest.mark.usefixtures('test2') def test_a(): print('---用例a執行---') @pytest.mark.usefixtures('test2') @pytest.mark.usefixtures('test1') class TestCase: def test_b(self): print('---用例b執行---') def test_c(self): print('---用例c執行---') if __name__ == '__main__': pytest.main(['-s', 'test_fixture1.py'])
輸出結果:
============================= test session starts ============================= platform win32 -- Python 3.7.0, pytest-4.0.2, py-1.7.0, pluggy-0.8.0 rootdir: C:\Program Files\PycharmProjects\exercise, inifile:collected 3 items test_fixture1.py 開始執行function2 開始執行function1 .---用例a執行--- 開始執行function1 開始執行function2 .---用例b執行--- 開始執行function1 開始執行function2 .---用例c執行--- [100%] ========================== 3 passed in 0.03 seconds =========================== Process finished with exit code 0
3.usefixtures與傳fixture區別
如果fixture有返回值,那么usefixture就無法獲取到返回值,這個是裝飾器usefixture與用例直接傳fixture參數的區別。
當fixture需要用到return出來的參數時,只能講參數名稱直接當參數傳入,不需要用到return出來的參數時,兩種方式都可以。
4.fixture自動使用autouse=True
當用例很多的時候,每次都傳這個參數,會很麻煩。fixture里面有個參數autouse,默認是False沒開啟的,可以設置為True開啟自動使用fixture功能,這樣用例就不用每次都去傳參了
autouse設置為True,自動調用fixture功能
import pytest # test_fixture1.py @pytest.fixture(scope='module', autouse=True) def test1(): print('\n開始執行module') @pytest.fixture(scope='class', autouse=True) def test2(): print('\n開始執行class') @pytest.fixture(scope='function', autouse=True) def test3(): print('\n開始執行function') def test_a(): print('---用例a執行---') def test_d(): print('---用例d執行---') class TestCase: def test_b(self): print('---用例b執行---') def test_c(self): print('---用例c執行---') if __name__ == '__main__': pytest.main(['-s', 'test_fixture1.py'])
輸出結果:
============================= test session starts ============================= platform win32 -- Python 3.7.0, pytest-4.0.2, py-1.7.0, pluggy-0.8.0 rootdir: C:\Program Files\PycharmProjects\exercise, inifile:collected 4 items test_fixture1.py 開始執行module 開始執行class 開始執行function .---用例a執行--- 開始執行class 開始執行function .---用例d執行--- 開始執行class 開始執行function .---用例b執行--- 開始執行function .---用例c執行---
5.conftest.py的作用范圍
一個工程下可以建多個conftest.py的文件,一般在工程根目錄下設置的conftest文件起到全局作用。在不同子目錄下也可以放conftest.py的文件,作用范圍只能在改層級以及以下目錄生效。
項目實例:
目錄結構:
5.1conftest在不同的層級間的作用域不一樣
# conftest層級展示/conftest.py import pytest @pytest.fixture(scope='session', autouse=True) def login(): print('----准備登錄----')
# conftest層級展示/sougou_login/conftest import pytest @pytest.fixture(scope='session', autouse=True) def bai_du(): print('-----登錄百度頁面-----')
# conftest層級展示/sougou_login/login_website import pytest class TestCase: def test_login(self): print('hhh,成功登錄百度') if __name__ == '__main__': pytest.main(['-s', 'login_website.py'])
輸出結果:
============================= test session starts ============================= platform win32 -- Python 3.7.0, pytest-4.0.2, py-1.7.0, pluggy-0.8.0 rootdir: C:\Program Files\PycharmProjects\conftest層級演示\sougou_login, inifile:collected 1 item login_website.py ----准備登錄---- -----登錄百度頁面----- .hhh,成功登錄百度 [100%] ========================== 1 passed in 0.03 seconds =========================== Process finished with exit code 0
5.2conftest是不能跨模塊調用的(這里沒有使用模塊調用)
# conftest層級演示/log/contfest.py import pytest @pytest.fixture(scope='function', autouse=True) def log_web(): print('打印頁面日志成功')
# conftest層級演示/log/log_website.py
import pytest def test_web(): print('hhh,成功一次打印日志') def test_web1(): rint('hhh,成功兩次打印日志') if __name__ == '__main__': pytest.main(['-s', 'log_website.py'])
輸出結果:
============================= test session starts ============================= platform win32 -- Python 3.7.0, pytest-4.0.2, py-1.7.0, pluggy-0.8.0 rootdir: C:\Program Files\PycharmProjects\conftest層級演示\log, inifile: collected 2 items log_website.py ----准備登錄---- 打印頁面日志成功 hhh,成功一次打印日志 .打印頁面日志成功 hhh,成功兩次打印日志 . ========================== 2 passed in 0.02 seconds ===========================