天天看點

pytest系列——Fixture的使用

pytest系列——Fixture的使用
pytest系列——Fixture的使用

迅捷小莫

本公衆号日常更新自動化技術,程式設計知識,迅捷掌握一切測試工程師需要的技術!

12篇原創内容

公衆号

Pytest

在pytest中,我們怎麼去實作unittest中的 setUp,teardown呢?

首先我們要明确一下,這些是做什麼用的。在unittest中我們通常分為幾個部分,有測試用例(TestCase),測試套件(TestSuite),測試固件(Fixtures), 測試執行器(TestRunner)等。而setUp, tearDown這些方法,就屬于Fixtures這部分,也就是測試固件。我們通常利用測試固件去做一些前後置操作 ,比如測試資料準備,登入,測試資料清洗等等。

那麼我們pytest中有沒有這個測試固件呢?強大的pytest,那必須有呀!本期為大家介紹的是pytest中的測試固件——Fixture,敲黑闆,重點重點重點!必須掌握!

01

實作第一個Fixture

首先,定義一個Fixture非常簡單,所謂的Fixture,無非就是python中的一個函數而已。但是這個函數必須要被pytest中的一個裝飾器裝飾,那它就會變成一個Fixture, 如下:

@pytest.fixture()  # fixture裝飾器
def setup(): # 随意定義一個函數
    print("setup...") # 函數内容
           

沒什麼問題,現在這個setup就是一個Fixture了。那我們怎麼使用呢?通常我們隻需要在測試函數中,傳入這個setup也就是Fixture的這個函數名即可:

import pytest  # 導入pytest


@pytest.fixture()
def setup():
    print("setup...")


def test_pytest(setup):  # 定義測試函數
    print("test_pytest run")


if __name__ == '__main__':  # 定義主函數
    pytest.main()  # 調用pytest
           

執行結果可以看到:

pytest系列——Fixture的使用

在測試函數test_pytest執行前,執行了一次setup函數。這裡test_pytest實際上是把setup這個函數傳入,優先執行了,那麼這裡是不是就類似我們unittest中的setUp了呀 。但是,還差一點點。

在unitttest中,我們所有的測試方法,都會去執行一遍setUp, 但是在上面可以看到,我們必須在測試函數中傳入Fixture才行,那有什麼辦法可以每個測試函數都去自動執行setUp呢?

那麼就要用到fxiture中的autouse參數!

02

Fixture的自動執行

@pytest.fixture中,我們可以傳入一個叫autouse的參數并設定為True,這裡代表每個測試函數會預設去執行fixture,并且我們測試函數不需要傳入setup也可以執行:

@pytest.fixture(autouse=True) # 傳入autouse
def setup():
    print("setup...")
           

是以代碼變成了下面這個樣子:

import pytest  # 導入pytest


@pytest.fixture(autouse=True)
def setup():
    print("setup...")


def test_pytest():  # 定義測試函數
    print("test_pytest run")


def test_pytest2():  # 定義測試函數2
    print("test_pytest2 run")


if __name__ == '__main__':  # 定義主函數
    pytest.main()  # 調用pytest
           

我們現在多定義了一個test_pytest2,友善 我們測試。執行結果如下:

pytest系列——Fixture的使用

是不是每個測試函數都執行了一遍setup,那就已經滿足了我們的需求了,非常的友善。但是現在又會有新的問題,我如果想實作每個測試類前執行一次,或者每個測試子產品執行前執行一次,那怎麼做呢?這就引申出了,Fixture中的作用域的問題,接着往下看。

03

Fixture的作用域

在@pytest.fixture中有一個scope參數可以幫助我們修改Fixture的作用域,scope支援以下四種作用域,按從大到小依次是:

  1. session (會話)
  2. module (子產品)
  3. class (類)
  4. function (函數)

而fixture預設的scope為function,是以我們不傳的時候,對測試函數依然生效。

我們将scope指定為class,可以實作每個測試類前執行一次:

import pytest  # 導入pytest


@pytest.fixture(scope="class", autouse=True)
def setup():
    print("class setup...")


class TestPytest:

    def test_pytest(self):  # 定義測試函數
        print("test_pytest run")

    def test_pytest2(self):  # 定義測試函數
        print("test_pytest2 run")


if __name__ == '__main__':  # 定義主函數
    pytest.main()  # 調用pytest
           

執行結果如下:

pytest系列——Fixture的使用

這時,我們的setup隻在測試類執行前執行了一次,沒得問題。

那麼可能有人想問,session和module是怎麼用的呢?其實session的話是指pytest的會話,即所有的測試執行開始到結束,隻會執行一次的操作。而module指的是,在某個py檔案執行前,執行一次,因為在py中,module即py檔案。

04

Fixture的全局注冊

在上面的講解中,我們的Fixture都是和測試函數在同一py檔案内,那如果我想在另外一個py檔案中,也使用我們的Fixture怎麼辦,這時候就需要把Fixture注冊為全局Fixture。

那麼如何把Fixture注冊為全局的呢?這裡要介紹一個新的pytest檔案,叫做conftest.py,這個檔案在pytest中被大量使用,用于定義一些Hook相關函數以及注冊全局的Fixture函數。

我們需要在根目錄下,建立一個conftest.py:

pytest系列——Fixture的使用

然後在這個檔案中,我們可以把之前的Fixture代碼放入這個檔案内:

pytest系列——Fixture的使用

隻要定義在conftest.py中的Fixture,我們 即視為全局的Fixture,可以在多個py檔案中去使用。

05

Fixture實作teardown

在前面我們介紹的都是setup,那利用Fixture能不能實作我們的teardown呢?其實也是非常的簡單,代碼如下:

@pytest.fixture(scope="class", autouse=True)
def setup():
    print("class setup...") # setup執行
    yield  # 使用yield分割
    print("class teardown") # teardown執行
           

這裡的yield可以幫助我們來做分割,在yield之前的屬于setup,而之後的就是teardown,我們再來看一下執行效果:

pytest系列——Fixture的使用

這裡可以看到,最後也輸出了我們teardown中的内容,非常的友善。

那麼本期的内容就到此結束,其實Fixture裡面還有很多東西沒有講到,小提莫就給大家抛磚引玉一下,我們下期再見!

pytest系列——Fixture的使用

迅捷小莫

本公衆号日常更新自動化技術,程式設計知識,迅捷掌握一切測試工程師需要的技術!

12篇原創内容

公衆号

pytest系列——Fixture的使用

個人微信号

ya1kaikai

繼續閱讀