9

BDD naming approach works perfectly when there's one method in a class that you're testing. Let's assume we have a Connector class which has Connect method:

Should_change_status_to_Connected_if_Disconnected

Beautiful, right? But I feel confused when I have to name tests when there're several methods in a class (let's assume we added Disconnect method to our class).

I see two possible solutions. The first one is to add a prefix with a method name like:

Should_change_status_to_Connected_if_Disconnected_when_Connect_was_called

Another approach is to introduce nested test classes for each method you're testing.

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()
    {
      ...
    }
  }
}

Honestly both approaches feel a little bit off (may be just because I'm not used to it). What's the recommended way to go?

Shadmehr
  • 278
  • 4
  • 13
SiberianGuy
  • 22,118
  • 44
  • 135
  • 253
  • Can you please add more context to your question. What's the difference between methodA and methodB. They both do something? – Sergey Berezovskiy Feb 09 '17 at 08:54
  • @SergeyBerezovskiy, I really meant a general case when a class contains several methods. – SiberianGuy Feb 09 '17 at 08:55
  • 1
    sorry, but it's not clear what kind of problem you have. Method introduces some behavior. If methodA is for *somethingA* and methodB is for *somethingB* then your problem is not clear. If they both for *somethingC* then what the difference between *methodA* and *methodB*? – Sergey Berezovskiy Feb 09 '17 at 08:57
  • 1. Pay attention to casing (If != if, etc. BDD w/o strict naming and conventions is worst than nothing) 2. why don't you just keep both methods on the same class? I find this article a good and simple reference on BDD: https://dzone.com/articles/7-popular-unit-test-naming – Simon Mourier Feb 12 '17 at 09:41

3 Answers3

2

I've written dosens tests using different naming styles. Essentially, such test methods is hard to read due to long names, they exceed limit of symbols per line, often underscored names of methods go against naming conventions. Difficulties begin when you want to add "And" conditions or preconditions to your BDD scenarios, like "When Connector is initialized Should change status to Connected if Disconnected AND network is available AND argument1 is... AND argument2 is...". So you have to group your test cases in many classes, sub-folders etc. It increases time of development and support.

Alternative way in C# is writing tests like with JavaScript testing frameworks: Jasmine, Jest etc. For unit tests for classes and methods, I'd use Arrange/Act/Assert style, and BDD style for Feature/Story scenarios, but both styles can be used. In C# I use my Heleonix.Testing.NUnit library and write tests in AAA or BDD (GWT) styles:

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);
            });
        });
    }
}

For me important is that in few months later I can open such tests and clearly recall what was written there, and don't sit hours to understand what/how it tests.

1

In my case, first, I try to separate classes depending pre and post conditions, so I can group some behaviors and keep together the related things. For example, In your case, one precondition could be "Disconnected", so, you can prepare the "disconnected environment" using attributes like ClassInitialize, TestInitialize, TestCleanup, ClassCleanup, etc. (here some examples in MSDN)

And please, as the other developers has recommended, don't forget the naming conventions.

Hope this help, greetings.

Community
  • 1
  • 1
Sebastian Ferrari
  • 769
  • 1
  • 10
  • 18
0

Since test cases are totally independent of each other you must to use a static class to initialize those values, connections, etc that you will use for your test later. If you want to use individuals values and initiators yo must to declare them in your classes individually. I use for this nunit framework.

And by the way, you are in c#, use the name convention of .net developers...

AbelMorgan
  • 401
  • 1
  • 5
  • 16