208

一般的

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

例子

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结束方法名
  • 以类名开头的方法名
4

7 回答 7

98

在这个人上,我非常赞同你。您使用的命名约定是:

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

测试名称还需要什么?

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

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

也就是说,我对用它测试和记录我的冒险还是很陌生:)

于 2008-09-18T20:32:48.137 回答
38

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

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

例如

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

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

于 2012-01-21T18:35:16.607 回答
30

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

Sum_ThrowsException_WhenNegativeNumberAs1stParam

但是,我确实看到很多是使测试名称遵循单元测试结构

  • 安排
  • 行为
  • 断言

它也遵循以下 BDD / Gherkin 语法:

  • 给定
  • 什么时候
  • 然后

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

所以你的例子:

WhenNegativeNumberAs1stParam_Sum_ThrowsAnException

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


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

换句话说,我喜欢:Sum_ThrowsException_WhenNegativeNumberAs1stParamSum_Throws_Exception_When_Negative_Number_As_1st_Param.

于 2012-02-15T18:20:19.490 回答
22

我确实将我的测试方法命名为使用“PascalCasing”的其他方法,没有任何下划线或分隔符。我留下了该方法的后缀测试,因为它没有增加任何价值。该方法是测试方法由属性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
}

对于测试异常或不可能的操作的方法,我在测试方法前加上“ Cannot ”一词。

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

我的命名约定基于 Bryan Cook 的文章“TDD Tips: Test Naming Conventions & Guidelines”。我发现这篇文章很有帮助。

于 2009-08-18T06:40:59.763 回答
5

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

我也倾向于在某处包含“测试”,无论是在函数名中,还是在封闭的命名空间或类中。

于 2008-09-18T20:04:52.870 回答
-3

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

于 2008-09-18T20:04:47.800 回答
-7

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

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

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

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

它看起来就像接口命名约定,(我的意思是,您不会对以“I”开头的事物感到困惑,也不会与“T”混淆)。

在有或没有测试的情况下进行编译都很容易。

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

于 2011-01-07T03:56:20.457 回答