Agile in enterprise legacy software

TDD

Setting up NUnit 3 in Visual Studio is a simple task, but if you don’t know what you need to do, there are a few ways you can easily get stuck. To help you avoid loosing time I put together all the steps you need to follow to get you up and running.

The steps to setup Visual Studio are the following:

Open Visual Studio 2012

In the menu bar go to TOOLS > Extensions and Updates

On the sidebar select Online and then type nunit on the search bar

Install NUnit Templates for Visual Studio

Install NUnit3 Test Adapter

Restart

OK, now your system is ready. Let’s add a test project to your solution

Open your solution

In the menu bar go to FILE > Add > New Project…

On the sidebar select Installed > Visual C# > Test

On the main panel select NUnit 3 Unit Test Project and choose a proper name (like UnitTests)

In the new project you wil find a file named TestClass.cs, open it

In the menu bar go to TEST > Run > All Tests

The last step will build and run all the tests in your solution (1 for now). A window with the test results should popup, otherwise go to TEST > Windows > Test Explorer to bring it up.

The test should pass and be marked as green. Otherwise write a comment to this post and I’ll help you solve this problem.

Like this:

I few months ago my brother did a couple of tech talk at work introducing TDD and explaining its benefits (and those talks then became posts in this blog). Then a few weeks later we asked our colleagues, if they hadn’t started writing unit test, why was that so.

These are the most common responses to why my colleagues didn’t write tests:

I don’t have time to write tests

I don’t know how to test

I know I should but I’m too lazy

There’s no reason to dismiss any of those reasons and in that meeting we gave each of them a response (the best we could come up with). Following you can find my summary of each response:

I don’t have time to write tests

This one is tough, it would be simple to say that the programmer is lazy and should just do it, but anyone familiar with the workload of programmers and the improvement curve will know what is happening.

We’ll talk about the improvement curve and all its causes in a future episode, but to summarize, every time you try to do something new, like improving on your workflow there will be inefficiencies, this mean that when you adopt a new methodology you will be slower and less productive than you where before. This causes those that don’t expect this to happen to get frustrated and drop the improvement before they start reaping its benefits.

You may hear about TDD and all its benefits, you may hear that it makes you go faster, and since you are overloaded with work you think “Hey I could use that!”. But when you try it and you find out you have to write twice as much code, you drop it in 0.2 seconds (then you write a blog post about why TDD is dead or why it doesn’t work for you).

To fix this you have to attack the root cause, the programmer is overloaded and has no time to sharpen the saw, an organization that wants his developers to practice TDD has to invest in this improvement curve, and reduce the workload till they learn this new methodology, only then they will be able to be more productive (that’s why it’s called investment! you get disproportionate results but it takes some upfront costs).

If the company doesn’t want to invest in this and the programmer is determined to improve his abilities then he’s the one that needs to make and investment, going the extra mile out of work till he can go back to being productive. I know, I know, this isn’t right, is the company that will reap most of the benefits so they should be investing, but this is the real world and we can’t always wait for the rest of the world to act rational and do the right thing. If the company won’t do it, you can improve on you own.

I don’t know how to test

This is similar to the previous reason, in that it takes concerned effort on your part to overcome. Finding out what does it mean to TDD is easy. Setting up your environment to test takes about 10 minutes, and you can watch a couple of videos introducing unit test, but then you have to actually write your tests.

We already went in great depth into the process but the gist of it is that you should write the test that forces you to write the code you wanted to write anyway. (you can re-read that, I’ll wait)

After that, you should write test that explore the boundaries of your problem (like passing a null, or an empty list).

Then you can continue with some simple cases and grow from there.

This is how you start, but you need to realize that you will be a noob TDDer. How much have you been programming (5 years? 15 years? more?), how much have you been TDDing? 5 minutes? 15 days?

Your first test will suck. They will be hard to follow, slow, break a lot and be full of duplication. Every time you change something you will need to fix most of them.

But this is not how TDD works in the real world, you shouldn’t give up on it just because you suck at it. It’s like changing your keyboard layout from QWERTY to DVORAK, even tough you know how to program and you know what keys you want to type, you will be slow and make a lot of mistakes, but then you will get used to it. You will learn new techniques, you will write better test, cleaner test. Only at this point unit tests will be a net positive gain for you, and once you reach this point, there’s no going back.

I know I should try but I’m too lazy

I’m not making this up, this is a real reason I was given for not writing unit test. The problem with this reason is that it is not the real one. This programmer most likely isn’t lazy, the problem is that he feels overwhelmed by the amount of work that it will mean to go full TDD, so he keeps procrastinating.

We saw in the two previous section that TDDing is simple but not easy. Specially if you are working in a legacy code base, it will be an uphill battle.

The only advise I can give you is this:

Start somewhere, do a small step and then keep improving.

Not every project is perfect for starting with TDD, not every CR is perfect for starting with TDD, but some of them are and of them most are Just OK.

You need to start somewhere, first setup your environment and do a couple of tutorials. Then choose a project where you tend to have CRs that add functionality (instead of changing existing stuff). Now setup a test project in that solution and then write a small unit test for a small piece of functionality. No need to TDD it, no need to do all of it. Just start somewhere and then… never stop improving.

Like this:

Well, this article will be quite short, because when you isolate yourself from sharepoint, or any other hard to test framework, you can write test the same way you would do in any other environment. Now it doesn’t matter if you are a sharepoint developer or a mvc developer, you have plain old business object everywhere and any boundary can be replaced with a test double.

Let’s see a concrete example of what I’m saying. Picking a recent example from a project I’m working on let’s implement the following requirement:

Given that a user can be in multiple groups, and that a company is related to 2 groups, find all the companies that are related to the current user

To do this we need two data sources:

One provides the list of groups the current user is in

The other provides the list of all the companies and its related groups

This data will be provided by two different repositories with the following interfaces:

This obviously fails, it doesn’t even compile. Let’s pretend we have the No___Repository stubs (if you have trouble implementing them ask in the comments). Let’s write the simplest manager that can pass that test

Given the new test the simplest manager can return all the companies from the repository without filter, so we need to test a negative result. The following test checks that we don’t return any company given a set of unrelated groups.

As you can see we have implemented a (simple) bit of business logic that in production will be dealing with objects coming from sharepoint, but that thanks to the layer of repositories, we were able to isolate and build using TDD

Like this:

In the last post we talked about Mock Objects and what are the difference between them and Spies. We have almost completed our journey through the all the different types of Test Doubles, in this post we are going to introduce the last one: the Fake Object.

There are sometimes where the need of isolation comes from the fact that your tests are running too slow because you are accessing services that need to read or write to the disk or make a network call. In this cases, the best way to improve the test is to use a Test Double that only mimics the same functionality as the service you are currently using. Of course, you need a way to swap the objects during the test, but the techniques to be sure that you can inject your Test Doubles are going to be discussed in a future post.

Let’s make an example

Let’s pretend that you are developing a method that prepares different kind of SMS messages and then sends them using a service that returns an id for the message so you can query it back and check the processing status of the message. The service also stores all sent messages in a queue for later use and the queue has to be manually emptied.

Maybe we can configure the service to avoid sending the SMS message while we are in test, but we still have to wait for the whole round trip to happen, causing a sensible delay in getting the results from the test, and if we have to run lot’s of tests those delays will start to add up. After a while, you end up with tests that take you minutes to run and you stop running them often.

Uncle Bob always talks about how he and his team developed FitNesse without needing a database. But how do they tested the functionalities that dealt with persistent data? well, they isolated the persistence layer and they faked it with an in-memory representation of it.

This is what Fake Objects are for: you swap slow external dependencies of your SUT with the Fake Object and you use them in your test as if they were real.

Can It Be THAT Simple?

Well, it depends. The problem is that Fake Object must have the same functionality as the real one, at least all the functionality the SUT uses, but implemented in a simpler way; for example, our fake SMS service could be implemented like this:

Internally the fake service retains a dictionary of key-value pairs where it saves all the messages that the method Send receives. Even though it’s pretty simple, this implementation is powerful because we can trust that the SUT will believe that it’s using the SmsService that makes the HTTP calls and all that, but in fact, all the operations stay in the memory of the running process, so it’s waaay faster.

Could you give an example of a Fake Object recently used?

In one recent project we used Effort to isolate us from the database.

We were using Entity Framework code first to create the database and then access it, and we discovered this Effort that was an Entity Framework Provider: it implemented the same interfaces and functionality of EF but it did it in an in-memory database so we didn’t have to worry about cleaning the DB in the TearDown phase of our test, we simply destroyed it and created it again, and it was super-fast.

What to do next?

Find a simple functionality on the code you are maintaining that uses an external service and start implementing a fake object based on that functionality; then use it in a test suite to cover your method. If the service is huge and with lots of functionality, don’t get overwhelmed, start small, just a simple implementation that helps you test the method you decided to cover.

Like this:

By using Test Spies we can capture all the indirect outputs of our software to check that it is working correctly. Often times, making the assertions for all the outputs in the testing function leads to lot’s of duplicated code that after a while starts to hinder the purpose of the tests. Sometimes, we would like to do our assertions in the context of the running code and not in the context of the test suite.

Think for example that one of the indirect outputs of your SUT is a disposable object. How you verify that it is in the correct state when it get’s injected to your dependency if it gets destroyed as soon as the method you are testing exits?

Let’s try to understand this problem with an example: let’s say we want to verify that the method CreateAndConfigureDisposable passes the correct object to DependencyObject:

this test looks correct, we configure the SUT, we pass in the TestSpy, we exercise the method we want to test and the we do the assertions. The problem is that as soon as we exit the using block inside LoadStreamAndPosition the disposable object gets, well, disposed and trying to access its state will cause an ObjectDisposedException.

The best way to test this code is to do the assertions in the context of the running code that we want to test. This is where Mock Objects come into play: you put all the assertions inside the Test Double’s method that receives the indirect output.

With this new Test Double the assertions run inside the using block while the DisposableObject still exists. By introducing the Mock Object the test logic flow changes quite a bit, the assertion step is missing and is substituted by a step for configuring the Test Double.

So… what’s the big difference then between Spy Objects and Mock Objects

With a Mock Object you mock an object and with a Spy you spy on it 😉

Just kidding, I read a similar explanation while researching this topic.

The real explanation is that spies are used to collect information about the behavior of the code and then do all the assertions in the testing context while mocks may collect some information (like how many times a method gets called) but all the assertion are done in the context of the running code.

This distinction is important for a few reasons of which this are the two most important in my opinion:Some indirect outputs may not exists outside of the SUT context;

Some indirect outputs may not exists outside of the SUT context;

The code you are trying to test may swallow the exceptions generated by the assertions;

The first one is a case when you are forced to use a mock object because you need to do the assertions while the code is still running; we have already discussed this problem so let’s check the second one.

In this case, we instantiate a non-disposable object that will live after the method LoadStreamAndPosition exists; We still could use a Mock Object if it wasn’t for the Pokémon Exception Handling that is going to catch the exceptions generated by the testing framework hiding all the failing assertions and making us think that the test run correctly.

Like this:

By using Dummy Objects and Test Stubs, we are able to control the inputs of the System Under Test to exercise every part of it during our tests. But of course, not every method that we want to test is going to have one just output or is going to change only the internals of the class that is under test. Most methods have side effects and are going to call other libraries or methods of other objects and we want to be sure that those method calls happen the right amount of times and with the correct parameters.

Let’s suppose we have a method that prepares an invoice when someone check’s out at a hotel. That method is part of a Registration class that takes in a Room and a Guest object and the BookingInformation with all the information about the booking period, like check-in and check-out dates number of people etc.

Then, when the method checkout gets called, it prepares a dictionary of strings and passes it to a library that prints the invoice. This dictionary an indirect output of our method and we want to check if it’s properly set, while also avoiding calling the real method that sends the file to the printer.

We notice that the a printer object is passed in the constructor of the class and that it implements the interface IPrinter. That means we could pass a special implementation of that interface and log the calls and the inputs passed to its methods.

In particular we want to capture the dictionary that is passed to the print method and expose it as a public field to do the assertions. We could also check that we are calling the method just once, or that we are not calling it for when an error occurs.

As you can see, in this test we pass to the Registration constructor the Room, the Guest and the BookingInformation objects properly configured and then we pass also a our Test Double that will get called and will record it’s inputs. After the method CheckOut gets called we have complete access to the information that it prepares and then passes over to the Print method. The SUT (System Under Test) doesn’t know that it’s talking to a test double so if the test passes we are sure that the method will work correctly in production when it will pass the dictionary to the object that will in fact print the invoice.

It’s not always that easy!

Sure, if you are working with some legacy code, chances are that your class doesn’t have the dependency that receives the indirect output nicely injected in the constructor. You could have something like this:

How could you test the indirect output now?

Depending on the code base and how confident you are in refactoring it you could try different strategies like extracting the ugly part of your code to a protected method and then extend the class with a special that you use class just for testing. Another way to address this problem is to isolate your code wrapping the external dependency in a class that you can override like this:

Like this:

In our last post we explored how to use Dummy Objects in order to test our code when we are dealing with objects that are difficult to create. One important restriction on the usage of this kind of test double is that we have to avoid touching the dummy object during our tests. We can easily check that LoadInvoicesByDate throws when from is higher that threshold:

But what happens if we have to pass the first ‘if’ and check that the text of WarningMessage is updated when count equals zero?

In this case the variable count is said to be an indirect input of the code we want to test and in order to control it’s value we need to instantiate a special version of dbFactory that we have under our control. Of course we don’t want to use the real instance of DbFactory because who knows the state of the database… we could never get a count that equals 0. So in our test we are going to need a Test Double called, you guessed it, Test Stub.

The Test Stub will provide you with the indirect input you need no matter what how it gets called. Let’s explain with a test that checks that the WarningMessage field is set when dbFactory.CountInvoices returns zero:

What’s happening here?

First I create a new class that implements IDbFactory and set the return value of CountInvoices to zero, which is exactly the return value we want to have. With this test double we are forcing our code through a path that could have been difficult to simulate with the real implementation.

Moreover, we can generalize a bit our dummy class and set the wanted return values in the tests

Like this:

Let’s pretend we want to add a method to a class. We, of course, are going implement the method using TDD but we have a problem, to create an instance of the class we need to pass in a super-difficult-to-build object. We are sure that our implementation won’t touch this object in any way, like if it smelled funny, but the class needs an’instance of that object. What can we do?

All the horrible code needed to instantiate a working instance of dbFacade is going to obscure the real purpose of the test and make the tests fragile because if something in the procedure of constructing the object changes, a lot of tests are going to fail.

But, do we really need a working instance of DbFacade? we said earlier that we are not going to use it in any way in our new method, so for what we know we could completely avoid it in our tests and just pass a null to the constructor of InvoiceFormatter .

If the constructor of InvoiceFormatter doen’t check for nulls this is a perfectly acceptable strategy and the great thing is that it cleans up the test function. Of course, if we are dealing with a constructor that doens’t accept passing nulls, we have to try to find a different solution.

One solution can be to check if we can instantiate a DbFactory in a simpler way, say with the default constructor and without setting any properties. This won’t result in a working instance of the class but it will be enought for our tests.

Another use of a dummy object is when we are covering a method already implemented and we only need to provide the values for the path that we want to test. For example the method LoadInvoicesByDate receives an IDbFactory

If we are going to test that a DateOverThresholdException is thrown when from is higher than threshold we are free to pass a null as an argument for dbFactory.

To summarize, Dummies are used to put the code that you are going to test in a testable condition whenever you don’t need to read any information form them or call their functions. For that you have stubs, spies, mocks and fakes…

Like this:

Setting up NUnit 3 in Visual Studio is a simple task, but if you don’t know what you need to do, there are a few ways you can easily get stuck. To help you avoid loosing time I put together all the steps you need to follow to get you up and running.

The steps to setup Visual Studio are the following:

Open Visual Studio 2013

In the menu bar go to TOOLS > Extensions and Updates

On the sidebar select Online and then type nunit on the search bar

Install NUnit Templates for Visual Studio

Install NUnit3 Test Adapter

Restart

OK, now your system is ready. Let’s add a test project to your solution

Open your solution

In the menu bar go to FILE > Add > New Project…

On the sidebar select Installed > Visual C# > Test

On the main panel select NUnit 3 Unit Test Project and choose a proper name (like UnitTests)

In the new project you wil find a file named TestClass.cs, open it

In the menu bar go to TEST > Run > All Tests

The last step will build and run all the tests in your solution (1 for now). A window with the test results should popup, otherwise go to TEST > Windows > Test Explorer to bring it up.

The test should pass and be marked as green. Otherwise write a comment to this post and I’ll help you solve this problem.

Like this:

One common objection that I get while explaining TDD to my colleagues is that they deal with objects that are too complex to be tested in an automated suite. They either have methods that are too complex (too many interactions with other libraries or classes) or objects too difficult to instantiate (constructors that call to databases or that need to set up a huge graph of dependent objects).

Sometimes the objection is that the program uses some method that reaches to a database or an external service to read (or worse to persist) some information. This normally happens when the developer is working with some legacy code that doesn’t have any real separation between what is the business logic of the software product and what are the external resources that it uses (databases, web services, etc).

Of course, writing automated tests to verify code that calls to a database to save some information can be painful for several reasons:

Databases are slow: the test would run slow and you will not be willing to run them often;

After every test you have to clean the database: this is important because tests should be atomic a reproducible, if the database contains old data, the tests could produce false results. Of course this result in even slower tests;

Your software may be using a database (or service) shared between different applications or different developers: if you are working with a shared database your tests may not be reproducible, you cannot clean the records because you could be deleting other people data. Sharing a database between developers makes your code untestable without some sort of separation from it;

To be able to test your code you have to be isolated from the parts that are difficult to test. By using other objects with the same interface as the one that we want to avoid using.

We have all seen videos of the crash test done on cars to certify their safety. Obviously it wouldn’t be acceptable to do the crash tests with real humans (luckily the time when living humans were used to test katanas is long gone) so they use a dummy that is loaded with sensors to measure the effects that the crash would have on real people.

The software counterpart of these dummies are called Test Doubles and are used in the same fashion: during the tests they are put in those places where it wouldn’t be acceptable or easy to use real production objects. We use Test Doubles to put the software in the condition that we want to test.

The method Contains uses an instance of the class NetworkHandler to load a list of strings from somewhere; this class is defined like this:

public class NetworkHandler
{
public virtual List<string> GetAsList(string uri)
{
// some code that connects to the uri passed as parameter
// and then parses the result and returns a List of strings
}
}

Using the real NetworkHandler there’s no easy way to test that our method returns false when a WebException gets thrown by the method GetAsList. The best way to test this behaviour is to replace in our tests the instance of NetworkHandler with a test double which only purpose is to throw a WebException when the method GetAsList gets called.

Types of Test Doubles

The Test Doubles are divided into different categories depending on their usage in the testing suite. Returning to our dummy analogy, a mannequin is a different Double than a fully featured Crash Dummy, both have the resemblance of a human but they are used in totally different scenarios. In the software world we have: