Unit Testing Your Xamarin Forms Applications with F# and FsUnit

One of the best and easiest ways to use F# in your projects is to use it for unit testing and the same can be said for your mobile applications with Xamarin.

While C# has FluentAssertions as well as Should (I prefer the syntax of FluentAssertions between the two) F# has FsUnit to give more readable test conditions. I would say even more readable than the C# equivalent.

With this post I’ll have a small demo Xamarin project using Xamarin Forms to build the UI. This will consist of a simple navigation and a small class to do some logic. We will use F# for our test project to test both the logic and use Xamarin UI Test to make sure our navigation and screens appear as we intend. These tests are also to make sure our workflows work as intended on several different devices.

Let’s quickly compare the two and see how they look. Within our demo Xamarin application, our PCL project that includes our XAML for Xamarin Forms will also have a class to do some logic for us. For demo purposes, this will just be an Add class that takes in two integers and adds them together and returns the result. Here’s our small class:

public static class Add
{
    public static int AddItems(int x, int y)
    {
        return x + y;
    }
}

Pretty simple, right? Now we can unit test this method. Here’s a C# version of using FluentAssertions to check to check our result.

[TestFixture]
public class AddTests
{
    [Test]
    public void Add2And2()
    {
        var result = Add.AddItems(2, 2);

        result.Should().Be(4);
    }
}

And here is the equivalent of the above in F# using FsUnit.

[<TestFixture>]
type AddTests() = 

    [<Test>]
    member x.``Adding 2 + 2 = 4``() =
        let result = Add.AddItems(2, 2)

        result |> should equal 4

From here, you may be able to tell that our F# version is more readable. It takes away the noise of the . and ( ). You may have also noticed that, in F#, we can add the double back-ticks to our function name which will allow us to use spaces. Now your test names are that much more readable as well! In Xamarin Studio we can easily read what each test either in the Test Results pad or in the easier to read Unit Tests pad.

Using F# for Unit Tests

Now that we’ve seen how using F# for unit tests can be to our advantage, how exactly do we make this happen?

Keep in mind that the F# templates for Xamarin Studio are still being worked on so some manual steps may need to be taken to get all of this working. Of course, the first step is to add an F# class library project to your solution.

Then just reference your PCL project as you usually would in a test project.

At this point, when trying to call the class or method to test against in the C# PCL library, you may need to add the System.Runtime DLL to the test project. On my Mac, this is located in the /Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5/Facades/ folder.

Now, from here you are free to just call your tests like usual in an NUnit test project and use NUnit’s built-in Assert class. To give us those fluent and easier to read tests we will import FsUnit, as well.

Another little quirk you may experience here is that, when running tests that use methods from FsUnit you may receive the error below when trying to run the tests.

For this issue, you would need to create an App.config for your test project (if not already created) and add the below assembly binding redirect configuration.

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.3.1.0" newVersion="4.3.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="nunit.framework" publicKeyToken="96d09a1eb7f44a77" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.6.4.14350" newVersion="2.6.4.14350" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

This is a bit weird and out of the way, but for now that’s what is needed.

Writing Tests With FsUnit

Of course, FsUnit has different methods that are included to make your testing much more readable. Below are a few other examples within our demo application.

[<Test>]
member x.``Adding 1 + 0 = 1``() =
    let result = Add.AddItems(1, 0)

    result |> should be (greaterThan 0)

[<Test>]
 member x.``Adding 1 + 1 = 2``() =
     let result = Add.AddItems(1, 1)

     result |> should not' (equal 0)

Note that the not' function uses a single-quote. The FsUnit team explains that this is due to not overriding the built-in F# function.

There are plenty more over on the FsUnit site.


Hopefully you get a sense of how much helpful using F# with FsUnit can be with your unit testing experience. Even if you’re completely new to F# this is a great way to get started and a very easy way to incorporate F# into your projects, especially without having to mess with production code.

Also wonder what F# and Wintellect can do for you or your business, or just have more questions about F# in general? Feel free to reach out to us at any time with questions.

Need Xamarin Help?

Xamarin Consulting  Xamarin Training

Jonathan Wood

Recent Posts

How to Navigate Azure Governance

 Cloud management is difficult to do manually, especially if you work with multiple cloud…

5 days ago

Why Azure’s Scalability is Your Key to Business Growth & Efficiency

Azure’s scalable infrastructure is often cited as one of the primary reasons why it's the…

3 weeks ago

Unlocking the Power of AI in your Software Development Life Cycle (SDLC)

https://www.youtube.com/watch?v=wDzCN0d8SeA Watch our "Unlocking the Power of AI in your Software Development Life Cycle (SDLC)"…

1 month ago

The Role of FinOps in Accelerating Business Innovation

FinOps is a strategic approach to managing cloud costs. It combines financial management best practices…

1 month ago

Azure Kubernetes Security Best Practices

Using Kubernetes with Azure combines the power of Kubernetes container orchestration and the cloud capabilities…

2 months ago

Mastering Compliance: The Definitive Guide to Managed Compliance Services

In the intricate landscape of modern business, compliance is both a cornerstone of operational integrity…

2 months ago