Unit (or integration) tests of Xamarin workbooks

In Nethereum all the documentation samples are getting migrated to Xamarin workbooks. The capability to mix executable c# code with explanations written in Markdown provides a magnificent learning experience. Workbooks could be even used as a replacement for console applications or even as a way for business users to test libraries and create their own tests in similar way to gherkin and BDD.

Another great benefit is that workbooks, as they are written in Markdown, can be reused as part of a “readthedocs” documentation.

Maintaining the code and documentation up to date

The workbooks do not solve the ever lasting problem, how to maintain the documentation up to date. As soon that a change has been made in a library the code might become obsolete, a simple refactoring of namespaces, names, reordering of parameters will break the code instantly.

Workbooks are designed to reference specific versions of nuget packages, so there is also the issue of changing all the packages to the latest version, but forcing you to work with internal development nugets, dlls or update the documentation once a package has been published.

Making the worbooks part of the software development lifecycle

So how can we integrate the workbooks to be part of the development lifecycle? I originally thought to generate the workbooks from unit tests, but this quickly transpire to be a rather messy situation, as I thought to write the markdown in comments.

But what if you could test the workbooks, using the latest development code? They could work as acceptance tests, but also provide the documentation.

Extracting and executing all the code from the workbooks

Workbooks mainly execute each of the code elements one by one using the Roslyn scripting engine. So if we extract all the code sections from the Markdown document, we can execute them inside of our unit test in the same way.

var code = GetCodeSectionsFromWorkbook();
 var state = await CSharpScript.RunAsync(code);

The beauty of this, is that the code will be using the current project, library, nuget reference in our project, which will be the latest.

Executing the code can be fine, but how do we validate the results?

state = await state.ContinueWithAsync(“return (balanceSecondAmountSend, originalBalanceFirstAmoundSend);”);

I did not want to mix testing with the documentation, so a simple way to validate the data is to return all the variables that we want to Assert using the new multiple return capability in c#7.

Once we know the variable names, we can just add them to the script to be the final return statement.

Finally, we can cast the returned tuple as a dynamic type and assert each of the returned values in order.

var returnValue = (dynamic) state.ReturnValue;
 Assert.Equal(2000, returnValue.Item1);
 Assert.Equal(1000, returnValue.Item2);”

The code sample

The full “sample” can be found here , hopefully you find it useful.