I really enjoy being able to write C# code and deploy/debug it on my Netduino device. However there are many cases where I would like to do a little Test Driven Development to flush out a coding problem without deploying to the actual hardware. This becomes a little difficult since the .Net Micro Framework doesn’t have an easily available testing framework. There are some options that you have in order to write and execute tests:
- You could wait for the NunitLite support for .Net Micro Framework
- You could use an emulator and role your own testing framework
- You could do something like what I used to do with the BX24
Well I have another option that works with the full blown NUnit framework if you follow a few conventions when writing your Netduino code. This approach does not use the emulator so you need to be able to break up your application into two different types of classes:
- Classes that use .Net Micro or Netduino specific libraries
- Classes that do not use .Net Micro or Netduino specific libraries.
This seems a little strange but another way to look at the organization of your classes is that if any code does any IO then it belongs in the non testable classes. Any other code that performs logical decisions or calculations belongs in the testable classes. This is a common approach that is done in a lot of systems and the IO classes are usually categorized as a hardware abstraction layer. You can use interfaces to the hardware abstraction layer so that during unit testing you can fake or mock out the hardware and simulate conditions that test the decision making code.
Enough talking about approaches to unit testing lets get going on an example project that shows how this will work. For this example I am creating a Netduino application that reads an analog sensor that measures the intensity of light and turns an LED on or off.
Here is how the solution is set up so that I can do unit testing.
The solution consists of two projects:
- Netduino.SampleApplication - a Netduino Application built against the .Net Micro Framework
- Netduino.SampleApplication.UnitTests – a .Net 4.0 Class Library
The Netduino.SampleApplication.UnitTests project references the following:
Notice that this unit test project does not reference the assembly that it will be targeting for testing. This is done on purpose because a .Net 4.0 Assembly cannot reference an assembly built against the .Net Micro Framework. The project does reference the NUnit testing framework.
Now lets talk about the class that we are going to write tests against. Since analog sensors can sometimes be a little noisy I wanted to take multiple samples of the sensor and average the results so that any noisy readings will be smoothed out. This class is able to accept sensor readings and provides an average of the last N readings.
Here is the AnalogSmoother class
This is a pretty simple class that exposes one operation called Add and one property called Average. One thing to notice is that I have removed any using statements (Microsoft.SPOT) that would make this class .Net Micro specific or Netduino specific.
To test this we need to use a cool Visual Studio feature called “Add as Link” where you can add an existing class to another project by linking to the original file. If you change the original file the project that has the linked file will also see the change. To add the linked file you simply right click on the Netduino.SampleApplication.UnitTests project and select Add –> Existing Item and navigate to the AnalogSmother.cs file and select the down arrow on the Add button.
So now you have a single file that is compiled in the Netduino project and the Unit Test project. This makes it very easy to create a test fixture class in the unit test project that exercises the linked class.
Here is the test fixture class:
So I was able to test this class without starting up an emulator or deploying to the Netduino. This is great for classes that do not need to perform any IO but eventually you are going to run into a case where you need to access the specific hardware of the Netduino. This is where the hardware abstraction layer comes into play.
In this sample application I created the following interface:
Here is the class that implements the interface and does all the actual IO:
Here is the class that uses the IHardwareLayer interface that has some more logic that can be tested using the same approach of adding the linked file to the unit test project.
This class will have to be tested a little differently though because it actually expects the IHardwareLayer to return values when calling ReadLight. We can simulate the hardware returning correct values by providing a fake implementation of the IHardwareLayer interface. This can be done easily by creating a FakeHardwareLayer that implements the IHardwareLayer and returns the expected values. Or you can use a mocking framework such as Moqto do the work for you.
The Moq mocking framework allows you to Setup specific scenarios and Verify that those scenarios are working. The above test verifies that the LED does turn on and off for specific values of Light Readings.
Conclusion
I have been able to show you that unit testing is doable for Netduino projects if you follow a couple design patterns and you don’t have to wait for a testing framework to be available for the .Net Micro Framework.
UPDATE: I made a couple small tweaks to the code and posted it on my NetduinoExamples repository under the UnitTestingExample subfolder.