Testing Xamarin Apps: Lowering Unit Testing Friction

In my my last post I showed how to set up unit tests that can easily be run against .NET/Mono, iOS, and Android. As a followup to that, I want to outline a few tips and tricks for lowering the friction to running these tests. The easier you can make it to add new tests and run them the more value you'll get out of testing. In fact, these tips apply to testing on any platform, so they are not limited to just Xamarin apps.

Code Templates

I'm always surprised to find out how many people don't take advantage of code templates in their IDEs, or even know they exist in the first place. Code templates allow you to define shortcuts for quickly scaffolding out predictable blocks of code so you don't have to type it all out manually. By default in Xamarin Studio and Visual Studio a lot of these are defined for you out of the box for C# code, such as prop for creating a property, or ctor for creating a constructor.

You can also go ahead and define your own, so one of the first things I do in any fresh install is add a template for tests. I tend to stick to a naming convention in my tests of MethodUnderTest_Scenario_ExpectedResult, which is very useful when reading a set of test results to understand what is working and what is not.

You can find code templates in Xamarin Studio's preferences under Text Editor > Code Templates:

Preferences

From there we can go ahead and add a new template for fact:

Fact template

The code for that template is:

[Fact]
public void $method$_$scenario$_$expected$()
{
	$end$
}

Each of the variables in the template - method, scenario, expected - should be editable. With this defined, in a C# code file if you type fact and hit tab twice you will see the template entered where your cursor is, and you'll be editing the first variable. You can continue hitting tab to cycle through the variables to rename them as needed. Hitting enter will take you to the body of the new method, as defined by the placement of $end$ in the template. Now you can add new tests to your suite in seconds!

Code templates are also available in Visual Studio, so you can set this up easily there as well if that's your preferred environment.

Shortcuts

There's not much to really write about this one, but it's worth calling out nonetheless. If your IDE has any shortcuts for running tests, make sure to learn and use them. For example, Visual Studio has a shortcut of Ctrl+R, A for running all tests in its runner. If you use ReSharper's runner there are a bunch of shortcuts depending on the type of run you want to do. Alt+R, U, N is one that's easy to remember, and will create a new session and run all the tests in ReSharper's runner.

Shortcuts will allow you to quickly trigger your tests without taking you out of the flow you're already in, keeping you both informed and productive.

Automatically Running Tests

Taking that even further, another great option is to just have your tests run automatically each time you build your solution. There are many solutions out there that can help you set this up, such as AutoTest.NET, but it's also easy to set up something basic by hand as well. To do this I'll make use of fswatch, which you can easily install via Homebrew:

brew install fswatch

With that in place let's create a script named monitor-tests.sh and set it up to monitor some tests, using the same example as the last post:

#!/bin/bash

XUNIT_PATH="packages/xunit.runner.console.2.1.0-rc2-build3176/tools/xunit.console.exe"
TESTS_PATH="bin/Debug/TestDemo.dll"

fswatch -0 $TESTS_PATH | xargs -0 -n 1 -I {} mono $XUNIT_PATH $TESTS_PATH

Each time the DLL file is changed, which will happen as part of building the project, fswatch will trigger the xUnit console runner to re-run against the updated test assembly. You can just leave this running off to the side and always be informed about the latest state of your test results.

Summary

These are just a few examples of easy ways to lower the friction to writing and running tests. Like with most things, if writing and running tests in your solution is too complicated or time consuming, you're ultimately going to stop using it. Make it easy on yourself to take advantage of these practices without sacrificing your time or productivity.

comments powered by Disqus
Navigation