一般

所有测试都遵循相同的标准。 清楚每个测试状态是什么。 明确预期的行为。

例子

1) MethodName_StateUnderTest_ExpectedBehavior

Public void Sum_NegativeNumberAs1stParam_ExceptionThrown() 

Public void Sum_NegativeNumberAs2ndParam_ExceptionThrown () 

Public void Sum_simpleValues_Calculated ()

来源:单元测试的命名标准

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 ()

其他

用Test结束方法名 用类名开始方法名


只要你坚持一个练习,这并不重要。通常,我为一个方法编写一个单元测试,它涵盖了该方法的所有变化(我有简单的方法;),然后为需要它的方法编写更复杂的测试集。因此,我的命名结构通常是test(从JUnit 3保留下来的)。


第一组名称对我来说可读性更强,因为camel套管分隔了单词,下划线分隔了命名方案的各个部分。

我还倾向于在函数名或外围名称空间或类中包含“Test”。


在这一点上,我很支持你。您使用的命名约定是:

清楚每个测试状态是什么。 明确预期的行为。

您还需要从测试名中得到什么?

与Ray的回答相反,我认为Test这个前缀没有必要。这是测试代码,我们知道。如果您需要这样做来识别代码,那么您就有更大的问题,您的测试代码不应该与生产代码混淆。

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

也就是说,我对测试和博客我的冒险仍然很陌生:)


我确实像其他方法一样命名我的测试方法,使用“pascal套管”,没有任何下划线或分隔符。我省略了方法的后缀Test,因为它没有增加任何值。属性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
}

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

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

我的命名惯例是基于Bryan Cook的文章“TDD技巧:测试命名惯例和指南”。我发现这篇文章很有帮助。


我为测试名称空间、类和方法使用“T”前缀。

我尽量保持整洁,创建复制名称空间的文件夹,然后为测试创建一个测试文件夹或单独的项目,并为基本测试复制生产结构:

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

我可以很容易地看出某些东西是一个测试,我确切地知道它属于什么原始代码,(如果你不能解决这个问题,那么这个测试就太复杂了)。

它看起来就像接口命名约定,(我的意思是,你不会混淆以“I”开头的东西,也不会混淆以“T”开头的东西)。

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

无论如何,这在理论上是很好的,并且对于小型项目非常有效。


这也值得一读:结构化单元测试

结构中每个被测试的类都有一个测试类。这并不罕见。但对我来说不同寻常的是,他为每个被测试的方法都有一个嵌套类。

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

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


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

Sum_ThrowsException_WhenNegativeNumberAs1stParam

然而,我所看到的是使测试名称遵循的单元测试结构

安排 行为 断言

它也遵循BDD / Gherkin语法:

鉴于 当 然后

这将是命名测试的方式:UnderTheseTestConditions_WhenIDoThis_ThenIGetThis

对于你的例子:

WhenNegativeNumberAs1stParam_Sum_ThrowsAnException

然而,我更喜欢把测试的方法名放在前面,因为这样测试就可以按字母顺序排列,或者在VisStudio的成员下拉框中按字母顺序排列,并且一个方法的所有测试都被分组在一起。


在任何情况下,我喜欢用下划线分隔测试名称的主要部分,而不是每个单词,因为我认为这样更容易阅读和理解测试的要点。

换句话说,我更喜欢:Sum_ThrowsException_WhenNegativeNumberAs1stParam,而不是sum_throw_exception_when_negative_number_as_1st_param。