Python 使用 pytest 测试类方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39395731/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 22:12:31  来源:igfitidea点击:

Testing class methods with pytest

pythonpytest

提问by laserbrain

In the documentation of pytest various examples for test cases are listed. Most of them show the test of functions. But I'm missing an example of how to test classes and class methods. Let's say we have the following class in the module cool.pywe like to test:

在 pytest 的文档中列出了各种测试用例示例。他们中的大多数都展示了功能的测试。但是我缺少一个关于如何测试类和类方法的示例。假设cool.py我们要测试的模块中有以下类:

class SuperCool(object):

    def action(self, x):
        return x * x

How does the according test class in tests/test_cool.pyhave to look?

里面的相应测试类tests/test_cool.py要怎么看?

class TestSuperCool():

    def test_action(self, x):
        pass

How can test_action()be used to test action()?

怎么可以test_action()用来测试action()

采纳答案by elethan

All you need to do to test a class method is instantiate that class, and call the method on that instance:

测试类方法所需要做的就是实例化该类,并在该实例上调用该方法:

def test_action(self):
    sc = SuperCool()
    assert sc.action(1) == 1

回答by Tyler Sebastian

Well, one way is to just create your object within the test method and interact with it from there:

嗯,一种方法是在测试方法中创建您的对象并从那里与之交互:

def test_action(self, x):
    o = SuperCool()
    assert o.action(2) == 4

You can apparently use something like the classic setupand teardownstyle unittest using the methods here: http://doc.pytest.org/en/latest/xunit_setup.html

您显然可以使用以下方法使用经典setupteardown样式单元测试之类的东西:http: //doc.pytest.org/en/latest/xunit_setup.html

I'm not 100% sure on how they are used because the documentation for pytest is terrible.

我不是 100% 确定它们是如何使用的,因为 pytest 的文档很糟糕

Edit:yeah so apparently if you do something like

编辑:是的,很明显,如果你做类似的事情

class TestSuperCool():
    def setup(self):
        self.sc = SuperCool()

    ... 

    # test using self.sc down here

回答by Kirill

I would use any fixtures only to create test environment (like database connection) or data parametrization.

我只会使用任何装置来创建测试环境(如数据库连接)或数据参数化。

If your data is relatively trivial, you can define it inside the testcase:

如果你的数据比较琐碎,你可以在测试用例中定义它:

def test_action_without_fixtures():
    sc = SuperCool()
    sc.element = 'snow'
    sc.melt()
    assert sc.element == 'water'

Example with parametrization:

参数化示例:

@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

回答by Trenton

If the class initialization is expensive but you need to run lots of paramaterized tests on a class method, you can change the method definition to allow external inputs. Then you can initialize once outside the test loop and run as many tests as you like on the method. For example:

如果类初始化代价高昂,但您需要对类方法运行大量参数化测试,则可以更改方法定义以允许外部输入。然后,您可以在测试循环外初始化一次,并在该方法上运行任意数量的测试。例如:

Instead of this:

取而代之的是:

class SuperCool():
    def action(self):
        return self.attribute ** 2

Rewrite to allow external input:

重写以允许外部输入:

class SuperCool():
    def action(self, x=None):
        if x is None:
            x = self.attribute
        return x ** 2

Now your test script can look like:

现在你的测试脚本看起来像:

sc = SuperCool()
@pytest.mark.parametrize("x, y", [(1, 1), (2, 4)])
def test_action_with_parametrization(x, y):
    assert sc.action(x) == y

But I'm not an experienced programmer so hopefully this isn't some kind of anti-pattern XD

但我不是一个有经验的程序员,所以希望这不是某种反模式 XD