Continuous Integration
TypeMock 5.3.5 – WasCalledWithArguments
Sep 21st
I normally do not blog bile by reposting another sites news, but this news is rather importnat in regards to TDD with Isolator.
I use Rhino Mocks 80% of the time for mocking, but that last 20% is Isolator. Why 20% – this is the real tough stuff to test. SharePoint, Silverlight, Tightly Coupled Legacy code (that I do not have source to), etc. In Rhino I’ve been able to assert with arguments for quite awhile now. Isolator did not fully support this, they do now!
See this release notice here: http://blog.typemock.com/2009/09/typemock-isolator-535-is-out.html
What does this mean? It means that you can assert whether or not arguments made to a particular mocked object were what you expect them to be. Perpaps. If they are not, then your test should fail. If your method performs various manipulations through various other calls, you can ensure that through the execution stack of your app, your calls are being made with what you expect them to be. If not, tests fail.
Fail fast is the name of the game and Isolator just stepped up theirs. Good stuff guys.
Code Review Tip: Using the ‘warning’ Preprocessor Directive
May 26th
Communicating changes back to a source developer during a remote code review (when the review is done while the developer is not near) can be very difficult. Emailing the thoughts/changes/errors is an option, but this option has “no teeth”. These items are likely to get missed and most likely will not get addressed. My preferred method is to use the #warning preprocessor directive in C#.
The Warning Preprocessor Directive
I’ll add a warning directive with some text defining what the issue is. I’ll then submit the code and then re-assign the feature ticket to the developer who’s code I reviewed.
Here’s what I’m talking about:
Now the main benefit to this approach is that if I have warnings as errors turned on I will get an error during compilation. If I do not, I’ll get a warning. My build system reports the warnings as well as errors so I’m able to keep track of what needs to be fixed still.
Here’s a screen shot of the warning that shows up from this code above:
I’m now able to keep track of the warnings/edits and also make the visible via the build system on the build server as well as each developers machine. Collective code ownership, baby.
Other Tips
- Create a nomenclature.
- Example: Include the ticket number or check in number that this original fix was in question of. Such as : FIX [ CheckIn-#OfCheckIn] – Comments such as …
- FIX [CheckIn - 1499]: Don’t hardcode UID/PW Combos …
- Have your build break on errors. This will cause you to fail fast.
- If the offense is a system halting issue, use the error preprocessor directive. This works the same as the warning, but throws a compilation error. Fast Failure, baby.
NCover Hangs on Configuring Profiler…
Apr 22nd
Our main build broke today. We have about 53 projects in our solution (yes, its huge) and all of a sudden … pow … NAnt started timing out. Upon further investigation I noticed that the build was timing out at the following instance:
Coverage Log: Coverage.Log
Waiting for profiled application to connect…Connected
Configuring Profiler…
It would hang until I killed it or until NAnt timed out (600 seconds/10 Mins). If I killed it, I received an “Object not set to an instance of object” exception.
Digging around some more I found out that others had this very same problem.
Just as they were, I was using NCover 1.5.8, the last free version. I followed suit as them, and used our NCover 2 license for our build server and everything started working again.
It seems that NCover has a critical mass that it reaches and then its like a game of Tumba. It could only handle so much and then it just fell over.
If you’re having this issue, just run NCover 2.
Finding App_Data Programmatically
Apr 14th
While writing some code I needed to be able to access the the App_Data directory in my ASPNET MVC app. Doing this usually involves a Server.MapPath, but this wont work for my unit test.
Here’s how you can get around it:
var appDataPath = (string)AppDomain.CurrentDomain.GetData("DataDirectory") ?? AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
Now I have my data directory for the test as well as during execution of the ASPNET MVC app.
During unit test execution it will be in testing directory while at runtime it will be in the ASPNET App_Data directory.
An Exercise in Managing the Measurements
Feb 19th
I’m a firm believer in the phrase:
“What gets measured gets managed.”
When it comes to unit testing code coverage is something we can use to measure how much of our code is under test. By no means does this mean that the code that is under test is actually covered by valid tests that mean anything to the product at hand – it just means at some point during the test execution a path of test code passes through the given line of code. However, it is still important to know what assemblies and code paths are not covered during the testing process so teams can analyze areas that might need to be covered a bit more.
When I set up a CC.NET server I always try to convince the client that NCover (a Code Coverage Tool) is a requirement just as much as the NUnit is. As long as I can set it up rather quickly the client is happy to oblige because from a management perspective they can now see via the CC.NET Dashboard what code is covered and what code is not covered.
That is … if you understand how NCover works.
The Problem
NCover will create a profile for any assembly that is loaded into memory at runtime of the test suite. Lets think about that….
“… any assembly loaded into memory at runtime … ”
There’s a problem here. What if one of my assemblies have NO tests whatsoever? The end result is that the assembly _does_not_ show up on the CC.NET report. But… to NCover’s defense this is expected. How can NCover know _exactly_ what assemblies to profile? It can’t. The best it can do is to load the one’s it see’s during testing and profile those.
Unfortunately if your project has 10 assemblies and only 2 of them are under test you coverage percentage might be 75% – because those two assemblies might have a decent test suite. Since the other 8 assemblies were not loaded during the execution process they do not get profiled. Hmmm. problem…
So how do we get NCover to profile _all_ the assemblies that _we_ want?
Hacking NCover
I’ll be the first to admit – this is a hack. But… it works.
In order to get NCover to profile the assemblies I want covered I created a class file called “NCoverHelper.cs” with one test inside of it, shown below.
[Test]
public void This_will_load_all_Foo_assemblies_for_ncover_auto_discovery()
{
// HACK: This is a SUPER NCover hack. Read below for more info.
//
// This test is purely here to force NCover to LOAD the assembly into memory so that
// we can profile the ENTIRE stack of DLL's that we want. If we do not do this, NCover will
// only load those assemblies that are "touched" by tests. Therefore, if you have an
// assembly that DOES NOT have a test suite it would NOT show up. This test FORCES it
// to show up in the coverage report.
//
var files = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "Foo.*",SearchOption.AllDirectories);
var dlls = files.Where(x => Path.GetExtension(x) == ".dll" && x.Contains(@"\build\bin\"));
// Uncomment line below to see all files the app is loading.
//File.WriteAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "dlls.txt"), String.Join(Environment.NewLine, dlls.ToArray()));
dlls.ToList().ForEach(x => Assembly.LoadFile(x));
}
How it works:
The code looks in the currently executing directory, then searches for all “Foo*” files. This would return Foo.DataAccess.dll, Foo.Business.dll, Foo.Repository.dll, you get the point. The code searches all folders under the currently executing root folder. In the end, it could possibly find 10 of the same Foo.DataAccess.dll if it was referenced throughout the project.
After the dll’s are found, I filter them based upon a location. In the example above, I filter them based upon the path “\build\bin\” which is where my build is dropped.
After I have all the Foo dll’s I need, I load them via Assembly.Load(…). Yes, its kind of slow. BUT… it works.
After loading the assemblies, NCover will then profile them and find that some of them are never tested. Therefore, the report that is returned from NCover is a 0.0% coverage for any assembly that has no tests.
Please note – I’m sure there is a better LINQ query to get the info I need, but this one works for me.
Conclusion
A hack? Yes. Does it work? Yes.
In the end we are able to load our assemblies via runtime of the tests which enables NCover to profile them. The end result is that we can now see our true code coverage for our entire project, not just the projects which were “touched” by a unit test.
