TDD实践:区分真正的失败和未实现的功能

时间:2011-11-05 01:28:51

标签: python tdd

如果您正处于TDD迭代的中间,您如何知道哪些测试失败,因为现有代码确实不正确,哪些失败,因为测试本身或功能尚未实现?请不要说,“你只是不在乎,因为你必须解决这两个问题。”我已经准备好超越这种心态了。

我编写测试的一般做法如下:

  • 首先,我全部或部分地构建测试套件的一般结构。那就是 - 我只会编写测试名称,提醒我我打算实现的功能。我通常(至少在python中)只是从每个测试只有一行开始:self.fail()。通过这种方式,我可以通过列出我认为我想要测试的每个功能来吸引意识流 - 例如,一次进行11次测试。

  • 其次,我选择一个测试并实际编写测试逻辑。

  • 第三,我运行测试运行器并看到11个故障--10个简单地是self.fail()和1个是真正的AssertionError。

  • 第四,我编写了导致我的测试通过的代码。

  • 第五,我运行测试运行器并看到1次传递和10次失败。

  • 第六,我转到第2步。

理想情况下,我不想在通过,失败和异常方面看到测试,而是希望有第四种可能性:NotImplemented。

这里的最佳做法是什么?

4 个答案:

答案 0 :(得分:4)

许多TDD工具都有PENDING测试和FAILING测试的想法。我认为unittest2也有这种区别。

(我认为你这样做是写:

def test_this_thing(self):
  pass

......但这是来自记忆......

[编辑:在2.7的unittest或unittest2中,您可以使用@skip@unittest.expectedFailure装饰器标记测试。 See the documentation on this

答案 1 :(得分:2)

我用一张纸来创建一个测试列表(用于跟踪测试的暂存器,以便我不会错过它们)。我希望你不是一次性编写所有失败的测试(因为每次Red-Green-Refactor循环都会产生新的知识,这会导致一些颠簸)。

要将测试标记为TO-DO或未实现,您还可以使用等效的[Ignore("PENDING")][Ignore("TODO")]标记测试。例如,NUnit会将此类测试视为黄色而非失败。所以Red意味着测试失败,Yellow意味着TODO。

答案 2 :(得分:1)

大多数项目都有层次结构(例如project-> package-> module->类),如果您可以选择性地为任何级别的任何项目运行测试,或者如果您的报告详细介绍了这些部分,可以很清楚地看到状态。大多数情况下,当整个软件包或类失败时,这是因为它尚未实现。

此外,在许多测试框架中,您可以通过从执行测试的方法/函数中删除注释/修饰或重命名来禁用单个测试用例。这样做的缺点是没有向您显示实现进度,但如果您决定使用固定的特定前缀,则可以很容易地从测试源树中获取该信息。

话虽如此,我欢迎一个测试框架确实做出这种区分,并且除了更标准的测试用例状态代码(如PASS,WARNING和FAILED)之外还有NOT_IMPLEMENTED。我想有些人可能有它。

答案 3 :(得分:0)

我现在也意识到unittest.expectedFailure装饰器完成了与我的需求一致的功能。我一直认为这个装饰器更适用于需要某些环境条件的测试,这些环境条件可能在运行测试的生产环境中不存在,但在这种情况下它实际上也是有意义的。