Contents tagged with Unit Testing
-
MSTest and Calling Exe with Sample Data Files
For various reasons I’m using MSTest for my unit tests and I have this console app which generates a PDF file from an XML file that needed some tests.
So, when moving the unit tests over to a TFS build server, having hard coded paths to test data files is not a good idea. The recommended way of doing it is to use the DeploymentItem attribute.
Also, when calling an exe-file which does Environment.Exit() and catching the exit code from the unit test is pretty straight forward by using Process.Start() and checking the ExitCode property.
A small sample:
[TestMethod] [DeploymentItem(@"TestData\arbetsorder.xml", "TestData")] [DeploymentItem(@"TestData\arbetsorderReport.rdlc", "TestData")] public void GeneratorShouldReturnWithExitCode0() { Process proc; try { proc = Process.Start("PdfGenerator.exe", "\"" + Directory.GetCurrentDirectory() + "/TestData/arbetsorderReport.rdlc\" \"" + Directory.GetCurrentDirectory() + "/arbetsorder.pdf\" \"" + Directory.GetCurrentDirectory() + "/TestData/arbetsorder.xml\""); } catch (System.ComponentModel.Win32Exception ex) { proc = null; Assert.Fail(ex.Message); } Assert.IsNotNull(proc); proc.WaitForExit(10000); Assert.IsTrue(proc.HasExited); Assert.AreEqual(0, proc.ExitCode, "Expected 0, got " + proc.ExitCode); }
But, there’s a small caveat to get the DeploymentItem argument working properly! First you have to open up the test settings of your .testsettings file, select the Deployment settings and make sure the “Enable deployment” checkbox is checked:
That’s all you need to do. And note that you may actually have to exit and restart Visual Studio to make it work. I never got the files deployed until I did that restart.
-
Visual Studio 2008 Web Test Not Recording on 64-bit Windows 7
I was about to record a web test in Visual Studio 2008 Team System today, and the recorder refused to record anything. And the Recorder “bar” in IE 8 was not showing. After some digging around, the issue was fixed by deleting a few registry keys. Found it on Michael Taute's Blog : Diagnosing and fixing Web Test recorder bar issues.
Quote from his blog page:
Vista caches the list of explorer bars you have available and the recorder bar was not included in your list. The fix is to force Windows to rebuild that cache. To do this, first make sure you have all Internet Explorer instances shut down, then open the 32 bit registry editor and delete the following keys:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Discardable\PostSetup\Component Categories\{00021493-0000-0000-C000-000000000046}
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Discardable\PostSetup\Component Categories\{00021494-0000-0000-C000-000000000046}[Note: by default, the 32 bit registry editor is located in %WINDIR%\SysWow64\RegEdt32.exe]
The next time you boot Internet Explorer, your explorer bar cache will be rebuilt and the recorder bar should be available.
-
Integration Testing WCF Services with Unity
I've been blogging a few times now about using Unity with WCF, but how do you integration test your service in an easy way without? The way I (and many others) do integration tests for a WCF service is by setting up my own service host and starting the service from test init:
[TestClass]
public class ServiceIntegrationTest
{
private static ServiceHost serviceHost;
[ClassInitialize]
public static void MyClassInitialize(TestContext testContext)
{
serviceHost = new ServiceHost(typeof(Service1), new [] { new Uri("http://127.0.0.1:8001/") });
serviceHost.AddServiceEndpoint(typeof(IService1), new BasicHttpBinding(), "Service1");
serviceHost.Open();
}
[ClassCleanup]
public static void MyClassCleanup()
{
serviceHost.Close();
}
[TestMethod]
public void Should_get_data()
{
var ep = new EndpointAddress("http://127.0.0.1:8001/Service1");
var proxy = ChannelFactory<IService1>.CreateChannel(new BasicHttpBinding(), ep);
var data = proxy.GetData(1);
Assert.IsTrue(data == "You entered: 1", "Got wrong data back, got - '" + data + "'");
}
}
By doing it this way I don't have to make sure Cassini is started up before the test or having to deploy the service to a local IIS. There is no need for web.config or app.config files and I don't have to add any service reference. This way of doing integration testing of services is described by many others, and it should work quite well on a TFS build server or similar.
Integration Testing WCF Service with Unity
A few blog posts away I wrote about using Unity with WCF, but how do you integration test a setup like that? Remeber that if you have created your own ServiceHostFactory, you specify the factory to use in the .svc markup using the Factory attribute this:
<%@ ServiceHost Language="C#" Debug="true" Factory="IRM.Patterns.UnityService.UnityServiceHostFactory" Service="WcfService3.Service1" CodeBehind="Service1.svc.cs" %>
The "problem" here is that the factory doesn't have any decent public methods to let you create the service host from a given service type. True, there is a CreateServiceHost method which accepts a string representation of the type, but that means your service host factory has to have a reference to the type in question. The way I went around that small issue is by creating a small "harness" around the factory, with a public method which accepts a Type:
public class UnityServiceHostFactoryHarness : UnityServiceHostFactory
{
public ServiceHost CreateServiceHost(Type serviceType, string baseAddress)
{
return CreateServiceHost(serviceType, new[]
{
new Uri(baseAddress)
});
}
}
A small change to the test-initialize method makes use of this test-harness:
[ClassInitialize]
public static void MyClassInitialize(TestContext testContext)
{
var serviceHostFactoryHarness = new UnityServiceHostFactoryHarness();
serviceHost = serviceHostFactoryHarness.CreateServiceHost(typeof(Service1), "http://127.0.0.1:8001/");
serviceHost.AddServiceEndpoint(typeof(IService1), new BasicHttpBinding(), "Service1");
serviceHost.Open();
}
Now we're running service integration tests and we have the Unity container loaded as well. I'm sure there are other, smarter and for me uknown ways of achieving the same, but it works for me :) If you want sample code for the UnityServiceHostFactory, please let me know, but know that my code is based on the this sample.
-
[.NET 2.0][Unit Testing] Good Tutorial on System.Transactions (and Unit Testing)
On my random blog reading and Googling around System.Transactions and Unit Testing, I ran into a series of short but great articles by Stuart Celarier which actually covers both topics. Stuart teaches the reader about System.Transaction by using unit tests in a very educational (and entertaining) way.
He uses NUnit in his articles, but nothing will stop you from using the test mechanism built into VS.NET if you got that Team Edition version. Just use the [TestMethod] attribute instead of [Test] and all sample code in the articles will compile and test well (eventually :)
Stuart also make use of anonymous methods for testing events that I recently blogged about.
System.Transactions is good stuff, I wonder if it could be useful to manage "compensating transactions" when dealing with multiple web service calls within a transaction?
-
[.NET 2.0][Unit Testing] Using Anonymous Methods when Testing Events
-
TDD: Who is testing the tester?
I posted earlier about the book "Test Driven Development in Microsoft.NET, and I liked that book very much, it's not that. I've been using JUnit and NUnit in smaller and larger projects, but I've never used it in the way you often see it described in books written by the TDD-gurus and the way it is described in this book. I can't help it, but it feels kind of stupid to create a test the first thing you do, just to see the compile fail, write enough code to make the test compile then see the test fail, then add "dummy code" so that the first test pass but the rest fails... you know the drill :)
Then there is this thing about testing every class in every layer in a system or application. Writing that many tests manually would probably make me go nuts, and the quality of the test methods would most certainly drop after a while. The value of unit testing only gets as good as your test code, right? I've seen some tools that try to create test code for you automatically, but I've not been that impressed.
The way I've been using JUnit is that I've created tests against the facade layer or (web) service layer and then added the tests as a target in my ANT build scripts. That has worked out pretty well. If someone in the team changed something in the database or some other layer, the test fail and you (most of the time) get a pretty good tracktrace which shows where the problem lies. Even so, writing really good tests for that layer only (with scripts for setting up database tables and populate with test data), can take quite some time. Of course, it depends on what kind of system you're building and if the service/facade interface takes complex parameters which makes it hard to test properly, but imagine writing tests for the service layer, business layer, utilties and data access layer too. You would probably spend more time writing test code than anything else :)
Some would probably say TDD, XP and Refactoring is something invented by a few smart guys so they would get longer contracts and get to spend more time coding and less time documenting ;) I just wish some of my customers believed in those methods when I was a consultant :p
Personally I'm going to continue to use parts of TDD, XP and refactoring that I like because I think these methods (not that refactoring is a dev method but anyway) have got some really good bits in them. Besides, I love to read the books about them.