一、Pytest 介紹
1、基于 python 的單元測試框架
主流的接口測試框架有:
- python:pytest 和 unittest
- java:testng 和 junit
- pytest 和 unittest 區別
1.安裝需求不同。pytest為第三方單元測試庫,需額外安裝;unittest為標準庫,無需額外安裝。
2.用例編寫規則不同。pytest編寫規則較為簡單,兼容性較好;unittest需按照固定的格式編寫,較為復雜。
pytest 優點
pytest是一個非常成熟的python單元測試框架,比unittest更靈活、更容易上手
pytest可以和selenium、requests、appinum結合實現web自動化、接口自動化、app自動化
pytest可以是實現測試用例的跳過以及reruns失敗用例重試
pytest可以和aliure生成非常美觀的測試報告
pytest可以和jenkins持續集成
pytest有非常強大的插件,并且這些插件能夠實現很多的使用的操作
pytest 可以和 selenium,requests,appium 實現 web,接口,app 自動化
2、pytest 強大的 插件
- pytest 本身
- pytest-html 生成html報告
- pytest-xdist 多線程
- pytest-ordering 控制用例的執行順序
- pytest-rerunfailures 失敗用例重跑
- pytest-base-url 處理基礎路徑(測試,開發,預發布環境,生產)
- allure-pytest 生成allure報告
插件自動安裝:
1、在項目根目錄創建文件:requirements.txt
2、在文件中寫入需要安裝的插件名
requirements.txt 內容
pytest
pytest-html
pytest-xdist
pytest-ordering
pytest-rerunfailures
pytest-base-url
allure-pytest
3、在項目根目錄打開控制臺,執行命令
pip install -r requirements.txt
4、執行命令后,等待安裝插件
3、pytest 作用
發現并找到測試用例
pytest 默認規則:
模塊名必須以test_開頭或_test結尾。
測試類必須以Test開頭,并且不能有init方法
測試用例方法必須以test開頭
按順序執行測試用例
通過斷言判斷測試結果
生成測試報告
二、 Pytest測試用例執行方式
2.1 主函數模式
1、運行所有:pytest.main()
2、指定模塊:pytest.main([‘-vs’,‘test_login.py’])
3、指定目錄:pytest.main([“-vs”,“testcase”])
4、通過nodeid指定用例運行:nodeid由模塊名,分隔符,類名,方法名,函數名組成
pytest.main([“-vs”,“./interface_testcase/test_interface.py::Testinterface::test_yujian”])
class Testinterface(object):
def test_demo1(self):
assert 3 == 3
def test_demo2(self):
assert 3 == 5
2.2 命令行模式
1、運行所有:pytest 指定模塊:pytest -vs
2、test_login.py 指定目錄:pytest -vs ./第一課:Pytest介紹
3、指定nodeid:pytest -vs ./interface_testcase/test_interface.py::Testinterface::test_03_zhiliao
2.3 參數詳解
-s:表示輸出調試信息,包括print打印的信息
-v:顯示詳細信息
-vs:一般這兩個參數一起使用
-n:支持多線程或分布式運行測試用例例如:pytest -vs ./testcase/test_login.py -n 2例如:pytest.main(["-vs", "./test_login.py", "-n=2"])
--return:失敗用例重跑
-x:表示只要一個用例報錯,就停止測試
--maxfail=2:出現兩個用例失敗就停止
-k:根據測試用例的部分字符串指定測試用例例如:pytest -vs -k "te"
2.4 通過讀取pytest.ini配置文件運行(重點)
1、位置:一般放在項目的根目錄
2、編碼:必須是ANSI,可以使用notepad++修改編碼格式
3、作用:改變pytest默認的行為
4、 運行的規則:不管是主函數模式,還是命令行模式,都會讀取這個配置文件
#文件名pytest.ini[pytest]
#命令行參數,用空格分割
addopts = -vs
#測試用例文件夾,可自己配置
testpaths = ./testcase
#配置測試搜索的模塊文件名稱
python_files = test*.py
#配置測試搜索的測試類名
python_classes = Test*
#配置測試搜索的測試函數名
python_functions = test
三、Pytest執行順序
unittest執行順序:按照ascli的大小來執行
pytest執行順序:默認從上到下執行
改變pytest的默認執行順序:使用@pytest.mark.run(order=1)
'''
需求:將test_demo2第一個先執行
'''
import pytest
class Testinterface(object):
def test_demo1(self):
assert 3 == 3
@pytest.mark.run(order=1)
def test_demo2(self):
assert 3 == 5
if __name__ == '__main__':
pytest.main(['-vs'])
四、Pytest跳過用例
4.1 無條件跳過
無條件跳過: @pytest.mark.skip(reason"跳過")
@pytest.mark.skip(reason="無理由跳過")
def test_demo2(self):
assert 3 == 5
4.2 有條件跳過
num = 1
@pytest.mark.skipif(num<5,reason="有理由跳過")
def test_demo3(self):
assert 3 == 5
五、前后置(夾具、固件)
5.1 setup/teardown,setup_class/teardown_class實現前后置
為什么要使用前后置?
比如:web自動化執行用例之前,請問需要打開瀏覽器嘛?用例執行后需要關閉瀏覽器嘛?
**import pytest
class Test_FirmWare():
#setup_class/teardown_class在所有的測試用例之前、之后只執行一次
def setup_class(self):
print('\n-----在每個類執行前的初始化工作,如:創建日志對象、創建數據庫的連接、創建接口的請求對象-----')
#setup/teardown在每個測試用例之前、之后都要執行一次
def setup(self):
print('\n-----在執行測試用例之前初始化的工作,如:打開瀏覽器,加載網頁-----')
def test01(self):
print('測試01')
def test02(self):
print('測試02')
def teardown(self):
print('\n-----在執行測試用例之后的掃尾工作,如:關閉瀏覽器-----')
def teardown_class(self):
print('\n-----在每個類執行后的掃尾工作,如:銷毀日志對象、銷毀數據庫的連接、銷毀接口的請求對象-----')**
5.2 使用@pytest.fixture()裝飾器來實現用例的前后置
@pytest.fixture()的5個參數含義
@pytest.fixture(scope="", params="", autouse="", ids="", name="")
scope:表示被@pytest.fixture()方法標記的作用域。functions(默認)、class、moudle、package/session
params:參數化(支持,列表,元組,字典列表[{},{},{}],字典元組({},{},{}) )
autouse=True:自動執行,默認False
ids:參數化時,給每一個值設置一個變量名,意義不大
name:給@pytest.fixture()標記的方法取一個別名
步驟一:定義fixture函數(函數名不固定);
步驟二:將函數名作為參數寫入用例方法;
yield作用:帶有yield的函數是一個迭代器,函數返回某個值時,會停留在某個位置,返回函數值后,會在前面停留的位置繼續執行,直到程序結束
**
import pytest
@pytest.fixture(scope="function")
def my_fixture():#"在這里插入代碼片"
print("\n這是用例前置")
yield
print("\n這是用例后置")
class TestDs(object):
def test_01(self):
print("測試01")
def test_fixture(self, my_fixture):
print("測試fixture前后置")
**
六、@pytest.mark.parametrize—參數化
@pytest.mark.parametrize(args_name,args_value)args_name:參數名
args_value:參數值(列表,元祖,字典列表,字典元祖) 有多少個值用例就會執行多少次
import pytest
class TestApi:
def test_01_jame(self):
print('\n測試JAME')
@pytest.mark.parametrize('args', ['張三', '李四', '王五'])
def test_02_lucy(self, args):
print('\n測試Lucy')
print('---------' + str(args))
if __name__ == '__main__':
pytest.main(['-vs'])
七、pytest斷言assert的用法
7.1 assert的用法
import pytest
class TestAssertions(object):
def test_string(self):
assert "spam" == "eggs"
class TestAssertions(object):
def test_function(self):
def f():
return [1, 2, 3]
assert f() == [1, 2, 4]
class TestCollections(object):
def test_dict(self):
assert {"a": 0, "b": 1, "c": 0} == {"a": 0, "b": 2, "d": 0}
def test_dict2(self):
assert {"a": 0, "b": {"c": 0}} == {"a": 0, "b": {"c": 2}}
def test_list(self):
assert [0, 1, 2] == [0, 1, 3]
def test_list2(self):
assert [0, 1, 2] == [0, 1, [1, 2]]
def test_tuple(self):
assert (0, 1, 2) == (0, 1, 3)
def test_set(self):
assert {0, 10, 11, 12} == {0, 20, 21}
# assert xx #判斷xx為真
# assert not xx #判斷xx不為真
# assert a > b #判斷a大于b
# assert a < b #判斷a小于b
# assert a != b #判斷a不等于b
# assert a in b #判斷b包含a
# assert a not in b #判斷b不包含a
# 對于異常的斷言,Pytest的語法是:with pytest.raises(異常類型),可以看下面的這個例子:
#
def test_zero_division():
with pytest.raises(ZeroDivisionError):
1 / 0
八、allure測試報告
8.1 Allure介紹
一個輕量級、靈活的、支持多語言的測試報告工具
支持多平臺,奢華的report框架
能提供詳盡的測試報告、測試步驟、Log等信息
Java語言開發,但支持pytest、JavaScript、PHP、ruby等語言或框架
可以集成到Jenkins
8.2 allure安裝
Allure的使用,需要安裝Java和Allure。
Java:由于Allure是Java語言開發的,所以需要安裝Java;網上很多java的安裝教程,這里就不詳細說明了
Allure:本人只有win10系統的,所以本章主要是在win10下操作的
下載地址:https://github.com/allure-framework/allure2/releases
如果github下載不太順暢,可以考慮別的網站:https://repo.maven.apache.org/maven2/io/qameta/allure/allure-commandline/
配置環境變量:解壓后將bin目錄加入PATH環境變量
環境驗證:命令行輸入allure --version,能正常打印對應版本即可
小作業
1、pytest環境安裝,下面關于pytest安裝方式說法正確的是
選項A:本地有python環境,使用命令行安裝,pip install pytest
選項B:本地沒有配置python環境,使用命令行安裝,pip install pytest
選項C:本地有python環境,使用命令行安裝,pip uninstall pytest
選項D:通過命令安裝 :pip install allure
2、下列哪個選項不是pytest執行用例結果的狀態?
選項A:skipped
選項B:failed
選項C:pending
選項D:passed
3、pytest運行測試用例,如何跳過某個用例,下面說法正確的是:
選項A:pytest -k
選項B:方法上面加上裝飾器,@pytest.mark.skip,運行的時候不添加任何參數
選項C:方法上面加上裝飾器,@pytest.mark.skip,運行的時候指定參數-k
選項D:方法上面加上裝飾器,@pytest.mark.parametrize
4、既然有unittest那么為什么還要用pytest呢?
5、Pytest編寫規則是什么?
6、pytest 默認的測試用例執行順序?
7、pytest改變測試用例的執行順序,需要用哪個裝飾器來實現?
8、pytest 執行用例的方式?