命名单元测试类和测试方法的最佳实践是什么?
这在之前的SO中讨论过,在什么是单元测试的一些流行命名约定?
我不知道这是否是一种非常好的方法,但目前在我的测试项目中,我在每个生产类和测试类之间都有一对一的映射,例如Product和ProductTest。
在我的测试类中,我有我正在测试的方法的名称,一个下划线,然后是情况和我期望发生的事情,例如Save_ShouldThrowExceptionWithNullName()。
命名单元测试类和测试方法的最佳实践是什么?
这在之前的SO中讨论过,在什么是单元测试的一些流行命名约定?
我不知道这是否是一种非常好的方法,但目前在我的测试项目中,我在每个生产类和测试类之间都有一对一的映射,例如Product和ProductTest。
在我的测试类中,我有我正在测试的方法的名称,一个下划线,然后是情况和我期望发生的事情,例如Save_ShouldThrowExceptionWithNullName()。
当前回答
看到的: http://googletesting.blogspot.com/2007/02/tott-naming-unit-tests-responsibly.html
对于测试方法名称,我个人认为使用详细的和自文档化的名称非常有用(以及进一步解释测试正在做什么的Javadoc注释)。
其他回答
我最近提出了以下约定来命名我的测试,它们的类和包含项目,以最大化它们的描述符:
假设我在MyApp的一个项目中测试设置类。序列化的名称空间。
首先,我将使用MyApp.Serialization.Tests名称空间创建一个测试项目。
在这个项目和命名空间中,我将创建一个名为IfSettings的类(保存为IfSettings.cs)。
假设我正在测试SaveStrings()方法。我将测试命名为CanSaveStrings()。
当我运行这个测试时,它将显示以下标题:
MyApp.Serialization.Tests.IfSettings.CanSaveStrings
我认为这很好地告诉了我,它在测试什么。
当然,在英语中名词“Tests”和动词“Tests”是一样的,这是很有用的。
在命名测试时,你的创造力是没有限制的,这样我们就可以得到完整的句子标题。
通常测试名称必须以动词开头。
例子包括:
检测(例如DetectsInvalidUserInput) 抛出(例如ThrowsOnNotFound) Will(例如WillCloseTheDatabaseAfterTheTransaction)
etc.
另一个选择是用“that”而不是“if”。
后者虽然节省了我的击键,但更准确地描述了我正在做的事情,因为我不知道,测试的行为是否存在,但我正在测试它是否存在。
(编辑)
在使用上述命名约定一段时间后,我发现,在处理接口时,If前缀可能令人困惑。恰好,测试类IfSerializer.cs看起来与“打开文件选项卡”中的isserializer .cs接口非常相似。 当在测试、被测试的类和它的接口之间来回切换时,这会非常烦人。因此,我现在将选择That而不是If作为前缀。
此外,我现在只对我的测试类中的方法使用“_”来分隔我的测试方法名称中的单词,因为它在其他任何地方都不是最佳实践:
[Test] public void detects_invalid_User_Input()
我觉得这个更容易读。
(结束编辑)
我希望这能产生更多的想法,因为我认为命名测试非常重要,因为它可以为您节省大量时间,否则您将花费大量时间试图理解测试正在做什么(例如,在长时间中断后恢复项目)。
看到的: http://googletesting.blogspot.com/2007/02/tott-naming-unit-tests-responsibly.html
对于测试方法名称,我个人认为使用详细的和自文档化的名称非常有用(以及进一步解释测试正在做什么的Javadoc注释)。
在VS + NUnit中,我通常在项目中创建文件夹,将功能测试分组在一起。然后我创建单元测试fixture类,并以我正在测试的功能类型命名它们。[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
我应该补充一点,将您的测试放在同一个包中,但位于与被测试的源代码并行的目录中,一旦您准备好部署它,就可以消除代码的膨胀,而不必执行一堆排除模式。
我个人喜欢“JUnit Pocket Guide”中描述的最佳实践……很难有一本书比JUnit!
我喜欢遵循测试的“Should”命名标准,同时以被测单元(即类)命名测试夹具。
为了说明(使用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));
}
}
为什么“应该”?
我发现它迫使测试编写人员用这样一句话来命名测试:“应该[处于某种状态][在动作发生之后/之前/当][发生时]”
是的,到处写“应该”确实有点重复,但正如我所说,它迫使作者以正确的方式思考(所以对新手来说很好)。此外,它通常会产生一个可读的英文测试名称。
更新:
我注意到Jimmy Bogard也是“should”的粉丝,他甚至有一个名为“should”的单元测试库。
更新(4年后…)
For those interested, my approach to naming tests has evolved over the years. One of the issues with the Should pattern I describe above as its not easy to know at a glance which method is under test. For OOP I think it makes more sense to start the test name with the method under test. For a well designed class this should result in readable test method names. I now use a format similar to <method>_Should<expected>_When<condition>. Obviously depending on the context you may want to substitute the Should/When verbs for something more appropriate. Example: Deposit_ShouldIncreaseBalance_WhenGivenPositiveValue()