几种方法的 BDD 命名

Posted

技术标签:

【中文标题】几种方法的 BDD 命名【英文标题】:BDD naming for several methods 【发布时间】:2017-06-27 04:19:34 【问题描述】:

当您正在测试的类中有一个方法时,BDD 命名方法非常有效。假设我们有一个具有 Connect 方法的 Connector 类:

Should_change_status_to_Connected_if_Disconnected

很漂亮,对吧?但是当一个类中有多个方法时,当我必须为测试命名时,我感到很困惑(假设我们在类中添加了 Disconnect 方法)。

我看到了两种可能的解决方案。第一个是添加一个带有方法名称的前缀,例如:

Should_change_status_to_Connected_if_Disconnected_when_Connect_was_called

另一种方法是为您正在测试的每个方法引入嵌套测试类。

public class ConnectorTests

  public class ConnectTests
  
    public void Should_change_status_to_Connected_if_Disconnected()
    
      ...
    
  

  public class DisconnectTests
  
    public void Should_change_status_to_Disconnected_if_Connected()
    
      ...
    
  

老实说,这两种方法都感觉有点不对劲(可能只是因为我不习惯)。推荐的方式是什么?

【问题讨论】:

您能否为您的问题添加更多上下文。方法A和方法B有什么区别。他们都做了些什么? @SergeyBerezovskiy,我的意思是一个类包含多个方法的一般情况。 抱歉,不清楚您遇到了什么问题。方法引入了一些行为。如果 methodA 用于 somethingA 而 methodB 用于 somethingB 那么你的问题就不清楚了。如果他们都为 somethingC 那么 methodAmethodB 有什么区别? 1.注意大小写(如果!= if 等。没有严格命名和约定的 BDD 总比没有好) 2. 为什么不将这两种方法保留在同一个类上?我发现这篇文章是关于 BDD 的一个很好且简单的参考:dzone.com/articles/7-popular-unit-test-naming 【参考方案1】:

我使用不同的命名风格编写了剂量测试。从本质上讲,这些测试方法由于名称过长而难以阅读,它们超出了每行符号的限制,通常下划线的方法名称违反了命名约定。当您想向 BDD 场景添加“和”条件或先决条件时,困难就开始了,例如“当连接器初始化时,如果断开连接且网络可用且参数 1 为...且参数 2 为...,则应将状态更改为已连接”。因此,您必须将测试用例分组到许多类、子文件夹等中。这会增加开发和支持的时间。

C# 中的另一种方法是编写测试,例如使用 javascript 测试框架:Jasmine、Jest 等。对于类和方法的单元测试,我会使用 Arrange/Act/Assert 样式,以及针对 Feature/Story 场景的 BDD 样式,但是两种样式都可以使用。在 C# 中,我使用我的 Heleonix.Testing.NUnit 库并以 AAA 或 BDD (GWT) 样式编写测试:

using NUnit.Framework;
using Heleonix.Testing.NUnit.Aaa;
using static Heleonix.Testing.NUnit.Aaa.AaaSpec;

[ComponentTest(Type = typeof(Connector))]
public static class ConnectorTests

    [MemberTest(Name = nameof(Connector.Connect))]
    public static void Connect()
    
        Connector connector = null;

        Arrange(() =>
        
            connector = new Connector();
        );

        When("the Connect is called", () =>
        
            Act(() =>
            
                 connector.Connect(options);
            );

            And("the Connector is disconnected", () =>
            
                Arrange(() =>
                
                     connector.Disconnect();
                );
            );

            Should("change the status to Disconnected", () =>
            
                Assert.That(connector.Disconnected, Is.True);
            );
        );
    

对我来说重要的是,几个月后我可以打开这样的测试并清楚地回忆起那里写的内容,而不是坐几个小时来了解它测试什么/如何测试。

【讨论】:

【参考方案2】:

就我而言,首先,我尝试根据前置条件和后置条件将类分开,这样我就可以对一些行为进行分组并将相关的事物放在一起。例如,在您的情况下,一个先决条件可能是“断开连接”,因此,您可以使用 ClassInitialize、TestInitialize、TestCleanup、ClassCleanup 等属性来准备“断开连接环境”(here some examples in MSDN)

请按照其他开发人员的建议,不要忘记naming conventions。

希望对您有所帮助,问候。

【讨论】:

【参考方案3】:

由于测试用例彼此完全独立,因此您必须使用静态类来初始化稍后将用于测试的那些值、连接等。如果您想使用个人值和发起者,您必须在您的类中单独声明它们。我用于这个 nunit 框架。

顺便说一句,你在 c# 中,使用 .net 开发人员的命名约定...

【讨论】:

以上是关于几种方法的 BDD 命名的主要内容,如果未能解决你的问题,请参考以下文章

行为驱动开发(BDD)实践示例

如何解决两个不使用命名空间的第三方库之间的类名冲突?

JS中命名空间的几种管理方式

程序中必须知道的几种命名规范

一些概念

大家的Android项目包命名规则是怎样的