unit testing命名最佳实践

命名unit testing类和testing方法的最佳实践是什么?

这在前面讨论过,在unit testing的一些stream行的命名约定是什么?

我不知道这是否是一个非常好的方法,但是目前在我的testing项目中,我在每个生产类和一个testing类(例如ProductProductTest之间都有一对一的映射关系。

然后在我的testing类中,我使用方法的名称,我正在testing的方法,一个下划线,然后情况和我期望发生,例如Save_ShouldThrowExceptionWithNullName()

我喜欢Roy Osherove的命名策略 ,如下所示:

[UnitOfWork__StateUnderTest__ExpectedBehavior]

它具有方法名称和结构化方式所需的全部信息。

工作单元可以像单一的方法一样小,也可以像多个类一样大。 它应该代表所有在这个testing案例中被testing的东西,并且在控制之下。

对于程序集,我使用典型的.Tests结尾,我认为这是相当普遍的,对于类(以Tests结束)是相同的:

[NameOfTheClassUnderTestTests]

以前我用夹具作为后缀而不是testing,但我认为后者更常见,然后我改变了命名策略。

我喜欢这种命名风格:

 OrdersShouldBeCreated(); OrdersWithNoProductsShouldFail(); 

等等。 这对非testing者来说真的很清楚是什么问题。

我喜欢按照“应该”命名标准进行testing,同时在testing装置 (即课程)之后命名testing夹具

为了说明(使用C#和NUnit):

 [TestFixture] public class BankAccountTests { [Test] public void Should_Increase_Balance_When_Deposit_Is_Made() { var bankAccount = new BankAccount(); bankAccount.Deposit(100); Assert.That(bankAccount.Balance, Is.EqualTo(100)); } } 

为什么“应该”

我发现它迫使testing作者用“应该[处于某种状态] [之前/之前/之后] [动作发生]”的句子来命名testing。

是的,在任何地方写“应该”都会有点重复,但正如我所说的那样,它会迫使作家以正确的方式思考(对新手来说也是如此)。 另外它通常会产生一个可读的英文testing名称。

更新

我注意到Jimmy Bogard也是“应该”的粉丝,甚至还有一个叫做Should的unit testing库。

更新(4年后…)

对于那些有兴趣的人来说,我的命名testing方法已经发展了多年。 我在上面描述的应该模式中的一个问题是,一眼就不容易知道哪种方法正在testing中。 对于OOP,我认为用被测方法开始testing名称更有意义。 对于devise良好的类,这应该会导致可读的testing方法名称。 我现在使用类似于<method>_Should<expected>_When<condition>的格式。 很显然,根据上下文,你可能想用“应当/当动词”来替代更适合的东西。 例如: Deposit_ShouldIncreaseBalance_WhenGivenPositiveValue()

Kent Beckbuild议:

  • 每个“单元”(您的程序的类)一个testing夹具。 testing夹具本身就是类。 testing夹具名称应该是:

     [name of your 'unit']Tests 
  • testing用例(testing夹具方法)的名称如下所示:

     test[feature being tested] 

例如,具有以下类:

 class Person { int calculateAge() { ... } // other methods and properties } 

testing夹具将是:

 class PersonTests { testAgeCalculationWithNoBirthDate() { ... } // or testCalculateAge() { ... } } 

类名称 。 对于testing夹具名称,我发现“testing”在很多领域中无处不在的语言中是相当普遍的。 例如,在工程领域: StressTest和化妆品领域: SkinTest 。 对不起,不赞同肯特,但在我的testing夹具( StressTestTest ?)使用“testing”是混乱。

“单位”在域中也用得很多。 如MeasurementUnitMeasurementUnitTest是“Measurement”还是“MeasurementUnit”?

所以我喜欢为我的所有testing类使用“Qa”前缀。 例如QaSkinTestQaMeasurementUnit 。 它永远不会与领域对象混淆,使用前缀而不是后缀意味着所有的testing夹具都可视化地共存(如果您的testing项目中有假货或其他支持类,

命名空间 。 我在C#中工作,并将testing类放在与testing类相同的名称空间中。 比单独的testing命名空间更方便。 当然,testing类在不同的项目中。

testing方法名称 。 我喜欢命名我的方法WhenXXX_ExpectYYY。 它使前提条件清晰,并有助于自动化文档(一个TestDox)。 这与Googletesting博客上的build议类似,但前提条件和期望更加分离。 例如:

 WhenDivisorIsNonZero_ExpectDivisionResult WhenDivisorIsZero_ExpectError WhenInventoryIsBelowOrderQty_ExpectBackOrder WhenInventoryIsAboveOrderQty_ExpectReducedInventory 

请参阅: http : //googletesting.blogspot.com/2007/02/tott-naming-unit-tests-responsibly.html

对于testing方法的名称,我个人发现使用详细和自我logging的名字是非常有用的(Javadoc的评论,进一步解释了什么是testing正在做)。

为了最大限度地描述它们,我最近提出了下面的约定来命名我的testing,他们的类和包含项目:

比方说,我正在testingMyApp.Serialization命名空间中的项目中的设置类。

首先我将用MyApp.Serialization.Tests命名空间创build一个testing项目。

在这个项目中,当然还有命名空间,我将创build一个名为IfSettings (保存为IfSettings.cs)的类。

比方说我正在testingSaveStrings()方法。 – >我将命名testingCanSaveStrings()

当我运行这个testing时,它会显示下面的标题:

MyApp.Serialization.Tests.IfSettings.CanSaveStrings

我想这个告诉我很好,它正在testing什么。

当然,在英语中,名词“Tests”与动词“tests”是相同的。

你在命名testing方面的创造力是没有限制的,所以我们可以为他们提供完整的句子标题。

通常,testing名称必须以动词开头。

例子包括:

  • 检测(例如DetectsInvalidUserInput)
  • 抛出(例如ThrowOnNotFound)
  • 意志(例如WillCloseTheDatabaseAfterTheTransaction)

等等

另一种select是使用“that”而不是“if”。

后者为我节省了键盘input,并且更准确地描述了我正在做的事情,因为我不知道被testing的行为是否存在,但是是否正在testing。

[ 编辑 ]

现在使用上面的命名约定现在已经有一段时间了,我发现,在处理接口时, If前缀可能会造成混淆。 恰好如此,testing类IfSerializer.cs与“Open Files”选项卡中的接口ISerializer.cs非常相似。 在testing,被testing的类和接口之间来回切换时,这会变得非常烦人。 因此,我现在将select如果作为前缀。

此外,我现在使用 – 仅用于我的testing类中的方法,因为它不被认为是其他任何地方的最佳实践 – “_”用于分隔testing方法名称中的单词,如下所示:

  • [testing] public void detected_invalid_User_Input()*

我觉得这样比较容易阅读。

[ 结束编辑 ]

我希望这会产生更多的想法,因为我认为命名testing非常重要,因为它可以为您节省大量的时间,否则这些时间会花费在试图了解testing正在做什么(例如,在延长的中断之后重新开始项目之后) 。

我使用Given-When-Then概念。 看看这个简短的文章http://cakebaker.42dh.com/2009/05/28/given-when-then/ 。 文章用BDD来描述这个概念,但是你也可以在TDD中使用它,而不需要做任何改变。

我认为最重要的事情之一是在你的命名约定中保持一致(并与你的团队的其他成员达成一致)。 很多时候,我看到在同一个项目中使用了大量不同的约定。

在VS + NUnit中,我通常会在项目中创build文件夹,将functiontesting分组在一起。 然后我创buildunit testing夹具类,并在我testing的functiontypes之后命名它们。 [Test]方法按照Can_add_user_to_domain命名:

 - MyUnitTestProject + FTPServerTests <- Folder + UserManagerTests <- Test Fixture Class - Can_add_user_to_domain <- Test methods - Can_delete_user_from_domain - Can_reset_password 

我应该补充说,保持你的testing在同一个包中,但是在一个并行目录中被testing的源代码消除了代码的膨胀,一旦你准备好部署它,而不需要做一堆排除模式。

我个人喜欢“JUnit Pocket Guide”中描述的最佳实践…很难打败JUnit的合着者所写的一本书!

Foo类的testing用例的名称应该是FooTestCase或类似的东西(FooIntegrationTestCase或FooAcceptanceTestCase) – 因为它是一个testing用例。 见http://xunitpatterns.com/一些标准的命名约定,如testing,testing用例,testing夹具,testing方法等。;