单元测试对抗 Pytest

2024-09-29 21:22:58 发布

您现在位置:Python中文网/ 问答频道 /正文

在unittest中,我可以在一个类中设置变量,然后这个类的方法可以选择它想要使用的变量。。。

class test_class(unittest.TestCase):
    def setUp(self):        
        self.varA = 1
        self.varB = 2
        self.varC = 3
        self.modified_varA = 2

    def test_1(self):
        do_something_with_self.varA, self.varB

    def test_2(self):
        do_something_with_self_modified_varA, self.varC

所以在unittest中,很容易将一堆测试放在一起,这些测试可以放在一个类下,然后为不同的方法使用许多不同的变量(varA和varB)。在pytest中,我在conftest.py中创建了一个fixture,而不是unittest中的一个类,如下所示。。。

@pytest.fixture(scope="module")
def input1():
    varA = 1
    varB = 2
    return varA, varB

@pytest.fixture(scope="module")
def input2():
    varA = 2
    varC = 3
    return varA, varC

对于两个不同的函数,我将这个input1和input2输入到另一个文件(假设test_this.py)中的函数中。以下是根据上述信息提出的问题。。。

  1. 因为我不能在conftest.py中声明局部变量,因为我不能简单地导入这个文件。这里是否有更好的方法来声明可以在test_this.py的不同函数中使用的不同变量?在对这些变量的实际测试中,我有五种不同的配置,在conftest.py中定义了许多不同的fixture,并将它们用作test中五种不同函数的函数参数this.py听起来很痛苦,我宁愿回到unittest类结构,定义我的变量并选择我想要的

  2. 我应该在test_this.py中声明全局变量,然后按照我想要的方式在函数中使用它们吗?似乎有点不像Python。此变量仅由此文件中的函数使用。

  3. 假设我有一个测试,也有一个测试。如果我在这些不同的文件之间有一些共享变量,我将如何声明它们?只需在所有这些测试文件所在的目录中创建一个calle variables.py文件,并在需要时进行导入?这样我就可以把所有的数据分开保存了。

  4. 我的印象是pytest不鼓励使用类来组织您的函数吗?我在网上读到的每一个例子,似乎都只使用固定装置的一堆函数。在pytest中定义类和方法并组织测试的配置是什么?

  5. 我有一个测试场景,我必须将一个函数的结果用于另一个函数。对于pytest,我有一个断言,它位于函数的末尾,而不是返回,因此我不能将此函数用作fixture。我该怎么做?我知道这不是一个好的做法,我的一个测试依赖于另一个,但有没有工作?

提前谢谢你的回答。


Tags: 文件方法函数pytestself声明pytest
2条回答

1)首先,您不仅可以在conftest.py中声明这些fixture,还可以在您想要的每个Python模块中声明这些fixture。你可以导入那个模块。 也可以使用与使用设置方法相同的装置:

@pytest.fixture(scope='class')
def input(request):
    request.cls.varA = 1
    request.cls.varB = 2
    request.cls.varC = 3
    request.cls.modified_varA = 2

@pytest.usefixtures('input')
class TestClass:
    def test_1(self):
        do_something_with_self.varA, self.varB

    def test_2(self):
        do_something_with_self_modified_varA, self.varC

或者可以在单独的装置中定义单独的变量:

def fixture_a():
    return varA

def fixture_b():
    return varB

def fixture_c():
    return varC

def fixture_mod_A():
    return modified_varA

或者制作一个返回所有变量的fixture(为什么不?) 或者甚至制作间接参数化的fixture,根据您的选择返回变量(相当混乱的方式):

@pytest.fixture()
def parametrized_input(request):
   vars = {'varA': 1, 'varB': 2, 'varC': 3}
   var_names = request.param
   return (vars[var_name] for var_name in var_names)

@pytest.mark.parametrize('parametrized_input', [('varA', 'varC')], indirect=True)
def test_1(parametrized_input)
   varA, varC = parametrized_input
   ...

或者你甚至可以做夹具工厂,这将为你的夹具飞行。当你只有5个测试和5个变量配置时,听起来很奇怪,但是当你同时得到数百个测试和配置时,它可能会很有用。

3)当然可以。但我建议您不要直接导入此文件,而是使用命令行选项来指向要导入的文件。在这种情况下,您可以选择另一个带有变量的文件,而无需更改代码。

4)我在测试中使用类,因为我是从nosetest迁移过来的。我没有提到在pytest中使用类有任何问题。

5)在这种情况下,我建议您执行以下操作: 首先用所需的动作来完成功能:

def some_actions(a, b):
    # some actions here
    ...
    return c

然后在测试和夹具中使用:

def test():
    assert some_actions(1,2) == 10

@pytest.fixture()
def some_fixture():
     return some_actions(1,2)

我认为unittest更容易阅读。对于新的测试人员来说,unittest非常简单。它是开箱即用的。您依赖于Python实现,但它们在未来几年不会更改接口。

我喜欢以这样的方式组织我的测试:每个文件最多有一个测试。那样的话我就不用上课了。。。但是我从每个测试中导入类来做一些事情。

一些网站抱怨unittest中的颜色是不可能的。我认为这是个笑话,因为我的unittests为Jenkins和其他人创建了JUNIT输出报告。有很多很好的工具(甚至有一个文件)可以将JUNIT转换成一个网站,这不是测试工具的职责。

另外,有些人抱怨你需要很多代码来启动unittest。我不同意,创建unittest需要4行代码!但是Pytest需要知道所有困难的注释,这对于一个简单的Python开发人员来说是不正常的。

一个重要的原因也是unittest将保持自由。但是,如果您出于某种原因想使用pytest(bitbucket等),则有一些工具可以转换您的测试并降低代码的可读性。

玩得开心!

相关问题 更多 >

    热门问题