最团结的对抗最卑鄙的

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

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 中,很容易将一组测试放在一个类下,然后为不同的方法使用许多不同的变量(varAvarB)。在 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的不同函数中使用的不同变量?在我对这些变量的实际测试中,我有五种不同的配置,在 conttest.py 中定义了许多不同的 fixture,并在 test _ this. py 的五个不同函数中使用它们作为函数参数,这听起来很痛苦,我宁愿回到 unittest 类结构,定义我的变量并选择我想要的。

  2. 我是否应该在 test_this.py中声明全局变量,然后按照我想要的方式在函数中使用它们?看起来不太像蟒蛇。此变量仅由此文件中的函数使用。

  3. Let's say I have test_that.py and test_them.py as well. If I have some shared variables between these different files, how would I declare them ? just create a file called variables.py in the directory where all these test files are and do an import whenever I need ? This way I can keep all data in a separate.

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

  5. 我有一个测试场景,我必须将一个函数的结果用到另一个函数中。使用 pytest,我有一个位于函数末尾的断言,它不是返回值,所以我不能将这个函数用作 fixture。我该怎么做?我知道这不是一个好的做法,我的一个测试依赖于另一个,但是有一个周围的工作?

166811 次浏览

1)首先,您不仅可以在 configtest.py 中声明这些 fixture,还可以在您想要的每个 Python 模块中声明这些 fixture。你可以导入那个模块。 你也可以像使用 setUp 方法一样使用 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个变量配置时,这听起来很奇怪,但是当您同时拥有数百个测试和5个变量配置时,它就很有用了。

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

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

5)在这种情况下,我建议你做以下事情: 第一步用期望的动作完成功能:

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

then use it both in test and fixture:

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


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

我认为单元测试更容易阅读。对于新的测试人员来说,单元测试真的很容易。这是工作的盒子。您依赖于 Python 实现,但是它们在未来几年内不会改变接口。

我喜欢以这样的方式组织我的测试: 每个文件最多有1个测试。在这种情况下,我不依赖于类... 但我从每个测试导入类来做事情。

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

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

一个重要的原因还在于,unittest 仍将是免费的。但是,如果出于某种原因(bitbucket 等)希望使用 pytest,可以使用一些工具来转换测试并降低代码的可读性。

玩得开心!