命名测试类与BDD风格“何时”及其维护后果

时间:2014-01-28 07:31:12

标签: unit-testing junit tdd naming-conventions bdd

根据我的理解,真正的BDD更多的是关于满足业务规范,但我认为从类似行为开始可能是值得的,因为我正在努力采用TDD和BDD命名使其更容易。

让我们专注于BDD风格的单元测试(在课堂级别)。

我开始以一种反映预期行为的方式命名我的测试类,使用“When”作为建议in this article。这真的很有效。然而很快,我意识到这样的测试类名称可能会产生以下维护后果。

为手头的课程找到测试课程并不容易。

我已经习惯了传统的命名“ClassnameTest”,在这种情况下,我可以快速找到测试类。

我使用 Java和JUnit4 ,遗憾的是我没有像给定的内置语言结构等。

让我们考虑以下示例。

public class Lion{...}

测试类

public class WhenLionIsHungy{
    @Test public void should_eat_meat(){...}
    @Test public void should_not_eat_grass(){...}
    @Test ...
}

public class WhenLionHunts{...}

public class WhenLionIsWithCubs{...}
...

请原谅我的例子。假设它们都是有效的测试类。除非您确定我们不应该为目标类提供多个基于行为的测试类,否则不要担心它。

BDD是将测试转化为文档的优雅解决方案,上面的示例反映了这一点。测试像“testMoneyTransfer()”这样的方法毕竟不会提供任何见解。

以上是一个很好的例子,但猜测名为“LibraryServiceImpl”的类的测试类是一场噩梦。

是BookIsRequested还是WhenLibraryIsClosed或两者兼有?

单元测试应作为完整或某种程度的文档。但是在LibraryServiceImpl-case中,文档本身不容易被发现。

即使您正确地命名了一个类并使用SRP设计它,仍然更难找到测试类,因为搜索引用也可能会在测试文件夹中返回100个命中。


我第一次尝试使用@Suite来解决问题。

@RunWith(Suite.class)
@Suite.SuiteClasses({WhenLionIsHungy.class,
                     WhenLionHunts.class,
                     WhenLionIsWithCubs.class
})
public class LionTest{}

它解决了什么?

  1. 当我在目标类名之后命名它时,很容易找到手头上的测试类。
  2. 单个班级在一个地方的所有类型的高级行为。就个人而言,我发现更具洞察力。
  3. 它介绍了什么?

    1. 没有目的的空类,但是对“When”类进行分组。我不完全确定这是否是一个更大的问题,但拥有它们确实感觉很奇怪。

    2. 我第二次尝试使用内部类来解决问题。 Reference

      @RunWith(Enclosed.class)
      public class LionTest{
      
           public static class WhenLionIsHungy{...}
      
           public static class WhenLionHunts{...}
      
           ...
      
      }
      

      它解决了什么?

      1. 当我在目标类名后命名它时,很容易找到一个类的测试类。
      2. 不再有空课。
      3. 有点容易弄清楚班级的要点。 (IDE可以提供大纲)
      4. 它介绍了什么?

        1. 可笑的冗长课程。然而,没有办法将它们全部放在一个地方而又紧凑而且紧凑。同样可读。
        2. 使用静态内部测试类?听起来不错吗?
        3. 我希望我不必完全回到目标类之后命名测试类,而是“轻松找到手头上的类的测试类”。似乎是一个不容忽视的重大问题。

          请单独提供您对上述解决方案的意见。

          如果你想出别的东西,那就好了。

1 个答案:

答案 0 :(得分:2)

“我使用Java和JUnit4,遗憾的是我没有像给定的内置语言结构”

如果你在JVM上你可以使用groovy / spock,它很容易在java项目和IMMO中集成spock,差别值得努力。试一试!。

我不认为找到具体生产类的测试类是你真正需要的。 BDD的一个优点是,您可以使用您正在开发的功能组织测试,实现此功能的类是实现细节。通常,当您正在寻找某些测试时,您真的很期待,因为您想验证/检查/修复应用程序中的某些功能。

实际上问题是它找不到LibraryServiceImpl的测试,这里的问题是有一个这个坏名字的类。 “图书馆”这个名称中唯一的信息“ServiceImpl”就是噪音。此时问题可以改为“找到库函数的测试”,稍微好一点,但是如果你在应用程序中有很多与库相关的功能,那么这个类可以在具有有意义名称的类中分离,比如LibraryBooksReturnPolicy或LibraryNewBooksRegister (只有样品,可能是不好的样品,但你可以得到这个想法)。

BDD / TDD它不仅是一种测试技术,它是一种驱动你的设计的技术,为你的类找到合适的名称,如果在一个好的设计中最重要的事情之一,你就不能为查找语义而做出很多努力。为您的测试代码命名的好方法(无论如何都是很好的努力),并在您的生产代码上添加名称如“service”,“manager”或“impl”的名称!。

无论如何,如果您不同意所有这些并且仍然希望找到给定类的测试,您可以使用您的IDE并在测试文件夹中找到类用法,并且您有一个测试的列表class milliseconds和可导航链接。