pytest fixture-安全地運(yùn)行多個(gè)斷言語(yǔ)句

2022-03-18 14:13 更新

有時(shí),您可能想在完成所有設(shè)置之后運(yùn)行多個(gè)斷言,這是有意義的,因?yàn)樵诟鼜?fù)雜的系統(tǒng)中,單個(gè)操作可以啟動(dòng)多個(gè)行為。Pytest有一種方便的方式來(lái)處理這個(gè)問(wèn)題,它結(jié)合了我們到目前為止所討論過(guò)的一些內(nèi)容。

所有需要做的就是逐步擴(kuò)展到更大的范圍,然后將??act??步驟定義為自動(dòng)使用??fixture??,最后,確保所有??fixture??都針對(duì)更高級(jí)別的范圍。

讓我們從上面的例子中提取一個(gè)例子,并對(duì)其進(jìn)行一些調(diào)整。假設(shè)除了在標(biāo)題中檢查歡迎消息外,我們還希望檢查退出按鈕和到用戶配置文件的鏈接。

讓我們看看如何構(gòu)造它,這樣我們就可以在不重復(fù)所有步驟的情況下運(yùn)行多個(gè)斷言。

# contents of tests/end_to_end/test_login.py
from uuid import uuid4
from urllib.parse import urljoin

from selenium.webdriver import Chrome
import pytest

from src.utils.pages import LoginPage, LandingPage
from src.utils import AdminApiClient
from src.utils.data_types import User


@pytest.fixture(scope="class")
def admin_client(base_url, admin_credentials):
    return AdminApiClient(base_url, **admin_credentials)


@pytest.fixture(scope="class")
def user(admin_client):
    _user = User(name="Susan", username=f"testuser-{uuid4()}", password="P4$word")
    admin_client.create_user(_user)
    yield _user
    admin_client.delete_user(_user)


@pytest.fixture(scope="class")
def driver():
    _driver = Chrome()
    yield _driver
    _driver.quit()


@pytest.fixture(scope="class")
def landing_page(driver, login):
    return LandingPage(driver)


class TestLandingPageSuccess:
    @pytest.fixture(scope="class", autouse=True)
    def login(self, driver, base_url, user):
        driver.get(urljoin(base_url, "/login"))
        page = LoginPage(driver)
        page.login(user)

    def test_name_in_header(self, landing_page, user):
        assert landing_page.header == f"Welcome, {user.name}!"

    def test_sign_out_button(self, landing_page):
        assert landing_page.sign_out_button.is_displayed()

    def test_profile_link(self, landing_page, user):
        profile_href = urljoin(base_url, f"/profile?id={user.profile_id}")
        assert landing_page.profile_link.get_attribute("href") == profile_href

請(qǐng)注意,這些方法只是在簽名中以形式引用??self??。沒(méi)有任何狀態(tài)綁定到實(shí)際的測(cè)試類,因?yàn)樗赡茉??unittest??中,?TestCase??框架。一切都由pytest ??fixture??系統(tǒng)管理。

每個(gè)方法只需要請(qǐng)求它實(shí)際需要的??fixture??,而不必?fù)?dān)心順序。這是因?yàn)??act fixture??是一個(gè)自動(dòng)使用的??fixture??,它確保所有其他??fixture??在它之前執(zhí)行。不需要進(jìn)行更多的狀態(tài)更改,因此測(cè)試可以自由地執(zhí)行任意數(shù)量的非狀態(tài)更改查詢,而不會(huì)有得罪其他測(cè)試的風(fēng)險(xiǎn)。

登錄??fixture??也是在類內(nèi)部定義的,因?yàn)椴皇悄K中的所有其他測(cè)試都期望成功登錄,而且對(duì)于另一個(gè)測(cè)試類,該行為可能需要以稍微不同的方式處理。例如,如果我們想編寫另一個(gè)關(guān)于提交錯(cuò)誤憑證的測(cè)試場(chǎng)景,我們可以通過(guò)在測(cè)試文件中添加如下內(nèi)容來(lái)處理它:

class TestLandingPageBadCredentials:
    @pytest.fixture(scope="class")
    def faux_user(self, user):
        _user = deepcopy(user)
        _user.password = "badpass"
        return _user

    def test_raises_bad_credentials_exception(self, login_page, faux_user):
        with pytest.raises(BadCredentialsException):
            login_page.login(faux_user)


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)