pytest介紹
pytest是一個非常成熟的全功能的Python測試框架。簡單靈活,容易上手;支持參數化;
測試用例的skip和xfail,自動失敗重試等處理:
。能夠支持簡單的單元測試和復雜的功能測試,還可以用來做selenium/appnium等自動化測試、接口自動化測試(pytest+requests);
pytest具有很多第三方插件,並且可以自定義擴展,比較好用的如pytest-allure(完美html測試報告生成),pytest- xdist(多CPU分發)等;
。可以很好的和jenkins集成
文檔:https://docs.pytest.org/en/latest/contents.html#toc第三方庫:https://pypiorg/search/?q=pytest
pytest測試用例的識別和運行
測試文件
- test_*py
- *_test.py
用例識別 - Test類包含的所有test的方法(測試類不能帶有_init方法)
- 不在class中的所有的test_*方法
- pytest也可以執行unittest框架寫的用例和方法
常用的終端執行命令:
pytest/py.test
pytest-v(最高級別信息-verbose)打印詳細運行日志信息
pytest-s -v 文件名.py(s是帶控制台輸出結果,也是輸出詳細)
pytest文件名.py執行單獨一個pytest模塊
pytest 文件名.py::類名 運行某個模塊里面某個類
pytest文件名.py:類名:方法名運行某個模塊里面某個類里面的方法
pytest文件名.py-v -k"類名 and not 方法名”跳過運行某個用例
pytest文件名.py-m[標記名] @pytestmark.[標記名]將運行有這個標記的測試用例
pytest文件名.py -x 一旦運行到報錯就停止運行
pytest文件名.py -maxfail-[num] 當運行錯誤達到num的時候就停止運行
創建test_01.py,並輸入以下代碼
def test_demo01():
print("執行測試demo01")
x = 'zhangshuai'
assert 'h' in x
def test_demo02():
print("執行測試demo02")
a = 'hello'
b = 'hello pytest'
assert a in b
分別執行一下三種pytest的執行語句
pytest test_01.py 只能看到失敗的信息(成功的時候顯示test_01py..)
pytest -v test_01.py 會顯示每個測試方法的執行情況
pytest -s test_01.py 會打印方法的輸出語句
結果如下
pytest執行失敗重新運行
場景:測試失敗后要重新運行n次,要在重新運行之間添加延遲時間,間隔n秒再運行。
安裝:pip install pytest-rerunfailures
執行:
pytest --reruns 3 -v -s test_01.py(加入方法demo01出錯會重復執行這個方法3次)
pytest -v --reruns 5 --reruns-delay 1 test_01.py(reruns-delay 1表示每次再執行失敗的方后法間隔1秒再重復執行下一次)
pytest執行多條斷言遇到有失敗的斷言也能繼續執行所有
場景:一個方法中寫多條斷言,通常第一條過不去,下面就不執行了。我們想報錯也執行
安裝:pip install pytest-assume
執行:
pytest.assume(14)
pytest.assume(24)
代碼:
class TestDemo:
def test_demo01(self):
print("執行測試demo01")
x = 'Changsha'
assert 'a' in x
def test_demo02(self):
print("執行測試demo02")
a = 'helloa'
b = 'hello pytest'
assert a in b
assert 'q' in b
# pytest.assume(1==1)
# pytest.assume(a in b)
# pytest.assume(1==2)
不使用assume的斷言
使用assume的斷言
文章主要介紹下在pycharm中怎么使用pytest框架進行測試
pycharm配置與執行pytest測試框架
運行方式:pytest.main(['-v',TestClass])(所有參數和pytest命令行方式一樣的)
下載pytest第三方包
將運行方式選擇pytest
詳細可參考這個文章:https://www.cnblogs.com/hpzyang/p/13948048.html
有時候在創建的項目是虛擬環境virtualenv的時候 會發現正常配置pytest的運行方式但是右鍵運行還是沒有出現 pytest for *** 運行,這時候需要在配置中選中項目
避免這種復雜的方式,(這種情況可以能虛擬環境使用的是本地的python的依賴 兩者沒法互通)我們在創建項目的時候可以創建為conda的項目
參數解析
pytest框架結構
import pytest類似的setupteardown同樣更靈活,
模塊級(setup_module/teardown_module)模塊始末,全局的(優先最高)
函數級(setup_function/teardown_function)只對函數用例生效(不在類中犯法)
類級(setup_class/teardown_class)只在類中前后運行一次(在類中)
方法級(setup_method/teardown_methond)開始於方法始末(在類中的方法)
類里面的(setup/teardown)運行在調用方法的前后(和method方法作用相同,在方法前進行執行但是執行的優先級別低於method)
import pytest
def setup_module():
print('setup_module')
def teardown_module():
print('teardown_module')
def setup_function():
print('setup_function')
def teardown_function():
print('teardown_function')
def test_login():
print('這是個登陸方法')
class TestDemo:
def setup_class(self):
print('setup_class')
print('用戶a已經開始登錄成功')
def teardown_class(self):
print('teardown_class')
def setup_method(self):
print('setup_method')
def setup(self):
print('setup')
def test_demo01(self):
print("執行測試demo01,需要登陸")
x = 'Changsha'
assert 'a' in x
pass
def test_demo02(self):
print("執行測試demo02,不需要登陸")
a = 'hello'
b = 'hello pytest'
assert a in b
# assert 'q' in b
# pytest.assume(1 == 1)
# pytest.assume(a in b)
# pytest.assume(1 == 2)
pass
def test_demo03(self):
print("執行測試demo03,需要登陸")
x = 'Changsha'
assert 'a' in x
pass
# class TestDemo1:
#
# def test_demo03(self):
# print("執行測試demo03")
# x = 'shanghaied'
# assert 'q' in x
#
# def test_demo04(self):
# print("執行測試demo04")
# a = 'hello'
# b = 'hello pytest'
# assert a in b
if __name__ == '__main__':
pytest.main("-v -x TestDemo")
結果如下
在方法前面加@pytest.fixture()
例子1:前端自動化中應用
用例1需要先登錄
用例2不需要登錄
用例3需要登錄
場景:測試用例執行時,有的用例需要登陸才能執行,有些用例不需要至 setup和teardown無法滿足。
fixture可以。默認scope(范圍)function
步驟:
導入pytest
在登陸的函數上面加@pytest.fixture()
在要使用的測試方法中傳入(登陸函數名稱),就先登陸
不傳入的就不登陸直接執行測試方法
import pytest
@pytest.fixture()
def test_login():
print('這是個登陸方法')
def test_demo01(test_login):
print('需要登陸')
pass
def test_demo02():
print('需要登陸')
pass
def test_demo03(test_login):
print('需要登陸')
pass
if __name__ == '__main__':
pytest.main()
運行結果如下
例子2場景:
不想原測試方法有任何改動,或全部都自動實現自動應用,沒特例,也都不需要返回值時可以選擇自動應用
解決:使用fixture中參數autouse=True實現
步驟:
在方法上面加@pytest.fixture(autouse=True)
在測試方法上加@pytest.markusefixtures("start")
conftest
場景:
你與其他測試工程師合作一起開發時公共模塊要在不同文件中,要在大家都訪問到的地方。
解決:
conftest.py這個文件進行數據共享,並且他可以放在不同位置起着不同的范圍共享作用。執行:
系統執行到參數login時先從本文件中查找是否有這個名字的變量,之后在conftestpy中找是否有
步驟:
將登陸模塊帶@pytest.fixture寫在conftestpy
- conftestpy配置需要注意:
- conftest文件名是不能換的
- conftest.py與運行的用例要在同一個package下,並且有_init_.py文件
- 不需要import導入conftset.py,pytest用例會自動查找
- 全局的配置和前期工作都可以寫在這里,放在某個包下,就是這個包數據共享的地方。
yield
場景:你已經可以將測試方法前要執行的或依賴的解決了,測試方法后銷毀清除數據的要如何進行呢?范圍是模塊級別的。類似setupClass
解決:通過在同一模塊中加入yield關鍵字,yield是調用第一次返 回結果,第二次執行它下面的語句返回。
步驟: 在@pytest.fixture(scope=module)
在登陸的方法中加yield,之后加銷毀清除的步驟注意,這種方式沒有返回值,如果希望返回使用addfinalizer