在pytest的文档中,列出了测试用例的各种示例。 其中大多数显示了功能测试。 但是我缺少一个有关如何测试类和类方法的示例。 假设我们要测试的模块cool.py中具有以下类:
class SuperCool(object):
def action(self, x):
return x * x
tests/test_cool.py中的相应测试类应如何显示?
class TestSuperCool():
def test_action(self, x):
pass
test_action()如何用于测试action()?
测试类方法所需要做的就是实例化该类,然后在该实例上调用该方法:
def test_action(self):
sc = SuperCool()
assert sc.action(1) == 1
那么,pytest中不涉及任何映射吗?
@laserbrain我不确定在这种情况下映射的含义,但是如果您尝试的话,我的示例应该适用。
我的意思是方法test_action()映射到action()上,因此不需要实例化(例如自动魔术)。
@laserbrain,以及这个自动魔术师如何找出您要执行哪种断言和检查?显式胜于隐式。
@laserbrain我仍然没有真正遵循,但是afaik在大多数情况下pytest会将类方法与普通顶级函数相同
@elethan我有一个类似于class TestSuperCool的类,但是该类具有类似于def test_action)的多个功能。当我直接运行pytest test_module.py::TestSuperCool::test_action时,它可以正常运行,并且我的测试通过了。但是,当我运行pytest test_module.py::TestSuperCool时,它会失败。您知道如何在pytest中而不是每个测试函数中测试单个测试类吗?
实际上没有后顾之忧..我的ipython或Windows10上的ipython似乎有问题。似乎即使我执行%reset -s之后,它也不会重置或清除ipython中的名称空间。当我在ipython中运行它时,这种情况反复发生。重新启动ipython后,问题消失了。
好吧,一种方法是只在测试方法中创建对象并从那里与之交互:
def test_action(self, x):
o = SuperCool()
assert o.action(2) == 4
您显然可以使用以下方法使用经典的setup和teardown样式单元测试之类的东西:http://doc.pytest.org/en/latest/xunit_setup.html
我不确定如何使用它们,因为pytest的文档太糟糕了。
编辑:是的,如果您做类似的事情,那么显然
class TestSuperCool():
def setup(self):
self.sc = SuperCool()
...
# test using self.sc down here
我只会使用任何固定装置来创建测试环境(例如数据库连接)或数据参数化。
如果您的数据比较琐碎,可以在测试用例中定义它:
def test_action_without_fixtures():
sc = SuperCool()
sc.element = 'snow'
sc.melt()
assert sc.element == 'water'
参数化示例:
@pytest.mark.parametrize("element, expected", [('snow', 'water'), ('tin', 'solder')])
def test_action_with_parametrization(element, expected):
sc = SuperCool()
sc.element = element
sc.melt()
assert sc.element == expected
如果类的初始化很昂贵,但是您需要在类方法上运行大量参数化测试,则可以更改方法定义以允许外部输入。然后,您可以在测试循环外进行一次初始化,并根据需要在方法上运行任意数量的测试。例如:
代替这个:
class SuperCool():
def action(self):
return self.attribute ** 2
重写以允许外部输入:
class SuperCool():
def action(self, x=None):
if x is None:
x = self.attribute
return x ** 2
现在,您的测试脚本如下所示:
sc = SuperCool()
@pytest.mark.parametrize("x, y", [(1, 1), (2, 4)])
def test_action_with_parametrization(x, y):
assert sc.action(x) == y
但是我不是一个经验丰富的程序员,所以希望这不是某种反模式的XD