使用 python 中的 Unittest 模块编写非单元测试。这是不好的做法吗?

Using the Unittest module in python to write non unit tests. Is it Bad practice?

提问人:doggo 提问时间:10/12/2023 更新时间:10/13/2023 访问量:72

问:

假设我在它自己的模块中设计了一个名为 A 的类。考虑代码可能是什么样子的缩写。

# file: A.py
class A:
  # define some useful behaviour for A class
  pass

然后,我继续为这个新类执行一些单元测试。测试将大致如下图所示进行。

在 TestA 类之外定义 create_test_A 函数的原因将在下面变得显而易见。

# file test_A.py
import A
import unittest

def create_test_A():
  # initialize into a useful test state before returning
  return A.A()

class TestA(unittest.TestCase):
  def test(self):
    new_A = create_test_A()
    # write some clever assertions about behaviour of new_A
    pass

现在假设我构建了一个新类,该类旨在直接处理 A 类的实例化。

class A_bundle:
  def __init__(self):
    # define some fields that work with objects of type <class A>
    pass

当我为这个新类编写单元测试时,我的第一反应是创建它的实例,然后创建一些 A 类型的对象来与它交互。也许它会是这样的。

#file test_A_bundle.py

import test_A # this is the part I feel weird doing
import A_bundle
import unittest

class TestABundle(unittest.TestCase):
  def test_a_bundle(self):
    # create a couple of test objects of type A
    new_A1 = test_A.create_test_A()
    new_A2 = test_A.create_test_A()

    # make a new A_bundle to perform tests on
    new_bundle = A_bundle.A_bundle()

    # make some assertions about the way new_bundle
    # should interact with new_A1 and new_A2

我现在是否已经超出了单元测试的范围,进入了集成测试的世界,因为我不仅仅是独立测试A_bundle类的行为?

如果是这样,似乎我仍然可以以这种方式使用 unittest 模块并运行一些有用的测试。这被认为是一种不好的做法吗?也就是说,使用 unittest 模块来编写和执行实际上不是单元测试的测试?

Python 单元测试 集成测试

评论


答:

2赞 User051209 10/12/2023 #1

在我看来,你仍然处于单元测试的领域,但我有一个建议给你。

提示

插入类的实例作为类的方法的参数。A__init__()bundle_A

按照这个提示,我修改了你的文件,如下所示:A_bundle.py

class A_bundle:
    def __init__(self, a1, a2):
        self.a1 = a1
        self.a2 = a2

    # define some fields that work with objects of type <class A>
    def sum(self):
        return self.a1.m_a() + self.a2.m_a()

我还在类中定义了方法:这是一个使用类 A 类型对象的字段示例。sum()A_bundle

对 A 类的变化

在文件中,我定义了属性和方法,如下所示:A.pyx=10m_a()

# file: A.py
class A:
    x = 10
    def m_a(self):
        return self.x

中的测试方法test_A_bundle.py

最后,我向您推荐一个包含 2 种方法的文件:test_A_bundle.py

  • 您的方法创建 2 个 class 的真实实例,一个 class 的实例并验证该方法的结果test_a_bundle()AA_bundlesum()
  • 调用第二个测试方法,它替换 by 2 Mock 对象的真实实例,并确定该 2 Mock 对象的方法的返回值test_a_bundle_with_mock()Am_a()

的代码如下:test_A_bundle.py

#file test_A_bundle.py

import test_A # this is the part I feel weird doing
import A_bundle
import unittest
from unittest import mock
import A

class TestABundle(unittest.TestCase):

    #+++++ YOUR TEST METHOD +++++
    def test_a_bundle(self):
        # create a couple of test objects of type A
        new_A1 = test_A.create_test_A()
        new_A2 = test_A.create_test_A()

        # make a new A_bundle to perform tests on (passes 2 instances of 
        # A to the __init__ method of A_bundle)
        new_bundle = A_bundle.A_bundle(new_A1, new_A2)
        self.assertEqual(20, new_bundle.sum())

    def test_a_bundle_with_mock(self):
        mock_a1 = mock.Mock()
        mock_a2 = mock.Mock()
        mock_a1.m_a.return_value = 20
        mock_a2.m_a.return_value = 30

        new_bundle = A_bundle.A_bundle(mock_a1, mock_a2)
        self.assertEqual(50, new_bundle.sum())

if __name__ == '__main__':
    unittest.main()

第二种方法演示如何通过单元测试来测试类对象和类对象之间的交互。在我看来,这个测试不是一个集成测试,它仍然是一个单元测试,测试类之间的合作。AA_bundle

评论

1赞 doggo 10/17/2023
非常感谢您的精彩回答,很抱歉我花了这么长时间才回复。