【问题标题】:unittest Vs pytestunittest 与 pytest
【发布时间】:2015-03-13 07:56:28
【问题描述】:

在单元测试中,我可以在一个类中设置变量,然后这个类的方法可以选择它想要使用的任何变量...

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 中定义了许多不同的夹具,并将它们用作 test_this.py 中五个不同函数中的函数参数听起来很痛苦,我宁愿回到 unittest 类结构,定义我的变量并选择我想要的

  2. 我是否应该在 test_this.py 中声明全局变量并按照我想要的方式在函数中使用它们?似乎有点不像pythonic。此变量仅供此文件中的函数使用。

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

  4. 我的印象是 pytest 不鼓励使用类来组织你的函数吗?我在网上阅读的每个示例,似乎都只使用了一些带有固定装置的功能。 pytest中定义类和方法以及组织测试的配置是什么?

  5. 我有一个测试场景,我必须将一个函数的结果用于另一个函数。使用 pytest,我有一个断言位于函数末尾而不是返回,因此我将无法将此函数用作固定装置。我该如何做到这一点?我知道我的一个测试依赖于另一个测试不是一个好习惯,但有解决方法吗?

提前感谢您的回答。

【问题讨论】:

标签: python pytest unit-testing


【解决方案1】:

1) 首先,您不仅可以在 conftest.py 中声明这些固定装置,还可以在您想要的每个 Python 模块中声明这些装置。您可以导入该模块。 您也可以像使用 setUp 方法一样使用固定装置:

@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

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

@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 迁移到 py.test 有很大帮助。不过有一条评论:我认为应该使用 @pytest.usefixtures 而不是 @pytest.mark.usefixtures
【解决方案2】:

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

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

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

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

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

玩得开心!

【讨论】:

  • “一个重要的原因是 unittest 将保持免费。但是,如果您出于某种原因(bitbucket 等)想使用 pytest,则有一些工具可以转换您的测试并降低代码的可读性。 "我不确定你的意思是什么,你是在暗示 pytest 不会是免费的吗?另外,这里的“免费”是什么意思?最后一段让我很困惑
  • 我对 unittest 的唯一抱怨是他们使用自定义语法操作,例如 self.assertEqual(some_var, 5),而不是在 pytest 中使用干净的 assert some_var == 5
  • “但是,如果你出于某种原因想使用 pytest(bitbucket 等)” pytest 与 bitbucket 的集成是否比 unittest 更好?
  • 最后一句“让代码不那么可读”有损这里的其他一些优点。标准库的一部分始终是使用包的好理由,并且单元测试可以在没有大量样板的情况下完成,但“可读性”是非常主观的。
  • unittest 之上的机器人框架将使您的测试更具可读性和更易于扩展。当 Gherkin 语言使用正确时,您会对测试质量感到惊讶。如需了解有关此免费技术的更多详细信息,请访问:robotframework.org 当然,我将它与 Bitbucket、Jira、Git 和 Jenkins 一起使用,没有任何限制。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-31
  • 1970-01-01
  • 2022-06-14
  • 2021-02-22
  • 2018-11-08
  • 2020-09-04
相关资源
最近更新 更多