After doing a few spikes it’s time for some actual work on my task based Silverlight application. In my previous post I indicated that I wanted to work in a ATDD and TDD fashion. The reason that I wanted to do this has to do with the automated feedback you constantly g et when implementing your code and you eventually have a big set of automated tests which help prevent regression problems.
ATTD & TDD
If you know TDD then the phrase ‘Red, Green, Refactor’ will be very familiar to you. If you work with ATDD then you will have a very similar flow. I tried to indicate in the following picture how I see ATDD and TDD work together:
So you start by writing a failing acceptance test (or multiple if this is handled by a product owner together with a tester). Since I will be doing this on my own, I will write those test myself. I will use SpecFlow to write the acceptance tests since it integrates nicely in Visual Studio and in MSTest. Next I’ll create the code to make the acceptance tests run the actual tests. The failing acceptance test will describe the expected behavior of the piece of functionality I will be adding. Next I’ll implement the functionality in the familiar TDD fashion, so using the ‘Red, Green, Refactor’ principle. When eventually the acceptance test(s) succeed, I’ve got some new functionality in my application for which I know that it works, because I started out by describing the functionality using SpecFlow and those tests now pass. The beauty of this is that the automated tests also become a great way of preventing regression problems because every feature you added is also covered by automated tests.
I’ve got a test TFS server running, so I will be using this to run a CI build on every check-in. This build will compile all code, run the unit tests and I also want it to run all the acceptance tests. To be able to do this, I will have to make sure that all tests run very quickly. Whenever the tests take several minutes or longer to execute, it will be a show stopper, since history have proved that when tests take too long, they will get skipped and you loose the advantage that the tests give you. To keep the tests fast, they will have to run completely in-memory. I’ll get into the decisions that I make related to that in a future blog post.
With all the testing in place, there is the possibility to try out continuous deployment. Lately there is a lot talk about this and I really see advantages of it. To get this working, one of the mayor prerequisites is to have a good automated testing strategy. I described some of the testing behavior already, which is the unit tests and the acceptance tests. Next to that I also want to add automated UI tests to test the behavior of the actual user interface. These tests will not test any business rules or logic, since those are tested using the acceptance tests. Last category of tests which are relevant would be integration and performance tests. These kind of test could be the integration with a database, but also with other linked systems. I’ll probably will not use these kind of tests a lot (only for the integration between all the layers of the application, including the actual database), but whenever you’re facing a more distributed environment, including links to other systems, those links should also be tested using the automated integration and performance tests.
The following picture gives an idea of how I would like to have the automated deployment working.
So the automated build consists of several steps. Whenever the solutions compiles and all unit tests pass, it will be deployment to the development server. When also all the acceptance tests succeed, I want it to be deployed to the test environment. Then the automated UI tests will be run against the test environment. If they also pass, then the solution will be deployed to the acceptance environment, where the performance and integration tests will be run. Then the application should be ready for deployment to a production environment.
For my application, the deployment to the different environment will not be that different, since I don’t have several different servers to deploy the application to. However, in a enterprise scenario, there will be a lot more challenges to get your deployment completely automated.