pytest fixture-安全地運行多個斷言語句

2022-03-18 14:13 更新

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

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

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

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

# 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

請注意,這些方法只是在簽名中以形式引用??self??。沒有任何狀態(tài)綁定到實際的測試類,因為它可能在??unittest??中,?TestCase??框架。一切都由pytest ??fixture??系統(tǒng)管理。

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

登錄??fixture??也是在類內(nèi)部定義的,因為不是模塊中的所有其他測試都期望成功登錄,而且對于另一個測試類,該行為可能需要以稍微不同的方式處理。例如,如果我們想編寫另一個關(guān)于提交錯誤憑證的測試場景,我們可以通過在測試文件中添加如下內(nè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)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號