Journey through software development

Testing

In the chapter about user stories, I explained that they should not contain every details for the feature. Yet the development team needs these details in order to provide value. The details are discussed between the whole team members and you write them down using acceptance tests.

An acceptance test represent a specific scenario for the given user story. They are written by the business analysts and the testers. The developers take no part in the writing since these tests are business focused and are not technical at all.

The acceptance tests are written during the development phase of the user story, this is mandatory since they must passed in order to validate the entire user story.

These tests must be kept and run each time a new build of the application is made. Because working on a new user story can have impacts on previous ones and you want to make sure that they are not broken. Therefore you should find a tool that allow you to run your whole acceptance tests suite automatically.

A common language

Earlier I said that the acceptance tests are written by non-technical people. This allow you to make them understandable by everyone, your whole team is able to read them.

To do so, you can use the gherkin language which has been created to answer this problematic. This language uses a Given-When-Then structure to define the steps of a scenario.

Let’s see an example with the following basic user story:

As a visitor, I want to login, in order to access the website.

I will now create two different acceptance tests with the gherkin syntax for this user story.

Given a visitor,When I log in with an existing account,Then I am able to access the website

Given a visitor,
When I log in with an undefined account,
Then I am not able to access the website

With these scenarios I get more details for the expected behavior of the application regarding the user story to develop. You can use acceptance tests to test incorrect behaviors.

One of the benefit of the gherkin language is that you can use it with several testing framework to automate your tests suite and then you can run them automatically. You can use Cucumber to do so, or Specflow with .NET, this will bring your acceptance tests to a whole new level.

Acceptance tests as proofs

Acceptance tests allow the team to prove that the user story is working as expected. You have a list of scenarios defining the behavior of the feature. And by using an automated tool, you can detect any regression quickly.

These tests are bound to the code written by the development team and therefore are up to date. If the code of the application is updated so are the tests or else it is likely they will no longer pass.

Acceptance tests as documentation

The other benefit I like about acceptance tests is the fact that they can provide documentation for the application. Every members of the team are able to read them to gain understanding of the expected behavior, very helpful for newcomers.

And since it is written by the business analysts, it uses the correct terms for the business domain. This should help the whole team to communicate by using the same vocabulary. It’s a step toward the use of an ubiquitous language for a Domain-driven design (DDD) approach.

Acceptance tests are complementary with the unit tests, they provide a good understanding of a feature and are readable by everyone. They bring the business analysts and the developers closer to each others by providing them a share ground. Using acceptance tests require a good collaboration in your whole team.

In my opinion having them is a big plus to avoid regression, like all automated tests they provide a good safety net for future developments.

I consider that Dependency Injection (DI) is a very helpful pattern, I love to use it in order to reduce the coupling in my code and it helps me when writing unit tests. But sometimes the code depends on objects that are difficult or impossible to mock.

The HttpContext class of the ASP .NET MVC framework is one example of this kind of object.

I just want to check that the view is not null but the test fails. I get a NullReferenceException because the HttpContext property of the Controller is null. This happens because there is no web context when executing the test and it makes sense since the execution occurred in a test context.

The first thing that comes to mind to fix this issue is to set the HttpContext property with a mock. But I cannot do that because this property is read only and thus I am not able to set it when doing the instantiation of the controller in the test method.

And if you need to mock the HttpContext class, you cannot because it is sealed. To avoid this you can use the HttpContextBase abstract class instead but in a test environment you will have to implement it in order to mock it and you don’t want to do this. Why? Because it’s a pain to do, you will have to provide implementation for everything, it’s like creating an entire web context just for the test. And in my case I just need the user languages.

So? What now? Do we give up testing our controllers? Absolutely not, it is possible to achieve our goal without too much complications. From the beginning I tried to mock the wrong thing. What I need is the user languages not the HttpContext, so let’s remove this dependency. I created the following interface with the data my code will use:

publicinterface IWebContext
{string[] UserLanguages {get;}}

And now I will inject this interface in my Controller and I will create a specific implementation that will use the HttpContext to retrieve the languages from the request:

My test is now passing! I removed the dependency between the test and the web context objects, I can now test the logic of my controller without having to set up an awful lot of mocks.

I encapsulated my specific logic inside an abstraction that is far easier to mock. This way I was able to reduced the coupling, I was also able to increase my code coverage and all of it without losing any behavior.

You can use this technique for other properties of the HttpContext like the user agent if you want to apply some logic on it and test it. Or also for static classes/methods (that you can maybe found in your legacy code).

I hope this will help you and as usual do not hesitate to leave a comment.

In the last part of my Dependency Injection article I introduced the term of “mocking”. This kind of test double can be really powerful. Yet in my example I had to create 2 new classes (my mocks) to be able to test my functionality in order to reduced coupling. Here is the code used by the tests:

I think that being able to write its own mocks is a great exercise to understand Oriented Object Programming (OOP) in a testing context. But in a larger application it is likely that you will have an enormous amount of them, it is a lot of code to maintain. This is why I will introduce a mocking framework name Moq.

I used this nuget package for a few months now and it offers a lot of helpful functionalities. But I think that it can be a bit complex to use at first when people are not familiar with the mocking technique. Let’s see how the previous code can be refactored when using Moq:

First thing to be aware of is that the manipulated object are Mock instances and not implementations of the interfaces. It is possible to access these implementations by using the Object property of the Mock to inject the dependencies to a client object (NotificationService in this case). I also used the Setup method of the MockRepository to return a new instance of User when the GetById method is called.

Moq also provides a Verify method to check whether or not a method has been called and how many times. This is the method I used in the test to validate my test scenarios. You can notice that I no longer used NFluent, because in this case I don’t need it. Yet it is possible to use NFluent with Moq for the tests, they work really well together.

Last but not least, Moq provides powerful methods to match arguments, in my example it is the It.IsAny method. With this I can tell my Mock to accept any value as parameter because I am not testing it in my unit tests since it is irrelevant in this testing context.

This is just a quick overview of the possibilities offered by Moq and I encouraged you to check this awesome mocking framework.

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.

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 :

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.

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 !

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.

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.

Software 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.