Behavior-driven development with NUnit
How can I make my unit testing with NUnit feel more like behavior-driven development?
I work with .NET and C#. I like to test my own code. I try to do TDD and BDD. My favorite framework for testing is Machine.Specifications.
I like Given
, When
, Then
over Arrange
, Act
, Assert
.
I like Should
instead of Assert
.
At work, we use:
Okay, so how can I make NUnit do Given, When, Then and feel more BDD? With as little effort as possible? I want to read the result in the test runner in as fluent English as possible. I do not want to write my own framework.
My solution:
- Use folders prefixed with
Given_
to group tests for a specific subject and context - Use classes prefixed with
When_
to group specific actions to be tested - Use test case methods prefixed with
Should_
to describe the behavior - Use a Should library for the assertions
A folder prefixed with Given_
will generate a namespace prefixed with Given_
. The name of the folder can end with the name of the subject / class under test. Given_Foo
. Or it can end in something that describes the context for the subject in a more specific way. Given_Foo_with_bar
.
The name of the class can end with the name of the method / property / member to be tested. When_GetFoo
. Or it can end in something that describes the action in a more fluent language. When_getting_the_foo
.
The name of the test case methods should describe the behavior of the code that is tested. Should_return_foo_if_bar_is_configured
. Create as many case methods as needed to describe all the behaviors of the code under test. Ideally each test case method should only contain a single assertion. It will make it easier to understand why tests fail.
Use Snake_case
as naming convention for folders, classes and methods.
Example code
You can get the example code at https://github.com/hlaueriksson/ConductOfCode
The subject:
The tests:
The solution explorer:
The unit test explorer:
The unit test sessions:
If you use ReSharper as test runner you can use the Group by: Projects and Namespaces option to get the output as seen above.