Testing Xamarin Projects using NUnit 3

NUnit Tests on AndroidWhen testing Xamarin using NUnit 3, you have two choices.

  1. A Portable Library that you reference from the test runner for each platform, or
  2. 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.

2015-12-20 15_05_02-Add New Project

Test Projects

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
  • xamariners

    I just put out a nuget library that allows using specflow with xamarin.forms, allowing viewmodel testing and navigation tracking, while running on console, so pretty ideal for CI, and necessary for good BDD practices.

    The nuget is here : https://www.nuget.org/packages/SpecFlow.Xamarin.Forms, and step by step instructions are available here: http://xamariners.com/2016/08/17/xamarin-forms-bdd-unit-testing/

  • Rob Prouse

    Yes, NUnit does not yet support testing portable projects because of internal limitations within how NUnit is architected. I am working on fixing that now, but I am not sure if I am going to be able to get it done in time for the upcoming 3.2 release. You can test portable projects by including them in a .NET 4.5 test project, you just can’t have a portable test project.

  • Denis

    OK, but the tests that are defined in the portable project do not show up in visual studio. I thought the reason for this is, that visual studio does not find them in the .Net project.
    Could you maybe make a post about that? I think it would be very interesting to have tests in a portable project targeting a xamarin pcl that show up in the visual studio test explorer.

  • Rob Prouse

    No, the .NET 45 project is a normal NUnit project DLL just like any other. All of your tests get compiled into it because they are in a shared project which has the same effect as linking the files into the project.

  • Denis

    So if I understand it correctly, the .Net 45 Project would be a Testrunner (e.g. a console application) which runs the Tests. I thought, that i could somehow reference/register the Tests in the shared Project from the .Net 45 Project so that the Tests Show up in Visual Studio Test Explorer.

  • Jakob

    Nice article Rob 🙂
    I have a Android application. It uses gps for various functionality. How do i unit test that functionality? A have to have a reference to Google play service, Android.v4 etc
    Regards

  • Rob Prouse

    The test project, what I named DefectCollection.Tests in my screenshots must be a Shared project, then the Net45 project should target .NET 4.5 and have a shared reference to the test project.

    If the test project is portable, it cannot run on Windows yet.

  • Denis

    I have everything set up like You wrote and I like the aproach. The only Thing I cannot get to work is to run the Tests located in the portable Project from within Visual Studio (especially the Test-Explorer). How should the portable test Project be linked to the Net45 Testproject?