一赊淑、pytest單元測(cè)試框架
1爵政、什么是單元測(cè)試框架
單元測(cè)試框架是指在軟件測(cè)試開(kāi)發(fā)當(dāng)中,針對(duì)軟件的最小單位(函數(shù)陶缺、方法)進(jìn)行正確性的檢查測(cè)試
2钾挟、單元測(cè)試框架有哪些
java:junit、testng
python:unittest饱岸、pytest
3掺出、單元測(cè)試框架主要做什么
測(cè)試發(fā)現(xiàn):從多個(gè)文件里面去找到我們測(cè)試用例
測(cè)試執(zhí)行:按照一定的順序和規(guī)則去執(zhí)行徽千,并生成結(jié)果
測(cè)試判斷:通過(guò)斷言判斷預(yù)期結(jié)果和實(shí)際結(jié)果的差異
測(cè)試報(bào)告:統(tǒng)計(jì)測(cè)試進(jìn)度,耗時(shí)汤锨,通過(guò)率双抽,生成測(cè)試報(bào)告
二、單元測(cè)試框架和自動(dòng)化測(cè)試框架有什么關(guān)系闲礼?
1牍汹、什么是自動(dòng)化測(cè)試框架
2、作用
提高測(cè)試效率柬泽,降低維護(hù)成本
減少人工干預(yù)慎菲,提高測(cè)試的準(zhǔn)確性,增加代碼的重用性
核心思想是讓不懂代碼的人也能夠通過(guò)這個(gè)框架去實(shí)現(xiàn)自動(dòng)化測(cè)試
3锨并、pytest單元測(cè)試框架和自動(dòng)化測(cè)試框架的關(guān)系
單元測(cè)試框架:只是自動(dòng)化測(cè)試框架中的組成部分之一
pom設(shè)計(jì)模式:只是自動(dòng)化測(cè)試框架中的組成部分之一
數(shù)據(jù)驅(qū)動(dòng)...
關(guān)鍵字驅(qū)動(dòng)...
全局配置文件的封裝...
日志監(jiān)控...
selenium钧嘶、requests二次封裝...
斷言
報(bào)告郵件等...
三、pytest簡(jiǎn)介
1琳疏、pytest是一個(gè)非常成熟的python的單元測(cè)試框架,比unittest更靈活闸拿,功能更強(qiáng)大
2空盼、pytest可以和selenium、requests新荤、appium結(jié)合實(shí)現(xiàn)web自動(dòng)化揽趾、接口自動(dòng)化、app自動(dòng)化
3苛骨、pytest可以實(shí)現(xiàn)測(cè)試用例的跳過(guò)以及reruns失敗用例重試
4篱瞎、pytest可以和allure生成美觀的測(cè)試報(bào)告
5、pytest可以和jenkins持續(xù)集成
6痒芝、pytest有很多非常強(qiáng)大的插件俐筋,并且這些插件能夠?qū)崿F(xiàn)很多的實(shí)用的操作
pytest? #pip install -U pytest
pytest-html? #生成html格式的自動(dòng)化測(cè)試報(bào)告
pytest-xdist? #測(cè)試用例分布式執(zhí)行,多CPU分發(fā)
pytest-ordering? #用于改變測(cè)試用例的執(zhí)行順序
pytest-rerunfailures? #用例失敗后重跑
allure-pytest? #用于生成美觀的測(cè)試報(bào)告
#pip install -r requirements.txt? #使用模塊文件安裝模塊
四严衬、使用pytest澄者,默認(rèn)的測(cè)試用例的規(guī)則以及基礎(chǔ)應(yīng)用
1、模塊名必須以test_開(kāi)頭或者_(dá)test結(jié)尾
2请琳、測(cè)試類必須以Test開(kāi)頭粱挡,并且不能有init方法
3、測(cè)試方法必須以test開(kāi)頭
五俄精、pytest測(cè)試用例的運(yùn)行方式
1询筏、主函數(shù)模式
? ? ? ? 運(yùn)行所有:pytest.main()
? ? ? ? 指定模塊:pytest.main(['-vs', 'test_login.py'])
? ? ? ? 指定目錄:pytest.main(['-vs', './interface_testcase'])
? ? ? ? 通過(guò)nodeid指定用例運(yùn)行:nodeid由包名、文件名竖慧、分隔符嫌套、類名逆屡、函數(shù)名組成:
? ??????????????pytest.main(['-vs', './interface_testcase/test_interface.py::test_04_func'])
? ??????????????pytest.main(['-vs', './interface_testcase/test_interface.py::TestInterface::test_04_func'])
2、命令行模式
? ? ? ? 運(yùn)行所有:pytest
? ? ? ? 指定模塊:pytest -vs test_login.py
? ? ? ? 指定目錄:pytest -vs?./interface_testcase
? ??????通過(guò)nodeid指定用例運(yùn)行:
????????????????pytest -vs?./interface_testcase/test_interface.py::test_04_func
????????????????pytest -vs?./interface_testcase/test_interface.py::TestInterface::test_04_func
參數(shù)詳解:
? ? ? ? -s:表示輸出調(diào)試信息灌危,包括print打印的信息
? ? ? ? -v:顯示更詳細(xì)的信息
? ? ? ? -vs:這兩個(gè)參數(shù)一起用
? ? ? ? -n:支持多線程或者分布式運(yùn)行測(cè)試用例(后跟線程數(shù))
? ? ? ? ? ? ? ? 如:pytest.main(['-vs', './testcase/test_login.py', '-n=2'])
? ? ? ? ? ? ? ? 如:pytest -vs ./testcase/test_login.py -n 2
? ? ? ? --reruns:失敗用例重跑(后跟重跑次數(shù))
? ? ? ? ? ? ? ? 如:pytest.main(['-vs', './testcase/test_login.py', '--reruns=2'])
? ? ? ? ? ? ? ? 如:pytest -vs ./testcase/test_login.py --reruns 2
? ? ? ? -x:只要有一個(gè)用例失敗用例停止執(zhí)行
? ? ? ? --maxfail=2:只要失敗2個(gè)用例就停止執(zhí)行
? ? ? ? -k:根據(jù)測(cè)試用例部分字符串指定測(cè)試用例(后跟包含字符串)
? ? ? ? ? ? ? ? 如:pytest -vs ./testcase/test_login.py -k "ao"
? ? ? ? --html:生成html格式的測(cè)試報(bào)告
? ? ? ? ? ? ? ? 如:--html=templates/report.html
3康二、通過(guò)讀取pytest.ini配置文件運(yùn)行
pytest.ini這個(gè)文件是pytest單元測(cè)試框架的核心配置完文件
? ? ? ? 位置:一般放在項(xiàng)目的根目錄下
? ? ? ? 編碼:必須是ANSI,可以使用notepad++修改編碼格式
? ? ? ? 作用:改變pytest默認(rèn)的行為
? ? ? ? 運(yùn)行規(guī)則:不管是主函數(shù)的模式運(yùn)行還是命令行模式運(yùn)行勇蝙,都會(huì)去讀取這個(gè)配置文件
pytest.ini配置文件
[pytest]
addopts = -v -p no:warnings --html=templates/report.html? #命令行參數(shù)沫勿,用空格分隔
testpaths = tests? #測(cè)試用例文件夾,可自己配置
python_files = test_*.py? #配置測(cè)試搜索的模塊文件名稱
python_classes = Test*? #配置測(cè)試搜索的測(cè)試類名
python_functions = test_*? #配置測(cè)試搜索的測(cè)試函數(shù)名
markers =
????smoke:冒煙用例
????usermanage:用戶管理模塊
????productmanage:商品管理模塊
六味混、pytest執(zhí)行測(cè)試用例的順序是怎樣的
unittest:ascll的大小來(lái)決定執(zhí)行的順序
pytest:默認(rèn)從上到下
????????改變默認(rèn)執(zhí)行順序:使用mark標(biāo)記
????????使用@pytest.mark.run(order=1)裝飾器標(biāo)記用例函數(shù)产雹,order越小越先執(zhí)行
七、如何分組執(zhí)行(冒煙翁锡,分模塊執(zhí)行蔓挖,分接口和web執(zhí)行)
smoke:冒煙用例,分布在各個(gè)模塊里面
1馆衔、需要在測(cè)試用例前面使用@pytest.mark.smoke標(biāo)記用例
2瘟判、執(zhí)行時(shí)加上-m
? ? ? ? 如:pytest -vs -m "smoke"
? ? ? ? 如:pytest -vs -m "smoke or usermanage"
八、pytest跳過(guò)測(cè)試用例
1角溃、無(wú)條件跳過(guò)
? ? ? ? 標(biāo)記:@pytest.mark.skip(reason="")
2拷获、有條件跳過(guò)
? ? ? ? 標(biāo)記:@pytest.mark.skipif(age>=18, reason="")
九、前后置(固件减细、夾具)
setup/teardown匆瓜,setup_class/teardown_class
1、為什么需要這些功能未蝌?
比如web自動(dòng)化用例執(zhí)行之前驮吱,需要打開(kāi)瀏覽器,用力執(zhí)行之后需要關(guān)閉瀏覽器
class Test_01:
????def setup_class(self):
? ? ? ? print("在每個(gè)類執(zhí)行之前的初始化工作");
? ? def setup(self):
? ? ? ? print("在每個(gè)用例執(zhí)行之前的初始化邏輯");
? ? def test_01(self):
? ? ? ? print("測(cè)試用例");
? ? def teardown(self):
? ? ? ? print("在每個(gè)用例執(zhí)行之后的后置步驟 ");
????def teardown_class(self):
? ? ? ? print("在每個(gè)類執(zhí)行之后的后置步驟 ");
和unittest框架不一樣萧吠,函數(shù)名全部都是小寫(xiě)
十左冬、fixture裝飾器實(shí)現(xiàn)部分用例的前后置
@pytest.fixture(scope="", params="", autouse="", name="")
1、scope:表示的使被@pytest.fixture標(biāo)記的函數(shù)的作用域(function(默認(rèn)) 怎憋,class又碌,module,package/session)
2绊袋、params:參數(shù)化(支持列表[]毕匀,元組(),字典列表{[], [], []}癌别,元組字典({}, {}, {}))
3皂岔、autouse:是否自動(dòng)執(zhí)行,F(xiàn)alse(默認(rèn))
4展姐、ids:當(dāng)使用params參數(shù)化時(shí)躁垛,給每一個(gè)值設(shè)置一個(gè)變量名
5剖毯、name:給被@pytest.fixture標(biāo)記的函數(shù)取一個(gè)別名(當(dāng)取了別名之后,原來(lái)的名稱便用不了了)
@pytest.fixture(scope="function", params=["params1", "params2", "params3"], ids=["p1", "p2", "p3"], name="mf")
def my_fixture(request):
? ? print("前置") # 前置邏輯
? ? yield request.param # 將params的值傳給用例(yield分隔前后置邏輯教馆,不能使用return返回逊谋,如果使用return則無(wú)法執(zhí)行后置邏輯)
? ? print("后置") # 后置邏輯
class TestFixture:
? ? def test_01(self):
? ? ? ? print("測(cè)試用例test_01")
? ? def test_02(self, my_fixture):
????????print("測(cè)試用例?test_02?")
????????print("==="+str(my_fixture)+"===")
十一、使用conftest.py和@pytest.fixture一起實(shí)現(xiàn)全局的前后置應(yīng)用
1土铺、conftest.py文件使單獨(dú)存放的一個(gè)夾具配置文件胶滋,名稱固定不能修改
2、可以在不同的py文件中使用同一個(gè)fixture函數(shù)
3悲敷、原則上conftest.py需要和運(yùn)行的用例放在同一層究恤,并且不需要做任何的import導(dǎo)入操作
#conftest.py文件
@pytest.fixture(scope="function", params=["params1", "params2", "params3"], ids=["p1", "p2", "p3"], name="mf")
def my_fixture(request):
????print("前置") # 前置邏輯
? ??yield request.param # 將params的值傳給用例(yield分隔前后置邏輯,不能使用return返回后德,如果使用return則無(wú)法執(zhí)行后置邏輯)
????print("后置") # 后置邏輯
#測(cè)試類
class TestFixture:
????def test_01(self):
????????print("測(cè)試用例test_01")
????def test_02(self, my_fixture):
????????print("測(cè)試用例?test_02?")
????????print("==="+str(my_fixture)+"===")
總結(jié):
setup/teardown 作用于當(dāng)前類或子類的所有用例
setup_class/teardown_class 作用于當(dāng)前文件的所有類
@pytest.fixture() 作用于部分用例或者所有用例
conftest.py和@pytest.fixture()結(jié)合使用部宿,作用于全局的所用用例
十二、斷言
assert 1==2
十三瓢湃、pytest結(jié)合allure-pytest模塊生成allure測(cè)試報(bào)告
allure下載地址:https://github.com/allure-framework/allure2/releases
1理张、下載.zip文件,解壓到本地绵患,配置bin環(huán)境變量涯穷,驗(yàn)證配置是否成功allure --version
2、生成json格式臨時(shí)報(bào)告
pytest.ini配置文件
[pytest]
addopts = -vs??--alluredir ./allure_temp
3藏雏、生成allure報(bào)告
pytest.main()
os.system("allure generate ./allure_temp -o ./report --clean")?
allure generate? 固定生成allure報(bào)告命令
./allure_temp 找到臨時(shí)報(bào)告
-o ./report輸出到指定目錄下
--clean 清除原報(bào)告目錄下的報(bào)告