美文网首页test
自动化测试框架pytest教程4-内置Fixture(夹具)

自动化测试框架pytest教程4-内置Fixture(夹具)

作者: python测试开发 | 来源:发表于2023-01-14 22:11 被阅读0次

    pytest的开发者在pytest中包含了一些常用的Fixture。pytest预包装的Fixture可以帮助你在测试中轻松而一致地做一些非常有用的事情。例如pytest包含的内置Fixture可以处理临时目录和文件,访问命令行选项,在测试会话之间通信,验证输出流,修改环境变量,以及询问警告。内置固定程序是对pytest的核心功能的扩展。

    tmp_path和tmp_path_factory

    tmp_path 和 tmp_path_factory Fixture用于创建临时目录。tmp_path返回一个pathlib.Path实例,该实例指向一个临时目录,在你的测试期间和更长的时间内一直存在。tmp_path_factory session-scope fixture返回一个TempPathFactory对象。这个对象有一个mktemp()函数来返回Path对象。你可以使用mktemp()来创建多个临时目录。

    ch4/test_tmp.py

    def test_tmp_path(tmp_path):
        file = tmp_path / "file.txt"
        file.write_text("Hello")
        assert file.read_text() == "Hello"
    
    
    def test_tmp_path_factory(tmp_path_factory):
        path = tmp_path_factory.mktemp("sub")
        file = path / "file.txt"
        file.write_text("Hello")
        assert file.read_text() == "Hello"
    

    使用tmp_path_factory,你必须调用mktemp()来获得一个目录。tmp_path_factory是session 范围。tmp_path是function 范围。

    在上一章中,我们使用标准库中的tempfile.TemporaryDirectory作为我们的db夹具。

    import cards
    import pytest
    
    
    @pytest.fixture(scope="session")
    def db(tmp_path_factory):
        """CardsDB object connected to a temporary database"""
        db_path = tmp_path_factory.mktemp("cards_db")
        db_ = cards.CardsDB(db_path)
        yield db_
        db_.close()
    
    

    很好。注意,这也允许我们删除两个导入语句,因为我们不需要导入 pathlib 或 tempfile。

    下面是两个相关的内置固定程序。

    *tmpdir-类似于tmp_path,但返回一个py.path.local对象。py.path.local比pathlib更早,pathlib是在Python 3.4中加入的。py.path.local在pytest中被慢慢淘汰,而采用pathlib版本。因此,我推荐使用 tmp_path。

    tmpdir_factory-类似于tmp_path_factory,只是它的mktemp函数返回py.path.local对象而不是pathlib.Path对象。

    所有pytest临时目录固定的基础目录是由系统和用户决定的,包括一个pytest-NUM部分,其中NUM在每个会话中递增。基准目录在会话结束后立即保持原样,以便在测试失败时进行检查。pytest最终会对其进行清理。只有最近的几个临时基础目录被留在系统中。

    如果需要,你也可以用pytest --basetemp=mydir指定你自己的基础目录。

    使用capsys

    有时应用程序代码向stdout、stderr等输出一些东西。

    $ cards version
    1.0.0
    $ python -i
    >>> import cards
    >>> cards.__version__
    '1.0.0'
    

    测试的一个方法是用subprocess.run()实际运行命令,抓取输出,并与API中的版本进行比较。

    import subprocess
    
    
    def test_version_v1():
        process = subprocess.run(
            ["cards", "version"], capture_output=True, text=True
        )
        output = process.stdout.rstrip()
        assert output == cards.__version__
    
    def test_version_v2(capsys):
        cards.cli.version()
        output = capsys.readouterr().out.rstrip()
        assert output == cards.__version__
    
    

    capsys能够捕获写到stdout和stderr的数据。我们可以直接调用CLI中实现这一功能的方法,并使用capsys来读取输出。

    capsys的另一个特点是能够暂时禁用pytest的正常输出捕获。pytest通常捕获你的测试和应用程序代码的输出。这包括打印语句。

    ch4/test_print.py

    def test_normal():
        print("\nnormal print")
    
    
    def test_fail():
        print("\nprint in failing test")
        assert False
    
    # 另一种总是包括输出的方法是使用 capsys.disabled()
    def test_disabled(capsys):
        with capsys.disabled():
            print("\ncapsys disabled print")
    
    

    如果我们运行它,没有看到任何输出。

    # pytest捕获了所有的输出。这有助于保持命令行会话的清洁。
    $ pytest test_print.py::test_normal
    ============================= test session starts =============================
    platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
    rootdir: D:\code\pytest_quick, configfile: pytest.ini
    plugins: allure-pytest-2.12.0, Faker-4.18.0, tep-0.8.2, anyio-3.5.0
    collected 1 item
    
    test_print.py .                                                          [100%]
    
    ============================== 1 passed in 0.10s ==============================
    
    # 有时我们希望看到所有的输出,即使是在通过测试时。我们可以使用-s或-capture=no标志来实现。
    
    $ pytest -s test_print.py::test_normal
    ============================= test session starts =============================
    platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
    rootdir: D:\code\pytest_quick, configfile: pytest.ini
    plugins: allure-pytest-2.12.0, Faker-4.18.0, tep-0.8.2, anyio-3.5.0
    collected 1 item
    
    test_print.py
    normal print
    .
    
    ============================== 1 passed in 0.07s ==============================
    
    $ pytest test_print.py::test_fail
    ============================= test session starts =============================
    platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
    rootdir: D:\code\pytest_quick, configfile: pytest.ini
    plugins: allure-pytest-2.12.0, Faker-4.18.0, tep-0.8.2, anyio-3.5.0
    collected 1 item
    
    test_print.py F                                                          [100%]
    
    ================================== FAILURES ===================================
    __________________________________ test_fail __________________________________
    
        def test_fail():
            print("\nprint in failing test")
    >       assert False
    E       assert False
    
    test_print.py:7: AssertionError
    ---------------------------- Captured stdout call -----------------------------
    
    print in failing test
    =========================== short test summary info ===========================
    FAILED test_print.py::test_fail - assert False
    ============================== 1 failed in 0.13s ==============================
    
    $ pytest test_print.py::test_disabled
    ============================= test session starts =============================
    platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
    rootdir: D:\code\pytest_quick, configfile: pytest.ini
    plugins: allure-pytest-2.12.0, Faker-4.18.0, tep-0.8.2, anyio-3.5.0
    collected 1 item
    
    test_print.py
    capsys disabled print
    .                                                          [100%]
    
    ============================== 1 passed in 0.08s ==============================
    
    
    

    以下是相关的内置Fixture。

    • capfd-类似于capsys,但捕获文件描述符1和2,通常与stdout和stderr相同。
    • capsysbinary- capsys捕捉文本,capsysbinary捕捉字节。
    • capfdbinary-捕获文件描述符1和2上的字节。
    • caplog-捕获用日志包编写的输出。

    相关文章

      网友评论

        本文标题:自动化测试框架pytest教程4-内置Fixture(夹具)

        本文链接:https://www.haomeiwen.com/subject/acqncdtx.html