根据我的理解,真正的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{}
它解决了什么?
它介绍了什么?
我第二次尝试使用内部类来解决问题。 Reference
@RunWith(Enclosed.class)
public class LionTest{
public static class WhenLionIsHungy{...}
public static class WhenLionHunts{...}
...
}
它解决了什么?
它介绍了什么?
我希望我不必完全回到目标类之后命名测试类,而是“轻松找到手头上的类的测试类”。似乎是一个不容忽视的重大问题。
请单独提供您对上述解决方案的意见。
如果你想出别的东西,那就好了。
答案 0 :(得分:2)
“我使用Java和JUnit4,遗憾的是我没有像给定的内置语言结构”
如果你在JVM上你可以使用groovy / spock,它很容易在java项目和IMMO中集成spock,差别值得努力。试一试!。
我不认为找到具体生产类的测试类是你真正需要的。 BDD的一个优点是,您可以使用您正在开发的功能组织测试,实现此功能的类是实现细节。通常,当您正在寻找某些测试时,您真的很期待,因为您想验证/检查/修复应用程序中的某些功能。
实际上问题是它找不到LibraryServiceImpl的测试,这里的问题是有一个这个坏名字的类。 “图书馆”这个名称中唯一的信息“ServiceImpl”就是噪音。此时问题可以改为“找到库函数的测试”,稍微好一点,但是如果你在应用程序中有很多与库相关的功能,那么这个类可以在具有有意义名称的类中分离,比如LibraryBooksReturnPolicy或LibraryNewBooksRegister (只有样品,可能是不好的样品,但你可以得到这个想法)。
BDD / TDD它不仅是一种测试技术,它是一种驱动你的设计的技术,为你的类找到合适的名称,如果在一个好的设计中最重要的事情之一,你就不能为查找语义而做出很多努力。为您的测试代码命名的好方法(无论如何都是很好的努力),并在您的生产代码上添加名称如“service”,“manager”或“impl”的名称!。
无论如何,如果您不同意所有这些并且仍然希望找到给定类的测试,您可以使用您的IDE并在测试文件夹中找到类用法,并且您有一个测试的列表class milliseconds和可导航链接。