Koen about .Net

September 22, 2011

Testing and deployment

Filed under: Deployment, Testing — Tags: , , , — koenwillemse @ 23:55

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.


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.

Continuous integration

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.

Continuous deployment

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.

Build process

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.


July 25, 2011

/temp/global.asax(1,0): error ASPPARSE: Could not load type

Filed under: Deployment — Tags: , , — koenwillemse @ 10:00

Since it’s my vacation I have some more time to work on my home project. I’m creating a web shop in ASP.NET MVC 3 and I’ve got a test TFS server running. I use this project to get some hands on experience in ASP.NET MVC 3 since the project I’m working on is still Webforms but I see more future in MVC. I’ve implemented a basic site where you get a view a list of products and some more details about them.

So my next step is that I want a CI build on the TFS server. I configured it and it seems pretty easy, but than I got the following error in my CI build (but I did not get it when building locally): “/temp/global.asax(1,0): error ASPPARSE: Could not load type …..”.

Eventually I found the problem. In the log file I saw the call to aspnet_compile, which is triggered because I set the property to build the views (MvcBuildViews). The problem is with the path which is supplied to the aspnet_compile command. I eventually fixed it by adding a condition to the AspNetCompiler build task in my web application project file. It now looks like this:

 <Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
     <AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)" Condition="'$(IsDesktopBuild)' == 'true'" />
     <AspNetCompiler VirtualPath="temp" PhysicalPath="$(OutDir)\_PublishedWebsites\$(ProjectName)" Condition="'$(IsDesktopBuild)' == ''" />

To get this working I defined a build property IsDektopBuild which I set to true in the Debug build configuration, which is the configuration I’ll build locally. I also defined a Debug CI configuration which does not contain this build property. Now I’ve got my CI build up and running. Next step is to add some specflow acceptance tests to see if they help me with controlling the quality of the code.

March 22, 2011

GAC using the windows explorer gotcha

Filed under: Deployment — Tags: — koenwillemse @ 21:29

A few days ago a colleague of mine was deploying a patch for an application on servers. All assemblies are located in the GAC, so those assemblies had to be updated. The application runs on several frontend servers, so the patch had to be deployed to every server. The following picture show’s how this was done.


The assemblies were copied to each of the windows explorers using drop & drop. However, the issue was still available on most of the servers. An application pool recycle did not help, even an IIS reset did not fix the problems.

Now what was the problem. The files were copied to the others servers using the windows explorer, which were opened like this: \\SERVER\c$\windows\assembly. The problem however was that this is a shell extension which make the GAC looks nice in the windows explorer. It does not show the actual directory structure. If you check the GAC using a dos prompt it looks more like this:


This windows shell extension however was the cause of the unexpected behavior. You would expect \\SERVER\c$\windows\assembly to be pointing to the GAC of the remote server, however, this is not the case. It just displays the contents of the local assembly cache again. One of the other colleagues ran into this same issue once before, so he already knew about this gotcha and could point to the mistake.

Another lesson learned. When you you are using the GAC (is it really, really necessary?) make sure that you install the assemblies on the machine itself, or use a tool which you’ve made sure of that you can use it to install assemblies in the GAC on a remote server.

Blog at WordPress.com.

%d bloggers like this: