pytest fixture-安全地运行多个断言语句

2022-03-18 14:13 更新

有时,您可能想在完成所有设置之后运行多个断言,这是有意义的,因为在更复杂的系统中,单个操作可以启动多个行为。Pytest有一种方便的方式来处理这个问题,它结合了我们到目前为止所讨论过的一些内容。

所有需要做的就是逐步扩展到更大的范围,然后将​​act​​步骤定义为自动使用​​fixture​​,最后,确保所有​​fixture​​都针对更高级别的范围。

让我们从上面的例子中提取一个例子,并对其进行一些调整。假设除了在标题中检查欢迎消息外,我们还希望检查退出按钮和到用户配置文件的链接。

让我们看看如何构造它,这样我们就可以在不重复所有步骤的情况下运行多个断言。

# 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​​。没有任何状态绑定到实际的测试类,因为它可能在​​unittest​​中,​TestCase​​框架。一切都由pytest ​​fixture​​系统管理。

每个方法只需要请求它实际需要的​​fixture​​,而不必担心顺序。这是因为​​act fixture​​是一个自动使用的​​fixture​​,它确保所有其他​​fixture​​在它之前执行。不需要进行更多的状态更改,因此测试可以自由地执行任意数量的非状态更改查询,而不会有得罪其他测试的风险。

登录​​fixture​​也是在类内部定义的,因为不是模块中的所有其他测试都期望成功登录,而且对于另一个测试类,该行为可能需要以稍微不同的方式处理。例如,如果我们想编写另一个关于提交错误凭证的测试场景,我们可以通过在测试文件中添加如下内容来处理它:

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)


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号