【问题标题】:When to stop when trying to write meaningful tests using TDD?尝试使用 TDD 编写有意义的测试时何时停止?
【发布时间】:2019-01-31 10:41:50
【问题描述】:

我正在努力寻找何时停止使用 TDD 编写测试用例。

假设一个必须写一个只接受部分字符串的方法,它只能接受字符串['red', 'green', 'blue'],它是必需的,不能为空。

我编写第一个失败的测试,将其设为绿色,依此类推,直到我有测试用例:

it('should accept red input', () => { /*...*/ }
it('should accept green input', () => { /*...*/ }
it('should accept blue input', () => { /*...*/ }
it('should not accept null input', () => { /*...*/ }
it('should not accept empty input', () => { /*...*/ }

此时一切都在过去,现在我应该结束一天的工作还是应该去添加一个测试,如果它对Purple 失败了?添加这个测试有意义吗? 如果是的话,我还可以举出其他 10 种颜色来测试,是不是也要考虑一下?

这个例子很简单,但是我知道正则表达式有无限组合的情况,这可能是一个问题,我无法添加我能想到的所有测试用例,因为时间限制。这些是最糟糕的,因为我不知道什么时候停止编写测试代码,并找到什么时候足够了。

我知道我无法为此获得具体的答案,但我想从经验中了解大多数情况下什么是有效的。

【问题讨论】:

    标签: javascript mocha.js tdd chai


    【解决方案1】:

    通常您希望测试输入类而不是特定输入,除非您已经知道特定输入会产生您需要通过测试涵盖的特定情况。

    在您的示例中,我将其分解为四个测试:

    1. 应接受预期输入空间中的颜色,例如“红色”
    2. 不应接受不在预期输入空间中的颜色,例如'紫色'
    3. 不应接受空输入
    4. 不应接受空输入

    您是对的,解析输入空间是巨大的,并且涵盖的案例比您实际测试的要多。在这种情况下,我会选择一些常见情况(空/空输入、明显预期和意外的输入等),并尝试考虑输入可能被错误分类为(未)预期的特定场景。 也许有两种颜色“红色”和“红色”,您想测试该功能是否涵盖两者或一种,而不是另一种。在这种情况下,具体的颜色并不重要,只是其中一种包含另一种。

    【讨论】:

      【解决方案2】:

      这里发布了一个很好的答案: Is there such a thing as excessive unit testing?

      简而言之,您会考虑失败的可能性,并权衡它与编写自动化测试用例的成本。

      在您的情况下,您可以测试另一种颜色,看看它是否正确拒绝它。但是针对所有情况进行测试是不必要且不可能的。

      如果您开始在某个值上收到重复错误,您可能希望将其添加到测试中。否则边界检查会做(空或无,正确的行为,一次失败)

      【讨论】:

        【解决方案3】:

        此时一切都在过去,现在我应该结束一天的工作还是应该去添加一个测试,如果它对 Purple 失败了?添加这个测试有意义吗?如果是的话,我还可以举出其他 10 种颜色来测试,是不是也要考虑一下?

        在不枚举整个世界的情况下改进您对测试对象的评估的一种方法是基于属性的测试。 Scott Wlaschin 写了一个good introduction to the technique

        Kent Beck 以呼吁注意测试和实施之间的数据重复而闻名,J. B. Rainsberger 建议,作为“删除重复”工作的一部分,数据往往会移向测试。那是什么意思呢?

        在您的情况下,听起来您可以将测试对象分成两部分——一部分看起来像颜色名称的数据库(地图、查找表),另一部分是一些逻辑,可以做一些有趣的事情颜色名称数据库。

        对于后一部分,您最终会得到类似“给定一个 [red, green, blue] 的数据库,当输入为紫色时,测试对象是否采用 thats-not-a-color 路径;给定一个数据库[red,green,blue,purple],当输入为紫色时,测试对象是否走那条颜色路径?

        这让您不必担心数据库。您需要注意的是,简单地测试您在两个不同的地方输入了相同的数据并不是特别有价值。

        你也可以考虑Beck的这个观察

        我是通过有效的代码而不是测试获得报酬,所以我的理念是尽可能少地测试以达到给定的信心水平

        请记住,投入在测试上的时间是没有投入到其他地方的时间。有时,正确的做法是发布,然后在您了解了有关它应该如何工作的新知识后再返回代码。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-08-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多