乾貨 | 一文搞定 pytest 自動化測試框架(一)

2021-02-19 霍格沃茲測試學院

本文節選自霍格沃玆測試學院內部教材,進階學習,文末加群!

簡介

pytest 是一個成熟的全功能 Python 測試工具,可以幫助您編寫更好的程序。它與 Python 自帶的 Unittest 測試框架類似,但 pytest 使用起來更簡潔和高效,並且兼容 unittest 框架。pytest 有以下實用特性:

pytest 能夠支持簡單的單元測試和複雜的功能測試;

pytest 本身支持單元測試;

可以結合 Requests 實現接口測試;

結合 Selenium、Appium 實現自動化功能測試;

使用 pytest 結合 Allure 集成到 Jenkins 中可以實現持續集成。工作中一般會使用持續集成來完成代碼集成到主幹分支之後的回歸測試,通過自動化測試的手段來實現產品的快速迭代,同時還能保證產品的高質量。

pytest 支持 315 種以上的插件;

參考網站:

安裝

pip install -U pytest

查看版本

pytest --version

用例的識別與運行

用例編寫規範:

創建一個 python 文件,命名以 test_ 開頭(或者以 _test 結尾),創建測試方法以 test_ 開頭,測試類需要以 Test 開頭。創建文件名為 test_add.py 文件,代碼如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
def add(x, y):
    return x + y

def test_add():
    assert add(1, 10) == 11
    assert add(1, 1) == 2
    assert add(1, 99) == 100

class TestClass:
    def test_one(self):
        x = "this"
        assert "h" in x

    def test_two(self):
        x = "hello"
        assert hasattr(x, "check")   

運行 test_add.py 文件,在命令行進入到這個文件所在的路徑,可以直接使用 pytest 命令運行,pytest 會找當前目錄以及遞查找子目錄下所有的 test_*.py 或 *_test.py 的文件,把其當作測試文件。在這些文件裡,pytest 會收集符合編寫規範的函數,類以及方法,當作測試用例並且執行,執行如下:

 $ pytest
....

test_add.py ..F  [100%]
....

self = <test_cases.test_add.TestClass object at 0x1091810d0>

    def test_two(self):
        x = "hello"
>       assert hasattr(x, "check")
E       AssertionError: assert False
E        +  where False = hasattr('hello', 'check')

test_add.py:18: AssertionError
===================================================== 1 failed, 2 passed in 0.05s 
...

結果分析:執行結果中,F代表用例未通過(斷言錯誤),.用例通過。如果有報錯會有詳細的錯誤信息。pytest 也支持 Unittest 模式的用例定義。

運行參數

pytest 帶有很多參數,可以使用 pytest --help 來查看幫助文檔,下面介紹幾種常用的參數:

無參數

讀取路徑下所有符合規則的文件,類,方法,函數全部執行。使用方法如下:

pytest 或者 py.test

-v 參數

列印詳細運行日誌信息,一般在調試的時候加上這個參數,終端會列印出每條用例的詳細日誌信息,方便定位問題。使用方法如下:

pytest -v 

-s 參數

帶控制臺輸出結果,當你的代碼裡面有 print 輸出語句,如果想在運行結果中列印 print 輸出的代碼,在運行的時候可以添加 -s 參數,一般在調試的時候使用,使用方法如下:

pytest -s 

-k 參數

跳過運行某個或者某些用例。

應用場景:在測試場景中,開發人員有一部分功能代碼還沒實現,測試人員已經將測試用例設計出來,或者測試人員發現了某功能上的 bug 需要開發人員修復之後再測試這部分有缺陷的測試用例,可以將這部分測試用例在運行的時候暫時跳過,等功能實現或者 bug 解決之後再加入運行。

使用方法如下:

pytest -k '類名' 
pytest -k '方法名' 
pytest -k '類名 and not 方法名' //運行類裡所有的方法,不包含某個方法

-x 參數

遇到用例失敗立即停止運行。

應用場景:在回歸測試過程中,假如一共有10條基礎用例,當開發人員打完包提交測試的時候,需要先運行這10條基礎用例,全部通過才能提交給測試人員正式測試。如果有一條用例失敗,都將這個版本打回給開發人員。這時就可以添加 -x 參數,一旦發現有失敗的用例即中止運行。

使用方法如下:

pytest -x

--maxfail 參數

用例失敗個數達到閥值停止運行。具體用法:

pytest --maxfail=[num] 

應用場景:在回歸測試過程中,假如一共有10條基礎用例,當開發人員打完包提交測試的時候,需要先運行這10條基礎用例,全部通過才能提交給測試人員正式測試。如果運行過程中有 [num] 條用例失敗,即中止運行,後面測試用例都放棄執行,直接退出。這時可以使用 --maxfail 參數。

使用方法如下:

-m 參數

將運行有 @pytest.mark.[標記名] 這個標記的測試用例。

應用場景:在自動化測試過程中可以將測試用例添加標籤進行分類,比如登錄功能、搜索功能、購物車功能、訂單結算功能等,在運行的時候可以只運行某個功能的所有的測試用例,比如這個版本只想驗證登錄功能,那就在所有登錄功能的測試用例方法上面加上裝飾符 @pytest.mark.login ,運行的時候使用命令添加一個 -m 參數,例如執行 pytest -m login 命令就可以只執行登錄功能這部分的測試用例。

使用方法如下:

pytest -m [標記名]  

運行模式

pytest 提供了多種運行模式,讓開發和調試更得心應手。指定某個模塊,執行單獨一個 pytest 模塊。

應用場景:在編寫測試用例的時候,經常會單獨調試某個類,或者某個方法,這時可以使用 Pycharm 裡面自帶的調試方式,點擊用例方法名前面的綠色按鈕,也可以使用命令行的方式單獨運行某個用例。

pytest 中可以使用 pytest 文件名.py 單獨執行某個 Python 文件,也可以使用 pytest 文件名.py::類名 單獨執行某個文件中的類,使用 pytest 文件名.py::類名::方法名 單獨執行類中的某個方法。

使用方法如下:

pytest 文件名.py
pytest 文件名.py::類名
pytest 文件名.py::類名::方法名

在 Pycharm 中運行 pytest 用例

打開 Pycharm -> 設置 -> Tools -> Python Integrated Tools -> Testing: pytest

首先次設置成 pytest ,需要安裝 pytest,可以直接按照這個頁面的提示點擊「fix」,也可以在 Project interpreter 裡面添加 pytest 依賴包。安裝完 pytest 之後,編寫的符合規則的測試用例都能被識別出來並且標出一個綠色的執行按鈕,點擊這個按鈕也能執行某個方法或者某個類。例如:

Pycharm 設置運行方式為 pytest 之後,用例左側會顯示綠色按鈕,可以直接點擊這個按鈕來執行這條用例。

pytest 框架結構

與 unittest 類似,執行用例前後會執行 setup,teardown 來增加用例的前置和後置條件。pytest 框架中使用 setup,teardown 更靈活,按照用例運行級別可以分為以下幾類:

模塊級(setup_module/teardown_module)在模塊始末調用

函數級(setup_function/teardown_function)在函數始末調用(在類外部)

類級(setup_class/teardown_class)在類始末調用(在類中)

方法級(setup_method/teardown_methond)在方法始末調用(在類中)

方法級(setup/teardown)在方法始末調用(在類中)

調用順序:

setup_module > setup_class >setup_method > setup > teardown > teardown_method > teardown_class > teardown_module

驗證上面的執行順序,看下面的案例。

創建文件名為 test_run_step.py ,代碼如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def setup_module():
    print("\nsetup_module,只執行一次,當有多個測試類的時候使用")

def teardown_module():
    print("\nteardown_module,只執行一次,當有多個測試類的時候使用")

class TestPytest1(object):

    @classmethod
    def setup_class(cls):
        print("\nsetup_class1,只執行一次")

    @classmethod
    def teardown_class(cls):
        print("\nteardown_class1,只執行一次")

    def setup_method(self):
        print("\nsetup_method1,每個測試方法都執行一次")

    def teardown_method(self):
        print("teardown_method1,每個測試方法都執行一次")

    def test_three(self):
        print("test_three,測試用例")

    def test_four(self):
        print("test_four,測試用例")

class TestPytest2(object):

    @classmethod
    def setup_class(cls):
        print("\nsetup_class2,只執行一次")

    @classmethod
    def teardown_class(cls):
        print("\nteardown_class2,只執行一次")

    def setup_method(self):
        print("\nsetup_method2,每個測試方法都執行一次")

    def teardown_method(self):
        print("teardown_method2,每個測試方法都執行一次")

    def test_two(self):
        print("test_two,測試用例")

    def test_one(self):
        print("test_one,測試用例")

上面的代碼執行完成後,查看測試結果來分析執行測試順序:

...
plugins: html-2.0.1, rerunfailures-8.0, xdist-1.31.0, ordering-0.6, forked-1.1.3, allure-pytest-2.8.11, metadata-1.8.0
collecting ... collected 4 items

test_run.py::TestPytest1::test_three 
setup_module,只執行一次,當有多個測試類的時候使用
setup_class1,只執行一次
setup_method1,每個測試方法都執行一次  PASSED      [ 25%]test_three,測試用例
teardown_method1,每個測試方法都執行一次
test_run.py::TestPytest1::test_four 
setup_method1,每個測試方法都執行一次    PASSED    [ 50%]test_four,測試用例
teardown_method1,每個測試方法都執行一次
teardown_class1,只執行一次
test_run.py::TestPytest2::test_two 
setup_class2,只執行一次
setup_method2,每個測試方法都執行一次    PASSED    [ 75%]test_two,測試用例
teardown_method2,每個測試方法都執行一次
test_run.py::TestPytest2::test_one 
setup_method2,每個測試方法都執行一次    PASSED     [100%]test_one,測試用例
teardown_method2,每個測試方法都執行一次
teardown_class2,只執行一次
teardown_module,只執行一次,當有多個測試類的時候使用
============================== 4 passed in 0.03s ===============================
...

從上面的結果可以看出 setup_module 和 teardown_module 在整個模塊只執行一次,setup_class 和 teardown_class 在類裡面只執行一次,setup_method 和 teardown_method 在每個方法前後都會調用。

控制用例的執行順序

pytest 加載所有的測試用例是亂序的,如果想指定用例的順序,可以使用 pytest-order 插件,指定用例的執行順序只需要在測試用例的方法前面加上裝飾器 @pytest.mark.run(order=[num]) 設置order的對應的num值,它就可以按照 num 的大小順序來執行。

應用場景:有時運行測試用例需要指定它的順序,比如有些場景需要先運行完登錄,才能執行後續的流程比如購物流程,下單流程,這時就需要指定測試用例的順序。通過 pytest-ordering 這個插件可以完成用例順序的指定。

安裝

pip install pytest-ordering

案例

創建一個測試文件「test_order.py」,代碼如下:

import pytest

class TestPytest(object):

    @pytest.mark.run(order=-1)
    def test_two(self):
        print("test_two,測試用例")

    @pytest.mark.run(order=3)
    def test_one(self):
        print("test_one,測試用例")

    @pytest.mark.run(order=1)
    def test_three(self):
        print("\ntest_three,測試用例")

執行結果,如下查看執行順序:

省略...
plugins: html-2.0.1, rerunfailures-8.0, xdist-1.31.0, \
ordering-0.6, forked-1.1.3, allure-pytest-2.8.11, metadata-1.8.0
collecting ... collected 3 items

test_order.py::TestPytest::test_three 
test_order.py::TestPytest::test_one 
test_order.py::TestPytest::test_two 
省略...

從上面的執行結果可以看出,執行時以 order 的順序執行:order=1,order=3,order=-1。

以上,更多進階內容,在後續文章分享。

【相關閱讀】

推薦學習

推薦霍格沃茲出品 《測試開發實戰進階》課程,資深測試架構師、開源項目作者親授 BAT 大廠前沿最佳實踐。4 個月 20+ 項目實戰強化訓練,帶你一站式掌握 BAT 測試開發工程師必備核心技能(對標阿里P6+,年薪50W+)!學員直推 BAT 名企測試經理,普遍漲薪 50%+!

🔥15 期熱招中🔥


霍格沃茲測試學院憑過硬課程課程、超強服務實力和超高好評率成為「騰訊課堂官方認證機構」並榮獲「最受歡迎獎」(測試類目僅此一家)

相關焦點

  • 基於Pytest框架的自動化測試開發實踐(萬字長文入門篇)
    「 Pytest是Python的一種易用、高效和靈活的單元測試框架,可以支持單元測試和功能測試。本文不以介紹Pytest工具本身為目的,而是以一個實際的API測試項目為例,將Pytest的功能應用到實際的測試工程實踐中,教大家將Pytest用起來。
  • python自動化測試之pytest框架
    pytest測試框架也是主流的一個測試框架,想比於unnitest框架來說,其不需要像unittest那樣單獨創建類繼承unittest.TestCase,而只需要創建測試類或者測試文件,然後以test開頭,pytest可以按照這個規則找到測試用例並執行。
  • 實戰 | 接口自動化測試框架開發(Pytest+Allure+AIOHTTP+用例自動生成)
    ,然而接口的數量一般都很多,而且會越來越多,所以提高執行效率很有必要;接口測試的用例其實也可以用來兼做簡單的壓力測試,而壓力測試需要並發;接口測試的用例有很多重複的東西,測試人員應該只需要關注接口測試的設計,這些重複勞動最好自動化來做;Pytest 和 Allure 太好用了,新框架要集成它們;接口測試的用例應該儘量簡潔,最好用 yaml,這樣數據能直接映射為請求數據
  • python pytest接口自動化框架搭建
    pytest2.編寫單測用例在pytest框架中,有如下約束:所有的單測文件名都需要滿足test_*.py格式或*_test.py格式。此時,在執行pytest命令時,會自動從當前目錄及子目錄中尋找符合上述約束的測試函數來執行。
  • 技術面試沒過,居然是因為沒用過 pytest 單元測試框架
    他說面試官問了一些 pytest 單元測試框架相關的知識,包括什麼插件系統和用力篩選。但是他之前的公司用的技術是基於 unittest 的,沒有用過 pytest。也就是因此被面試官給卡住了。實際上他在面試之前已經了解過 pytest 的一些基礎用法,但是網上的一些資料,都是停留基礎講解,沒有深入到 pytest 內部運行和一些高級特性。
  • Pytest丨如何使用全功能的Python測試框架?小白必看
    關注我,每周分享軟體測試技術乾貨、面試經驗,想要進入軟體測試學習交流群的可以直接私信我哦~~我們在寫自動化的過程中,用例的斷言也是至關重要的,斷言可以幫助我們判斷用例測試點是否成功和失敗。當然在我們這麼強大的pytest框架中,斷言也是比較強大的。為什麼?繼續往下看。
  • 手把手教你pytest測試框架(7)-fixture裝飾器
    文 | 遠山近海
  • 使用pytest-xdist實現分布式APP自動化測試
    不知道大家有沒有遇到這樣一種情況,實際工作中,app自動化測試的用例可能是成百上千條的,如果放在一臺機器上跑,消耗的時間非常久,那能不能使用分布式的來跑測試用例呢?比如有1000條測試用例,給A機器分配500個,給B機器分配500個,同時去跑,這樣耗時就大大減少。剛好pytest-xdist為我們提供了一種可能pytest-xdist是一款分布式測試插件。它在pytest的基礎上做了一些獨有的測試執行模式的擴展。
  • Python測試框架Pytest的常用插件測試報告
    一、pytest-html 生成 html 測試報告要求:Python 3.6+安裝:pip install pytest-html文檔:https://github.com/pytest-dev/pytest-html、https://www.cnblogs.com
  • APP UI自動化測試思路總結
    接下來,一起總結一下APP UI自動化測試的思路吧。一,開發語言選擇通常用於自動化測試的程式語言有:Python、Java、Javascript、Ruby、C#、PHP等。一般我們會選擇自己熟悉的程式語言來編寫自動化腳本,但對於編程基礎基本為0的童鞋(或者專注於做自動化測試的童鞋),推薦學習使用Python。
  • 從小白變高手,這7個超實用的Python自動化測試框架請收好!
    隨著技術的進步和自動化技術的出現,市面上出現了一些自動化測試框架。只需要進行一些適用性和效率參數的調整,這些自動化測試框架就能夠開箱即用,大大節省了開發時間。而且由於這些框架被廣泛使用,他們具有很好的健壯性,並且具有廣泛多樣的用例集和技術來輕易發現微小的缺陷。今天,我們將看一看常見的 Python 自動化測試框架。
  • APP UI自動化測試,思路全總結在這裡了
    一般我們會選擇自己熟悉的程式語言來編寫自動化腳本,但對於編程基礎基本為0的童鞋(或者專注於做自動化測試的童鞋),推薦學習使用Python。相對於其他語言,Python做自動化測試有以下優點:選擇開發語言之後,我們需要選擇UI測試框架。目前較為主流或者使用較多的APP UI自動化測試框架有Appium、Airtest等。
  • Pytest的基本應用(一)
    在Python的程式語言中,單元測試框架主要是pytest,unittest,和nose,其中應用最廣泛的是unittest和pytest
  • Python自動化之unittest框架
    在金字塔模型的測試理論體系中,單元測試是最底層的測試,而且是測試覆蓋最多的層面。在自動化所有的測試體系中,不管是單元測試,還是接口測試以及基於UI的自動化測試,都需要單元測試框架,在Python語言中,最常用的單元測試框架是unittest和pytest,今晚主要來介紹unittest單元測試框架,後期逐步的介紹pytest測試框架在自動化測試中的應用。
  • 測試工程師必須要學會的APP UI 自動化都在這裡了!
    一般我們會選擇自己熟悉的程式語言來編寫自動化腳本,但對於編程基礎基本為0的童鞋(或者專注於做自動化測試的童鞋),推薦學習使用Python。相對於其他語言,Python做自動化測試有以下優點:選擇編開發語言之後,我們需要選擇UI測試框架。目前較為主流或者使用較多的APP UI自動化測試框架有Appium、Airtest等。
  • 用於全棧自動化測試的最佳Python工具!
    Splinter是一個使用Python測試web應用程式的開源工具。它允許您自動化瀏覽器操作,例如訪問url並與它們的項進行交互。它使得編寫python Selenium測試更容易,因為它有一個高級API,可以讓您更容易地為瀏覽器應用程式開發自動化腳本。  如果您想使用Python進行測試自動化,那麼使用Robot框架是不會出錯的。
  • 自動化測試面試題(附答案)
    下面是正題崗位JD 1、【技術能力】能獨立完成產品線中自動化測試工作,根據測試任務,搭建軟體測試環境,編寫測試腳本,輸出報告;2、【項目管理】熟練開發測試工具、測試腳本,及迭代優化測試框架,使用合理方式進行自動化管理項目;3、【業務推動】對測試項目的結果負責,使用合理方式推動業務端測試的效率、開發質量;
  • Pytest之並發執行(十四)
    不管是UI自動化測試用例還是API的自動化測試用例,在編寫的使用都需要注意每個測試用例執行的獨立性,也就是說編寫的每個測試用例都是互相不依賴的
  • pytest「conftest、pytest參數化、重運行、出測試報告」
    文章總覽圖一、conftest問題整理:1.這個conftest.py分路徑嗎?如果在TestCases下建這個包可以直接用嗎?二、pytest參數化pytest當中不能使用ddt。流程性質的東西,在pytest裡面叫做參數化。
  • 同時連接多臺手機,使用appium實現app自動化測試
    同時連接多臺手機,使用appium實現app自動化測試使用appium可以實現app自動化測試,我們之前是連接一臺手機去運行,如何同時連接多臺手機呢?很多人可能想到的是多線程(threading)。環境準備appium的安裝:adt,nodejs,appium的python庫,appium serverpytest的安裝:pytestallure的安裝:allure的python庫pytest-allure-adaptor