Write clean tests with NFluent

nfluent-logo
NFluent logo

I believe in automated testing. Not only to check that my program works but although as specifications and documentation for my application. When an acceptance test passed you know that the feature is working as it should. Automated tests are also a very good way to document your code and your application, because if the test passed it means that the functionnality is working. And if this functionnality is updated so is the test otherwise it will fail : it is up to date !

At a code level a test let you know how to use the functions/classes you can access and what the return value will be. It is useful when using an external library in your own application. Well, this is a lot of responsibility for a test, so it has to be clear, concise and most of all understandable when read. This is not an easy task but there are some tools that can help you, one of them is NFluent.

Smooth your .NET TDD experience with NFluent! NFluent is an ergonomic assertion library which aims to fluent your .NET TDD experience (based on simple Check.That() assertion statements). NFluent aims your tests to be fluent to write (with a super-duper-happy ‘dot’ auto-completion experience), fluent to read (i.e. as close as possible to plain English. – NFluent team on GitHub.

I used this .NET library for a few months now and I must admit that I just love it ! I just can’t see myself writing unit tests without it, they are easier to write and easier to read. There are a lot of built-in functions based on the type of the value that is checked :

[TestClass]
public class NFluentExamples
{
    [TestMethod]
    public void NFluent_Integer_Examples()
    {
        var sum = Calculator.Add(5, 9);
        Check.That(sum).IsEqualTo(14);
        Check.That(sum).IsNotZero();
        Check.That(sum).IsPositive();
        Check.That(sum).IsLessThan(20);
        Check.That(sum).IsGreaterThan(10);
    }
 
    [TestMethod]
    public void NFluent_String_Examples()
    {
        const string name = "John Doe";
        Check.That(name).IsNotEmpty();
        Check.That(name).IsNotEqualTo("Jane Doe");
        Check.That(name).Contains("John", "Doe");
    }
}

It is also possible to chain the checks the following way  :

int? one = 1;
Check.That(one).HasAValue().Which.IsPositive().And.IsEqualTo(1);

In my last blog post I wrote about exception testing, this is how it is done with NFluent :

[TestMethod]
public void NFluentTest()
{
    Check.ThatCode(() => ClassToTest.IsAQuestion(null)).Throws<NullReferenceException>();
}

You can find a lot more relevant examples on the project website.

Beside making you write cleaner and more readable tests, @NFluent is free, easy to install, open-source and comptatible with your favorite testing frameworks. It is hard to find an excuse for not using it !

NFluent can help you having meaningful tests that become documentation for your application and your public APIs.

See you next time !

Coding Tips – Testing exceptions

coding-tip

Welcome to my new series entitled “Coding Tips”. The purpose of this new collection of articles is to share some tips related to programming I came across during my journey. These tips helped me and I still use some of them and maybe it can help you too.

If you are the same kind of developer as I am, you certainly like to write unit tests and a lot of them. You certainly also want to test every aspect of your code, including exceptions. But you might wonder if there is an easy way to test them, and of course there is !

Given the following (only for testing purpose) sample of code in C# :

public static class ClassToTest
{
    public static bool IsAQuestion(string toTest)
    {
        return toTest.EndsWith("?");
    }
}

The following call will throw a NullReferenceException :

ClassToTest.IsAQuestion(null);

So ? How to test this assertion ? Here is a common solution :

[TestMethod]
public void TryCatchTest()
{
    try
    {
        ClassToTest.IsAQuestion(null);
    }
    catch (NullReferenceException)
    {
        return;
    }
    Assert.Fail();
}

This test will pass only if a NullReferenceException is catched, otherwise it fails.

This solution looks a bit “heavy” for just testing an exception and this is why there is another solution much “lighter” than can be used. Please welcome the ExpectedExceptionAttribute :

[TestMethod]
[ExpectedException(typeof(NullReferenceException))]
public void AttributeTest()
{
    ClassToTest.IsAQuestion(null);
}

Yes, this is it, nothing more ! You can now test the exceptions with a single line of code. The .NET framework is full of helpful classes, the ExpectedExceptionAttribute is one of them but sometimes finding them is harder than using them.

If you use a different testing framework than Microsoft.VisualStudio.QualityTools.UnitTestFramework, it is likely that there is also a functionality allowing you to easily check the exceptions.

I hope you will like this new “Coding Tips” series, do not hesitate to share your ideas in order to improve it.

See you next time !

The Clean Coder : Testing Strategies

Test Pyramid
The test automation pyramid

Professional developers test their application but not only with some unit tests and a few acceptance tests. These are components of a testing strategy.

Your company might have a Quality Assurance (QA) department or quality analysts (QAs) in each development team to track bugs before a release. As programmer our role is to let them find nothing, otherwise it means that in a way we failed somewhere during the development phase. Of course this goal is almost impossible to achieve every time but that is not an excuse for letting bugs slip through the code.

Am I saying that the developers and the QAs relationship is adversarial ? Absolutely not, they are parts of the same team. First, QAs are “specifiers”. It means that they are able to translate business requirements into test cases to let the programmers know how the system should behave (more in chapter Acceptance Testing). Secondly QAs are “characterizers”. They have the discipline to track incorrect behavior and to reproduce them in order to give proper feedback to development team and to the business.

Having a full test automation policy is a feature of professional development teams which is not only composed by unit tests and acceptance tests. The test automation pyramid figure show every test types and their proportion.

Unit tests are written by the programmers for the programmers to ensure that the code is working at the deepest/lowest level. They should execute in milliseconds and target a 100% code coverage (at least 90%).

Component tests are a part of the acceptance tests and check the behavior of individual component. A component encapsulate a specific set of business rules. These kind of tests should be very quick as well because they are decoupled from the other components and should cover about half the system.

Integration tests are required to check the communication between components in order to verify that the “plumbing” has been done correctly. They ensure that the architectural structure of the system is correct. About 20% of the system is covered by integration tests.

System tests are executed at the highest level of the system, from the UI to check the whole application and its construction (load tests are in this category for instance). They check about 10% of the system.

Manual/exploratory tests are done by humans to explore the application for unexpected behaviors. They need the human creativity to hunt possible hidden bugs.

An effective testing strategy is required to develop reliable applications. This comes from the relationship between QAs and programmers and from a solid automated test suite.

See you next time for Time Management !

The Clean Coder : Acceptance Testing

Check ListSoftware craftsman do not only test their code through unit testing they also have to develop an application that meets the requirements defined by the business. Even a well coded, fully tested software can be worthless if it doesn’t have the functionalities wanted by the end users. So, how do you make sure of that ? You do more tests, Acceptance Tests this time ! You write this type of test to validate a User Story. This way you are able to match the functionalities of your application with the desired features. They are formal requirements documents that specify how the system should behave from the business point of view. The audience is the business and the programmers.

For example you might have acceptance tests to check that the login feature is working correctly for each scenario (no input in form, invalid input, correct input etc…).

As acceptance tests are requirements they have to be very specific and written in a language that is understood by the business and by the developers. To do so there are several format to specify the user stories.

“As a <role>, I want <goal/desire> so that <benefit>”

This is a typical user story format. But sometimes it can be too restricted for a proper acceptance test. In that case you can use the Given-When-Then (GWT) pattern especially with the Gherkin language. This Business Readable Domain Specific Language is easy to understand and can be converted to actual tests for the programmers with a tool called Cucumber. If you are working with the Microsoft .NET framework you can use SpecFlow which brings Gherkin and Cucumber into Visual Studio.

Acceptance tests are not unit tests, they allow you to document your software behavior and to match the business requirements. They are proof that the program works technically and functionally.

See you next time for Testing Strategies !

The Clean Coder : Test Driven Development

Red Green RefactorI’m sure you have already heard of Test Driven Development or TDD since it has been introduced in the Extreme Programming (XP) methodology in the late 90’s by Kent Beck. This development process relies on a 3 parts cycle : Red – Green – Refactor. You start by writing a unit test that fails (red) because the tested code does not yet exist. After you write the code for your application that makes the test pass (green) and then you can refactor your code to remove code duplication and others code smells.

In “The Clean Coder” Robert Martin defines 3 laws of TDD :

  1. “You are not allowed to write any production code until you have first written a failing unit test.”
  2. “You are not allowed to write more of a unit test than is sufficient to fail – and not compiling is failing.”
  3. “You are not allowed to write more production code that is sufficient to pass the currently failing unit test.”

By following these 3 laws you are locked into a cycle that force you to test every aspect of your code and to fully follow the TDD principles.

Having a full test suite allows you to have the control over the behavior of your application and to avoid any regression after a bug fix or a refactor. The other benefit of having tests is that it provides a detailed documentation for every piece of your program. Each test gives information about the behavior and the expected result of the feature it tests in a given context.

I have to admit that, when writing these lines, I don’t use TDD. Why ? I don’t really have any excuse for not doing it. But I believe in the fact that TDD is a helpful process. I have to practice it in order to absorb it into my everyday development process.

See you next time for Practicing !