如果您正处于TDD迭代的中间,您如何知道哪些测试失败,因为现有代码确实不正确,哪些失败,因为测试本身或功能尚未实现?请不要说,“你只是不在乎,因为你必须解决这两个问题。”我已经准备好超越这种心态了。
我编写测试的一般做法如下:
首先,我全部或部分地构建测试套件的一般结构。那就是 - 我只会编写测试名称,提醒我我打算实现的功能。我通常(至少在python中)只是从每个测试只有一行开始:self.fail()。通过这种方式,我可以通过列出我认为我想要测试的每个功能来吸引意识流 - 例如,一次进行11次测试。
其次,我选择一个测试并实际编写测试逻辑。
第三,我运行测试运行器并看到11个故障--10个简单地是self.fail()和1个是真正的AssertionError。
第四,我编写了导致我的测试通过的代码。
第五,我运行测试运行器并看到1次传递和10次失败。
第六,我转到第2步。
理想情况下,我不想在通过,失败和异常方面看到测试,而是希望有第四种可能性:NotImplemented。
这里的最佳做法是什么?
答案 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装饰器完成了与我的需求一致的功能。我一直认为这个装饰器更适用于需要某些环境条件的测试,这些环境条件可能在运行测试的生产环境中不存在,但在这种情况下它实际上也是有意义的。