Testing Xamarin Projects using NUnit 3
When testing Xamarin using NUnit 3, you have two choices.
- A Portable Library that you reference from the test runner for each platform, or
- A Shared Project with your tests referenced from the platform specific test runners.
I prefer the Shared Project approach because it also allows you to run your tests from within Visual Studio by also creating a .NET 4.5.x test project. As of NUnit 3.0.1, you cannot run tests that use the portable version of the NUnit Framework from the console or within Visual Studio, so the .NET 4.5.x test project gets around that limitation.
This approach assumes that you are using and testing a portable Xamarin project. If not and you are using a shared project, everything will be the same except you will not be able to test in Visual Studio using a .NET 4.5.x test project because you cannot reference the platform specific assemblies.
To get started, you should install the NUnit Templates extension for Visual Studio. It will add project templates for the various Xamarin platforms.
The first step is adding a Shared Project to your solution that will contain your tests. Next, add a NUnit 3 Unit Test Project from under the Visual C# | Test node. This project will be .NET 4.5.x based and allow you to run tests from within Visual Studio or on the console. Add your shared project to this project as a shared reference. Depending on what you are testing, you will likely have to add references to the NuGet packages for Xamarin and any plugins you are using.
As you are testing with the .NET 4.5 project, you will eventually try to test things that requires Xamarin or one of the plugins to be initialized on the platform which won't work under .NET 4.5. This is where you will start needing platform specific test runners.
To add the platform specific test projects, Add | New Project.. and add a NUnit 3 Test Project (Android) from under the Visual C# | Cross-Platform | Test node. Repeat for the platforms that you support.
You will need to add references to your shared test project, your portable project that you want to test and if you have platform specific code you want to test, your platform specific projects. You may be using a newer version of Xamarin.Forms and/or require additional NuGet packages, so Manage NuGet Packages for Solution and install/upgrade packages for your test projects as appropriate.
With the platform specific runners, you can add needed platform initialization code to the runners just like any other Xamarin.Forms app. You can also include platform specific tests either by adding them to the runners themselves, or by using the various defines for conditional compilation like __MOBILE__ or __ANDROID__.
#if __MOBILE__
// This test causes the view to be bound to the viewmodel which doesn't work on the
// desktop because Xamarin.Forms.Init() must be called
[Test(TestOf = typeof(IssueViewModel))]
async public Task ListAttachmentsCommandNavigatesToAttachments()
{
await ViewModel.OnAppearing();
Assert.That(ViewModel.ListAttachments != null);
await ViewModel.ListAttachmentsFunc();
var navigation = Navigation as MockNavigation;
Assert.That(navigation.PushAsyncHappend);
}
#endif