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?
Naming your tests The name of your test should consist of three parts: The name of the method being tested. The scenario under which it's being tested. The expected behavior when the scenario is invoked.
Unit tests are usually written as a separate code in a different file, and there could be different naming conventions that you could follow. You could either write the name of the unit test file as the name of the code/unit + test separated by an underscore or test + name of the code/unit separated by an underscore.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With