单元测试有哪些流行的命名约定?

时间:2008-09-18 19:59:56

标签: unit-testing naming-conventions

常规

  • 对所有测试遵循相同的标准。
  • 明确每个测试状态是什么。
  • 具体说明预期的行为。

实施例

1)MethodName_StateUnderTest_ExpectedBehavior

Public void Sum_NegativeNumberAs1stParam_ExceptionThrown() 

Public void Sum_NegativeNumberAs2ndParam_ExceptionThrown () 

Public void Sum_simpleValues_Calculated ()

来源:Naming standards for Unit Tests

2)按下划线分隔每个单词

Public void Sum_Negative_Number_As_1st_Param_Exception_Thrown() 

Public void Sum_Negative_Number_As_2nd_Param_Exception_Thrown () 

Public void Sum_Simple_Values_Calculated ()

其他

  • 使用测试
  • 结束方法名称
  • 使用班级名称
  • 启动方法名称

7 个答案:

答案 0 :(得分:91)

我和你在这一个人身上非常相似。您使用的命名约定是:

  • 清楚每个测试状态是什么。
  • 具体关于预期的行为。

您还需要一个测试名称吗?

Ray's answer相反,我不认为 Test 前缀是必要的。它是测试代码,我们知道。如果您需要这样做来识别代码,那么您就会遇到更大的问题,您的测试代码不应与您的生产代码混淆。

至于下划线的长度和用途,它的测试代码,谁在乎呢?只有您和您的团队才能看到它,只要它是可读的,并且清楚测试正在做什么,继续! :)

那就是说,我对测试和blogging my adventures with it仍然很陌生:)

答案 1 :(得分:35)

这也值得一读:Structuring Unit Tests

  

该结构每个类都有一个测试类。那不是那么不寻常。但对我来说不同寻常的是,他为每个被测试的方法都有一个嵌套类。

e.g。

using Xunit;

public class TitleizerFacts
{
    public class TheTitleizerMethod
    {
        [Fact]
        public void NullName_ReturnsDefaultTitle()
        {
            // Test code
        }

        [Fact]
        public void Name_AppendsTitle()
        {
            // Test code
        }
    }

    public class TheKnightifyMethod
    {
        [Fact]
        public void NullName_ReturnsDefaultTitle()
        {
            // Test code
        }

        [Fact]
        public void MaleNames_AppendsSir()
        {
            // Test code
        }

        [Fact]
        public void FemaleNames_AppendsDame()
        {
            // Test code
        }
    }
}

这就是为什么:

  

一方面,这是保持测试有条理的好方法。一切   方法的测试(或事实)被组合在一起。例如,如果   你使用CTRL + M,CTRL + O快捷方式来折叠方法体,你可以   轻松扫描您的测试并将其读作您的代码规范。

我也喜欢这种方法:

<强> MethodName_StateUnderTest_ExpectedBehavior

所以也许适应:

StateUnderTest_ExpectedBehavior

因为每个测试都已经在嵌套类

答案 2 :(得分:26)

我倾向于使用MethodName_DoesWhat_WhenTheseConditions的约定,例如:

Sum_ThrowsException_WhenNegativeNumberAs1stParam

但是,我看到很多是让测试名称遵循

的单元测试结构
  • 安排
  • 断言

其中也遵循BDD / Gherkin语法:

  • 鉴于
  • 然后

将以下列方式命名测试:UnderTheseTestConditions_WhenIDoThis_ThenIGetThis

所以你的例子:

WhenNegativeNumberAs1stParam_Sum_ThrowsAnException

但是我更喜欢首先测试方法名称,因为测试可以按字母顺序排列,或按字母顺序排列在VisStudio的成员下拉框中,并且1方法的所有测试都组合在一起。


无论如何,我喜欢用下划线分隔测试名称的主要部分,而不是每个单词,因为我觉得它更容易阅读和得到测试点。

换句话说,我喜欢:Sum_ThrowsException_WhenNegativeNumberAs1stParam优于Sum_Throws_Exception_When_Negative_Number_As_1st_Param

答案 3 :(得分:22)

我使用“PascalCasing”命名我的测试方法,就像其他方法一样,没有任何下划线或分隔符。我将该方法的postfix Test 保留为out,因为它没有添加任何值。该方法是一种测试方法,由属性 TestMethod

表示
[TestMethod]
public void CanCountAllItems() {
  // Test the total count of items in collection.
}

由于每个Test类只应测试另一个类,因此我将该类的名称保留在方法名称之外。包含测试方法的类的名称被命名为使用后缀“Tests”测试的类。

[TestClass]
public class SuperCollectionTests(){
    // Any test methods that test the class SuperCollection
}

对于测试不可能的异常或操作的方法,我在测试方法前加上单词不能

[TestMethod]
[ExpectedException(typeOf(ArgumentException))]
public void CannotAddSameObjectAgain() {
  // Cannot add the same object again to the collection.
}

我的命名对话基于布莱恩库克的文章"TDD Tips: Test Naming Conventions & Guidelines"。我发现这篇文章非常有用。

答案 4 :(得分:5)

第一组名称对我来说更具可读性,因为CamelCasing将单词和下划线分开命名方案的各个部分。

我也倾向于在函数名称或封闭的命名空间或类中包含“Test”。

答案 5 :(得分:-3)

只要您遵循一次练习,这并不重要。通常,我为一个方法编写单个单元测试,该方法涵盖方法的所有变体(我有简单的方法;)然后为需要它的方法编写更复杂的测试集。因此,我的命名结构通常是测试(来自JUnit 3的保留)。

答案 6 :(得分:-8)

我为测试命名空间,类和方法使用'T'前缀。

我尝试整洁并创建复制命名空间的文件夹,然后为测试创建测试文件夹或单独的项目,并复制基本测试的生产结构:

AProj
   Objects
      AnObj
         AProp
   Misc
      Functions
         AFunc
   Tests
      TObjects
         TAnObj
            TAnObjsAreEqualUnderCondition
      TMisc
         TFunctions
            TFuncBehavesUnderCondition

我可以很容易地看到某些东西是一个测试,我确切地知道它所属的原始代码,(如果你无法解决这个问题,那么无论如何测试太复杂了。)

它看起来就像接口命名约定(我的意思是,你不会对以'我'开头的事情感到困惑,也不会对'T'感到困惑。)

使用或不使用测试进行编译很容易。

无论如何,这在理论上是好的,对小型项目也很有效。