UnitTest.TestCase支持¶
pytest
支持运行python unittest
-开箱即用的测试。它是为了利用现有的 unittest
-基于测试套件,将pytest用作测试运行程序,还允许增量调整测试套件,以充分利用pytest的特性。
运行现有的 unittest
-样式测试套件使用 pytest
类型:
pytest tests
Pytest将自动收集 unittest.TestCase
子类及其 test
方法在 test_*.py
或 *_test.py
文件夹。
几乎所有 unittest
支持以下功能:
@unittest.skip
风格装饰符;setUp/tearDown
;setUpClass/tearDownClass
;setUpModule/tearDownModule
;
到目前为止,pytest不支持以下功能:
load_tests protocol
②subtests
②
开箱即用的好处¶
通过使用pytest运行测试套件,您可以使用多个功能,在大多数情况下,无需修改现有代码:
Test selection options 使用
-k
和-m
旗帜;使用将测试分发到多个CPU pytest-xdist 插件;
使用 plain assert-statements 而不是
self.assert*
functions (unittest2pytest 在这方面非常有用);
中的pytest功能 unittest.TestCase
子类¶
以下Pytest功能适用于 unittest.TestCase
子类:
以下Pytest功能 不 工作,可能永远不会由于不同的设计理念:
第三方插件可能工作得不好,这取决于插件和测试套件。
将比重测试夹具混合到 unittest.TestCase
使用标记的子类¶
使用运行UnitTest pytest
允许您使用 fixture mechanism 具有 unittest.TestCase
风格测试。假设您至少略过了pytest fixture的特性,那么让我们从一个集成了pytest的示例开始。 db_class
fixture,设置一个类缓存的数据库对象,然后从unittest样式测试引用它:
# content of conftest.py
# we define a fixture function below and it will be "used" by
# referencing its name from tests
import pytest
@pytest.fixture(scope="class")
def db_class(request):
class DummyDB:
pass
# set a class attribute on the invoking test context
request.cls.db = DummyDB()
这定义了一个fixture函数 db_class
如果使用,每个测试类调用一次,并设置类级别 db
属性为 DummyDB
实例。fixture函数通过接收一个特殊的 request
允许访问的对象 the requesting test context 如 cls
属性,表示从中使用设备的类。该体系结构将实际测试代码中的fixture编写分离开来,并允许通过最小的引用(fixture名称)重用fixture。那么让我们写一个 unittest.TestCase
使用我们的fixture定义初始化:
# content of test_unittest_db.py
import unittest
import pytest
@pytest.mark.usefixtures("db_class")
class MyTest(unittest.TestCase):
def test_method1(self):
assert hasattr(self, "db")
assert 0, self.db # fail for demo purposes
def test_method2(self):
assert 0, self.db # fail for demo purposes
这个 @pytest.mark.usefixtures("db_class")
类decorator确保pytest fixture函数 db_class
每个类调用一次。由于故意失败的断言语句,我们可以查看 self.db
回溯中的值:
$ pytest test_unittest_db.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-6.x.y, py-1.x.y, pluggy-0.x.y
cachedir: $PYTHON_PREFIX/.pytest_cache
rootdir: $REGENDOC_TMPDIR
collected 2 items
test_unittest_db.py FF [100%]
================================= FAILURES =================================
___________________________ MyTest.test_method1 ____________________________
self = <test_unittest_db.MyTest testMethod=test_method1>
def test_method1(self):
assert hasattr(self, "db")
> assert 0, self.db # fail for demo purposes
E AssertionError: <conftest.db_class.<locals>.DummyDB object at 0xdeadbeef>
E assert 0
test_unittest_db.py:10: AssertionError
___________________________ MyTest.test_method2 ____________________________
self = <test_unittest_db.MyTest testMethod=test_method2>
def test_method2(self):
> assert 0, self.db # fail for demo purposes
E AssertionError: <conftest.db_class.<locals>.DummyDB object at 0xdeadbeef>
E assert 0
test_unittest_db.py:13: AssertionError
========================= short test summary info ==========================
FAILED test_unittest_db.py::MyTest::test_method1 - AssertionError: <conft...
FAILED test_unittest_db.py::MyTest::test_method2 - AssertionError: <conft...
============================ 2 failed in 0.12s =============================
这个默认的pytest回溯显示两个测试方法共享相同的 self.db
在编写上面的类范围fixture函数时,我们打算使用的实例。
使用自动使用设备并访问其他设备¶
尽管在给定的测试中显式地声明所需的fixture的使用通常更好,但有时您可能希望在给定的上下文中自动使用fixture。毕竟,传统风格的UnitTest设置要求使用这种隐式的fixture编写,机会是,你习惯了它或者喜欢它。
可以用标记fixture函数 @pytest.fixture(autouse=True)
并在您想要使用的上下文中定义fixture函数。让我们看看 initdir
使所有试验方法 TestCase
类在临时目录中执行,并预先初始化 samplefile.ini
. 我们的 initdir
fixture本身使用pytest内置 tmpdir 委托创建每个测试临时目录的fixture:
# content of test_unittest_cleandir.py
import pytest
import unittest
class MyTest(unittest.TestCase):
@pytest.fixture(autouse=True)
def initdir(self, tmpdir):
tmpdir.chdir() # change to pytest-provided temporary directory
tmpdir.join("samplefile.ini").write("# testdata")
def test_method(self):
with open("samplefile.ini") as f:
s = f.read()
assert "testdata" in s
由于 autouse
国旗 initdir
fixture函数将用于定义它的类的所有方法。这是使用 @pytest.mark.usefixtures("initdir")
类上的标记,如前一个示例中所示。
运行此测试模块…:
$ pytest -q test_unittest_cleandir.py
. [100%]
1 passed in 0.12s
…给了我们一次通过测试,因为 initdir
fixture函数在 test_method
.
注解
unittest.TestCase
方法不能直接接收fixture参数,因为实现可能会影响运行常规unittest.testcase测试套件的能力。
以上 usefixtures
和 autouse
示例应该有助于将Pytest夹具混合到UnitTest套件中。
您也可以逐渐远离子类化 unittest.TestCase
到 简单断言 然后开始逐步受益于完整的pytest特性集。
注解
由于两个框架之间的体系结构差异,为 unittest
-基础测试在 call
测试阶段而不是 pytest
标准 setup
和 teardown
阶段。在某些情况下,理解这一点很重要,尤其是在推理错误时。例如,如果 unittest
-基于套件在设置期间显示错误, pytest
将在其 setup
并将在 call
.