使用 BDD 风格的“When”命名测试类及其维护结果

pha*_*ani 6 tdd bdd junit unit-testing naming-conventions

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

让我们关注 BDD 风格的单元测试(在类级别)。

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

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

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

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

让我们考虑以下示例。

public class Lion{...}
Run Code Online (Sandbox Code Playgroud)

测试类

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

public class WhenLionHunts{...}

public class WhenLionIsWithCubs{...}
...
Run Code Online (Sandbox Code Playgroud)

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

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

上面是一个快乐的例子,但猜测名为“LibraryServiceImpl”的类的测试类将是一场噩梦。

是 WhenBookIsRequested 或 WhenLibraryIsClosed 还是两者兼而有之?

单元测试应该作为完整或某种程度的文档。然而,在 LibraryServiceImpl 案例中,文档本身并不容易被发现。

即使您正确命名了一个类并使用 SRP 对其进行设计,仍然很难找到测试类,因为搜索引用也可能会在测试文件夹中返回 100 次点击。


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

@RunWith(Suite.class)
@Suite.SuiteClasses({WhenLionIsHungy.class,
                     WhenLionHunts.class,
                     WhenLionIsWithCubs.class
})
public class LionTest{}
Run Code Online (Sandbox Code Playgroud)

它解决什么问题?

  1. 很容易找到手头的类的测试类,因为我以目标类名命名它。
  2. 一个类在一个地方的所有类型的高级行为。就我个人而言,我觉得这更有见地。

它介绍了什么?

  1. 没有目的的空类,只是将“何时”类分组。我不完全确定这是否是一个更大的问题,但拥有它们肯定感觉很奇怪。

我第二次尝试使用内部类解决问题。 参考

@RunWith(Enclosed.class)
public class LionTest{

     public static class WhenLionIsHungy{...}

     public static class WhenLionHunts{...}

     ...

}
Run Code Online (Sandbox Code Playgroud)

它解决什么问题?

  1. 很容易找到手头的类的测试类,因为我以目标类名命名它。
  2. 没有更多的空课。
  3. 有点容易弄清楚课程的要点。(IDE 可以提供大纲)

它介绍了什么?

  1. 冗长可笑的课程。然而,没有办法将所有这些都放在一个地方,同时又紧凑且可读。
  2. 使用静态内部测试类?听起来对吗?

我希望我不必完全回到在目标类之后命名测试类,而是“轻松找到手头类的测试类”。似乎是一个不容忽视的重大问题。

请分别提供您对上述解决方案的意见。

如果你能想出别的东西就太好了。

Alf*_*ado 2

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

如果你使用的是 JVM,你可以使用 groovy/spock,在 java 项目中集成 spock 真的很容易,恕我直言,差异值得付出努力。试一试!。

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

事实上,问题是没有找到 LibraryServiceImpl 的测试,这里的问题是有一个具有这个坏名称的类。“Library”这个名称“ServiceImpl”中唯一的信息是噪音。此时,问题可以更改为“查找库功能的测试”,这样会好一点,但是如果应用程序中有很多与库相关的功能,则该类可能可以分成具有有意义名称的类,例如 LibraryBooksReturnPolicy 或 LibraryNewBooksRegister (只有样本,可能是不好的样本,但你可以明白)。

BDD/TDD 它不仅是一种测试技术,也是一种驱动设计的技术,如果良好设计中最重要的事情之一是为您的类找到合适的名称,那么您不能付出很多努力来寻找语义和伟大的方法来为您的测试代码命名(无论如何,这是一个很好的努力),并在您的生产代码上添加带有“service”、“manager”或“impl”等单词的名称!

无论如何,如果您不同意所有这些,并且仍然想查找给定类的测试,您可以使用 IDE 并在测试文件夹中查找类用法,并且您将获得一个以毫秒为单位执行此类的测试列表,并且具有可导航的链接。