单元测试都有哪些流行的命名约定? [关闭]

Posted

技术标签:

【中文标题】单元测试都有哪些流行的命名约定? [关闭]【英文标题】:What are some popular naming conventions for Unit Tests? [closed]单元测试有哪些流行的命名约定? [关闭] 【发布时间】:2010-09-10 21:52:03 【问题描述】:

一般

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

示例

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

其他

Test 结束方法名称 以类名开头的方法名

【问题讨论】:

见Behavior Driven Development。 【参考方案1】:

我倾向于使用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

【讨论】:

【参考方案2】:

这也值得一读:Structuring Unit Tests

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

例如

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

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

【讨论】:

对于那些在 Visual Studio 中使用 Resharper 的测试运行器的用户,他们使用 8.x 中的嵌套测试类修复了错误。从那时起,这成为了我的首选结构。 使用 MethodName_StateUnderTest_ExpectedBehavior 方法使名称变得很长是否重要?如“InitializeApiConfiguration_MissingApiKey_IllegalArgumentException”。这真的是一个很好的测试名称吗?【参考方案3】:

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

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

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

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

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

不管有没有测试,编译都很容易。

不管怎样,理论上还是不错的,对于小型项目也很有效。

【讨论】:

有趣的方法。有些人可能会争辩说 T 前缀与您在泛型中使用的约定冲突(例如 func(T1, T2, TResult)),但我个人不在乎,只要团队内部达成共识。名称很短,这也使内容更具可读性。 对我来说太匈牙利了(符号)。此外,ad stung 指出,前缀 T 用于泛型类型参数。 我同意,匈牙利符号已被贬低,并且由于与标准泛型类型参数的冲突,我没有看到在这种情况下应用异常(就像接口一样)。【参考方案4】:

我确实像使用“PascalCasing”的其他方法一样命名我的测试方法,没有任何下划线或分隔符。我将后缀 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

对于测试异常或不可能的操作的方法,我在测试方法前加上单词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"。我发现这篇文章很有帮助。

【讨论】:

+1 链接到我的帖子——尽管在您的测试中没有必要使用“测试”前缀。确保您的测试指定了预期的行为。例如,CanRetrieveProperCountWhenAddingMultipleItems() 我不喜欢它,因为它不包含预期的行为【参考方案5】:

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

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

测试名称还需要什么?

与Ray's answer 相反,我认为 Test 前缀是不必要的。这是测试代码,我们知道。如果你需要这样做来识别代码,那么你有更大的问题,你的测试代码不应该和你的生产代码混在一起。

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

也就是说,我对测试还是很陌生,blogging my adventures with it :)

【讨论】:

“只要它可读、清晰”和“谁……在乎”略有矛盾。好吧,当它不可读和清晰时,每个人都在乎,所以这很重要。 :-) 前缀的一个附加参数。当您在 IDE 中搜索文件时,您可以从 Test 和您的类名开始轻松搜索测试用例。如果类名和测试类名相同,我们将总是不得不暂停并读取两个文件的路径 @THISUSERNEEDSHELP 我认为您的观点可以通过像 src/libssrc/tests 这样的良好文件夹结构轻松克服。我知道一些测试运行器框架确实需要像 test 这样的前缀来识别测试代码,因此在这些情况下无法避免,但对于其余情况,它可能是重复的 no required 前缀。 @negrotico19 当你 Search Everywhere (shift shift) 或 Find a Class By Name (CMD O) 时,我正在考虑 IntelliJ 中的情况。我知道它通过文件夹结构或模块结构来区分,但是当我们搜索某些内容时,我们已经知道要搜索什么。例如,如果我正在寻找一个测试,我想将我的搜索限制为test,然后搜索名称,而不是搜索名称并然后通过眼睛手动过滤掉测试。这是一个很小的区别,但是“测试[类名]”要容易得多,并且只弹出一个并减少心理负担【参考方案6】:

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

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

【讨论】:

@Frank methodName = camelCase MethodName = PascalCase @metro-smurf:有趣的区别,我从未听说过使用 PascalCase 一词,而且我已经这样做了很长时间。我只看到微软开发者圈子里出现了 PascalCase 这个词,你是这样做的吗? Pascal Casing 和 Camel Casing 的历史(来自:Brad Abrams - blogs.msdn.com/brada/archive/2004/02/03/67024.aspx)... “在框架的初始设计中,我们就命名风格进行了数百小时的辩论。为了促进这些“我们创造了许多术语。由于 Anders Heilsberg(Turbo Pascal 的原始设计师)是设计团队的关键成员,因此我们选择 Pascal Casing 一词来表示 Pascal 编程语言普及的套管样式也就不足为奇了。” 【参考方案7】:

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

【讨论】:

以上是关于单元测试都有哪些流行的命名约定? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

markdown 单元测试命名约定

一文弄懂Springboot+Junit5微服务单元测试编写实践

python如何开展单元测试?

自动化单元测试工具目前常用的都有哪些?

在 Angular 中对 requestAnimationFrame 进行单元测试的选项都有哪些?

Golang 单元测试规范