我正在使用pytest来测试我的应用。 pytest支持2种方法(我知道)如何编写测试:
test_feature.py - > class TestFeature - > def test_feature_sanity
test_feature.py - > def test_feature_sanity
是否需要在课堂上分组测试的方法?是否允许backport unittest内置模块? 你会说哪种方法更好,为什么?
提前致谢!
答案 0 :(得分:13)
没有关于将测试组织到模块和类中的严格规则。这是个人喜好的问题。最初我尝试将测试组织成课程,经过一段时间后,我意识到我没有用于其他级别的组织。现在我只是将测试功能收集到模块(文件)中。
当一些测试可以逻辑地组织到同一个文件中时,我可以看到一个有效的用例,但是仍然有更多的组织级别(例如,使用类范围的fixture)。但这也可以分成多个模块来完成。
答案 1 :(得分:4)
通常在单元测试中,我们的测试对象是单个功能。也就是说,单个功能会引发多个测试。在通读测试代码时,将某个单元的测试以某种方式组合在一起很有用(这也使我们能够例如针对特定功能运行所有测试),因此这给我们留下了两个选择:
在第一种方法中,我们仍然会对以某种方式对与源模块(例如utils.py
)相关的所有测试进行分组感兴趣。现在,由于我们已经在使用模块对功能的测试进行分组,这意味着我们应该使用 package 对源模块的测试进行分组。
结果是一个源功能映射到一个测试 模块,一个源 module 映射到一个测试软件包。
在第二种方法中,我们将一个源函数映射到一个测试类(例如my_function()
-> TestMyFunction
),将一个源模块映射到一个测试模块(例如{{1 }}-> utils.py
)。
也许这取决于情况,但是第二种方法,即对要测试的每个功能进行一类测试,对我来说似乎更清楚。此外,如果我们正在测试源类 /方法,那么我们可以简单地使用测试类的继承层次结构,而仍然保留一个源模块->一个测试模块映射。
最后,对于仅使用一个包含多个功能测试的平面文件的方法,这两种方法的另一个好处是,在类/模块已经确定要测试哪个功能的情况下,可以为实际测试使用更好的名称,例如test_utils.py
和test_does_x
,而不是test_handles_y
和test_my_function_does_x
。
答案 2 :(得分:4)
pytest中TestClass的一个引人注目的用例是子类对类属性的继承。我将使用摘自another answer的代码的修改版本来演示:
# in file `test_example.py`
class TestBase:
VAR = 3
DATA = 4
def test_var_positive(self):
assert self.VAR >= 0
class TestSub(TestBase):
VAR = 8
def test_var_even(self):
assert self.VAR % 2 == 0
def test_data(self):
assert self.DATA == 4
在此文件上运行pytest
导致运行四个测试:
$ pytest -v test_example.py
=========== test session starts ===========
platform linux -- Python 3.8.2, pytest-5.4.2, py-1.8.1
collected 4 items
test_example.py::TestBase::test_var_positive PASSED
test_example.py::TestSub::test_var_positive PASSED
test_example.py::TestSub::test_var_even PASSED
test_example.py::TestSub::test_data PASSED
在子类中,使用更新后的值test_var_positive
运行继承的self.VAR == 8
方法,并针对继承的属性test_data
运行新定义的self.DATA == 4
方法。这种方法和属性继承提供了灵活的方式来重用或修改不同测试用例组之间的共享功能。
答案 3 :(得分:0)
在 JavaScript jasmine 中,测试由 describe 和 it 方法构成: What is the difference between describe and it in Jest?
这是该概念的 Python 实现:
https://pypi.org/project/pytest-describe/
缺点可能是对 IDE 的支持滞后。 我想为了找到测试方法,他们的名字必须 以“test_”而不是“it_”开头
def describe_list():
@pytest.fixture
def list():
return []
def describe_append():
def adds_to_end_of_list(list):
list.append('foo')
list.append('bar')
assert list == ['foo', 'bar']
def describe_remove():
@pytest.fixture
def list():
return ['foo', 'bar']
def removes_item_from_list(list):
list.remove('foo')
assert list == ['bar']