如何用nosetests对Python测试案例进行分解

5 投票
1 回答
1619 浏览
提问于 2025-04-16 12:14

我有几个函数,分别是 f()、g() 和 h(),它们实现了同一个问题的不同算法。我想用 unittest 框架来对这些函数进行单元测试。

对于每个算法,有几个条件是必须始终满足的(比如空图、只有一个节点的图等等)。这些共同的条件检查代码不应该重复写。所以,我开始设计的测试架构是这样的:

class AbstractTest(TestCase):
  def test_empty(self):
      result = self.function(make_empty_graph())
      assertTrue(result....) # etc..
  def test_single_node(self):
      ...

然后是具体的测试案例

class TestF(AbstractTest):
  def setup(self):
      self.function = f
  def test_random(self):
      #specific test for algorithm 'f'

class TestG(AbstractTest):
  def setup(self):
      self.function = g
  def test_complete_graph(self):
      #specific test for algorithm 'g'

... 对每个算法都这样做

不幸的是,nosetests 尝试在 AbstractTest 中执行每个测试,但这不行,因为实际的 self.function 是在子类中指定的。我试着在 AbstractTest Case 中设置 __test__ = False,但这样的话根本没有测试被执行(我想这是因为这个字段是继承的)。我也尝试过用抽象基类(abc.ABCMeta),但没有成功。我还读过关于 MixIn 的内容,但也没有什么结果(我对这个不是很有信心)。

我相信我不是唯一一个想要简化测试代码的人。你们是怎么在 Python 中做到这一点的?

谢谢。

1 个回答

2

Nose是一个工具,它会收集那些符合特定规则(比如匹配某种模式)或者是unittest.TestCase这个类的子类的测试类。所以,最简单的解决办法就是既不匹配这些规则,也不使用这些子类:

class AlgoMixin(object):
  # Does not end in "Test"; not a subclass of unittest.TestCase.
  # You may prefer "AbstractBase" or something else.

  def test_empty(self):
    result = self.function(make_empty_graph())
    self.assertTrue(result)

class TestF(AlgoMixin, unittest.TestCase):
  function = staticmethod(f)
  # Doesn't need to be in setup, nor be an instance attribute.
  # But doesn't take either self or class parameter, so use staticmethod.

  def test_random(self):
    pass  # Specific test for algorithm 'f'.

撰写回答