亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

首頁 慕課教程 PyCharm 編輯器教程 PyCharm 編輯器教程 在 PyCharm 里使用 Pytest 測試框架

在 PyCharm 里使用 Pytest 測試框架

在上一小節已經介紹了基于 Python unittest 在 PyCharm 里執行測試相關知識,本節將繼續介紹另一個比較流行的測試框架 Pytest。

1. Pytest 介紹

Pytest 是 Python 語言中一款強大的單元測試框架,它是基于 unittest 開發的擴展框架,用來管理和組織測試用例,可應用在單元測試、自動化測試工作中。

Pytest 主要特點:

1. 兼容性好: 支持 Python 2.7,Python 3.4+。

2. 與 unittest 和 nose 測試框架兼容: 如果之前測試用例全部是基于 unittest 或者 nose 來編寫的,執行 Pytest 命令同樣可以正常運行并得到結果。因此無需擔心遷移測框架從而帶來額外的人工成本。

3. 豐富的插件支持: 大約有 300 多個,像 Pytest-repeat, pytest-xdist,pytest-ordering,pytest-rerunfailures 以及 pytest-html 這些常用插件在測試重復執行、并發與生成報告方面都提供了非常強大的支持。

4. 允許直接使用 assert 進行斷言:相比 unittest 簡單,unittest 定義了 assertEqual、assertIn、assertTrue、assertFalse 等一系列斷言。

5. 可以自動尋找單測文件、類和函數:Pytest 要求所有的單測文件名都需要滿足 test_.py 格式或_test.py 格式。在單測文件中,可以包含 test_ 開頭的函數,也可以包含 Test 開頭的類。在單測類中,可以包含一個或多個 test_ 開頭的函數。在執行 Pytest 命令時,會自動從當前目錄及子目錄中尋找符合上述約束的測試函數來執行。

6. 提供應用不同范圍前置/后置方法: Pytest 提供了模塊級、函數級、類級、方法級的setup/teardown,比 unittest 的 setUp/tearDown 更靈活。

7. 分類執行與測試數據參數化簡單 : unittest 需依賴 ddt 庫實現數據參數化,而 Pytest 直接使用@pytest.mark.parametrize 裝飾器。

總之, Pytest 因為其功能強大性及使用的方便性,已經成為主流的測試框架之一,unittest 更適合入門級的測試,當執行比較復雜的測試 Pytest 就更適合一些,這也是為什么我們會單列一小節講 Pytest 的原因。更多關于 Pytest 使用請參考官網。

2. 使用 Pytest 執行測試

在 PyCharm 里使用 Pytest 執行測試的過程與 unittest 是一致的,所以對于步驟上的操作在本小節將不再過多說明,將把重點關注在 Pytest 一些特性上。

2.1 配置測試框架

主菜單: PyCharm/File -> Preference/Settings -> Tools -> Python Integrated Tools, 點擊 Default Test Runner 選擇 Pytest。
圖片描述

2.2 創建測試

創建一個新的 Python project,增加新文件 rectangle.py,添加下面的代碼到文件, 繼續沿用上一小節用到的待測代碼。

import math


class Rectangle:
    def __init__(self, length, width, size=(40, 20)):
        self.length = length
        self.width = width
        self._size = size

    def area(self):
        area = self.length * self.width
        return area

    def perimeter(self):

        perimeter = (self.length + self.width) * 2
        return perimeter

    def diff(self):

        diff = math.fabs(self.length - self.width)
        return diff
    
    def resize(self, width, height):
        if width <= 0 or height <= 0:
            raise ValueError("illegal size")
        self._size = (width, height)

    def get_length(self):
        return self.length

    def get_width(self):
        return self. width

在編輯器中,將光標放在類聲明或方法中的位置。

  • 從主菜單中,選擇 Navigate -> Test。
  • 編輯器內,右鍵上下文菜單中選擇 Go to -> Test (??T: Ctrl + Shift + T)

PyCharm 顯示可用測試的列表。單擊"創建新測試"。在打開 Create test 對話框中進行設置, 點擊 OK 會自動生成測試文件 test_rectangle 與 測試方法模板。

圖片描述

生成的模板 如下圖所示: 沒有像 unittest 那樣創建同名測試類,無需像導入 unittest 一樣導入pytest , 斷言直接用 assert。使用pytest 寫測試用例看上去更簡單一些。

圖片描述

2.3 修改代碼與執行測試

根據 Pytest 規則更新代碼:

from rectangle import Rectangle


def test_area():
    rect = Rectangle(30, 15)
    assert rect.area() == 450


def test_perimeter():
    rect = Rectangle(30, 15)
    assert rect.perimeter() == 90

在 編輯器的上下文菜單,選擇 Run pytest for Name,會默認運行當前文件所有以 ‘test’ 開頭的所有方法。Run 窗口會自動彈出,顯示測試結果。

圖片描述

3. Pytest 一些特性

從上面介紹可以看出,無論用哪種測試框架,基本流程都是一樣的。下面介紹一些Pytest 一些特性,這些特性都是使用頻率比較高,也是相對于unittest 測試功能更為便利與先進的功能。

3.1 使用 fixture

fixture 是 Pytest 特有的功能,它用 pytest.fixture 標識,定義在函數前面。在你編寫測試函數的時候,你可以將此函數名稱做為傳入參數,pytest將會以依賴注入方式,將該函數的返回值作為測試函數的傳入參數。

我們可以把fixture看做是資源,在你的測試用例執行之前需要去配置這些資源,執行完后需要去釋放資源。比如module類型的fixture,適合于那些許多測試用例都只需要執行一次的操作。更多使用請參考這里

上面的兩個測試方法都有 rect = Rectangle(30, 15) 實例化類, 此時可以使用 fixture 簡化代碼:

from rectangle import Rectangle
import pytest


@pytest.fixture()
def my_rect():
    rect = Rectangle(30, 15)
    return rect


def test_area(my_rect):
    assert my_rect.area() == 450


def test_perimeter(my_rect):
    assert my_rect.perimeter() == 90

3.2 標記用例

pytest.mark 定義在函數前面??梢越o用例打標簽,用于給用例分類與篩選用例。每個用例可以加多個標簽。在執行用例時根據標簽名選擇執行。相比unittest 通過 TestSuite 加載不同的測試用例要方便的多。

from rectangle import Rectangle
import pytest


@pytest.fixture()
def my_rect():
    rect = Rectangle(30, 15)
    return rect


@pytest.mark.smoke
@pytest.mark.p1
def test_area(my_rect):
    assert my_rect.area() == 450


@pytest.mark.regression
def test_perimeter(my_rect):
    assert my_rect.perimeter() == 90

在運行之前, 需要先創建一個pytest.ini 文件在當前項目下,注冊標簽名。

[pytest]
markers=
    smoke
    p1
    regression

運行的時候加參數 -m 標簽名, 就可以只執行帶標簽名的用例。

圖片描述

3.3 測試數據參數化

你可能希望在預定義的數據集上運行測試。PyCharm 支持通過 @pytest.mark.parametrize 在 pytest 中實現的測試參數化。更多使用參考

增加下面的測試用例在 test_rectangle.py 文件中,傳遞三個參數兩組數據給測試用例。如果數據可以用于其它用例,也可以定義數據做為全局變量。

@pytest.mark.parametrize(("length", "width", "expected_diff"), [(30, 20, 10), (20, 20, 0)])
def test_diff(length, width, expected_diff):
    rect = Rectangle(length, width)
    assert rect.diff() == expected_diff

點擊編輯器側邊框綠色箭頭執行上面的用例,可以看到用例執行了兩次:

圖片描述

3.4 重復運行用例

有時候需要重復運行單個用例,Pytest也提供相應的插件支持 。需要事先安裝包 pytest-repeat, Preference/Settings -> Project -> Python Interpreter

圖片描述

通過在函數前加 @pytest.mark.repeat(次數),指定函數重復的次數,也可以通過命令行–count=次數,為所有函數級別方法指定重復次數。

@pytest.mark.regression
@pytest.mark.repeat(5)
def test_perimeter(my_rect):
    assert my_rect.perimeter() == 90

執行測試用例,可以看到用例被執行了5 次:

圖片描述

3.5 并發執行用例

有時候為了節省測試時間,需要并發執行測試用例。Pytest 是支持并發測試的,需提前安裝包 pytest-xdist。運行的時候加參數 -n 并發進程數 或者 -n auto (根據當前cpu信息自動分配合理的核數運行用例。也可以在 pytest.ini 指定。

[pytest]
addopts = -n3

為了增強演示效果,在三個用例里都增加了10秒的延遲,并設置了三個并發,可以觀察到三個用例是同時執行的。

圖片描述

Tips:當使用這個插件做并發測試時,只能用于沒有依賴關系的測試用例。

4. 小結

本節主要介紹了在 PyCharm 里如何使用 Pytest 測試框架和一些測試過程中常用插件。Pytest 是功能非常強大的測試框架,在業內也比較被推崇,如果想真正掌握,建議多參考官方文檔及相關的插件說明文檔,這將幫助我們在開發單元測試與自動化測試過程中事半功倍。
圖片描述