命名单元测试和集成测试方法的最佳实践是什么?

18

最近我接手了一款由不同的人在不同时期编写的应用程序,现在我正在寻求如何进行标准化的指导。

8个回答

10
假设使用NUnit测试框架:
[Test]
public void ObjectUnderTest_StateChanged_Consequence()
{
    Assert.That(tra_la_la);
}

[Test]
public void ObjectUnderTest_Behaviour_Consequence()
{
    Assert.That(tra_la_la);
}
例如:
[Test]
public void WifeIsTired_TakeWifeToDinner_WifeIsGrateful()
{
    Assert.That(tra_la_la);
}

[Test]
public void WifeIsTired_MentionNewGirlfriend_WifeGetsHalf()
{
    Assert.That(tra_la_la);
}

2
另一种选择是使用“方法_场景_期望”的命名方式,例如AddItem_EmptyCart_OneItemInCart()。这种方式假设每个被测试类都有一个测试夹具类。 - Ryan
@Ryan -- 你的建议是我最终采用的。这也是书籍《单元测试的艺术》的推荐。 - Dave

6

并没有一个固定的标准,不同的人和地方会有不同的方案。重要的是你要遵循一个标准。

个人而言,我比较喜欢以下这种方式 - 示例代码使用C#编写,但非常接近Java,同样的规则适用:

[Test]
public void person_should_say_hello()
{
     // Arrange
     var person = new Person();
     // Act
     string result = person.SayHello();
     // Assert
     Assert(..., "The person did not say hello correctly!");
}

明确

测试名称应该给出被测试类的名称。在这个例子中,被测试的类是Person。测试名称还应该包含被测试的方法的名称。这样,如果测试失败,你至少知道在哪里寻找解决方法。我也建议遵循AAA - 安排,行动,断言规则,这将确保您的测试易于阅读和遵循。

友好的失败消息

在确定结果/状态时,包含一个可选的消息非常有用。这使得当测试失败时更容易,特别是当它作为构建过程的一部分或通过外部工具运行时。

下划线

我所遵循的最后一条(尽管是可选的)准则是在测试名称中使用下划线。虽然我不喜欢在生产代码中使用下划线,但在测试名称中使用它们很有用,因为测试名称通常更长。快速扫视使用下划线的测试名称证明更易读,尽管这是主观的,并在单元测试实践方面引起了许多争议。

集成测试

相同的标准适用于集成测试,唯一的区别是这些测试的位置应该与单元测试分开。在上面的示例代码中,测试类将被称为PersonTests,并位于名为PersonTests.cs的文件中。集成测试也将以类似的方式命名- PersonIntegrationTests,位于PersonIntegrationTests.cs中。同一个项目可以用于这些测试,但确保它们位于不同的目录中。


6

我只是写出它的用途。不像你需要在其他地方输入这些名称,所以拥有一个testWibbleDoesNotThrowAnExceptionIfPassedAFrobulator并不是问题。任何测试都以“test”开头,显然。


使用Martin Fowler的术语表达方式,这是一个不错的选择。 - progonkpa

2
看看BDD(行为驱动开发)和特别是这篇博客文章对我们的指导很有帮助。
BDD主要关注组件及其应该做什么。因此,它直接影响您如何命名/结构化您的测试以及它们用于设置条件和验证的代码。BDD不仅允许开发人员阅读/编写测试,而且非技术团队成员(业务分析师等)也可以通过指定测试和验证来做出贡献。


1
在这种情况下,我可能会找到使用最多的命名约定,并重构其他代码以使用它。如果使用最多的那个真的很糟糕,我仍然会查看现有代码,并尝试找到一个我可以接受的。一致性比任意约定更重要。

我追求的不是任意的惯例,而是最佳实践。 - Dave

1

我使用 FunctionTestCondition 结构。如果我有两个方法,GetSet,我可能会创建以下测试方法:

  • GetTest 作为正面测试(一切正常)。
  • GetTestInvalidIndex 测试传递给方法的无效索引。
  • GetTestNotInitialized 测试在使用之前未初始化数据。
  • SetTest
  • SetTestInvalidIndex
  • SetTestTooLargeValue
  • SetTestTooLongString

0

按照设置对测试进行分组,围绕此设置创建一个测试类,并使用Test或IntegrationTest作为后缀进行命名。使用像JUnitTestNG这样的测试框架,您可以根据需要命名测试方法。我会将方法命名为它所测试的内容,使用驼峰式句子,而不是以test为前缀。这些框架使用@Test注释将方法标记为测试。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接