Testing That Your Public APIs Have Not Changed Unexpectedly with PublicApiGenerator and Approval Tests

We can write automated tests to cover various aspects of the code we write. We can write unit/integration tests that test that the code is producing the expected outcomes. We can use ConventionTests to ensure internal code quality, for example that classes following a specified naming convention and exists in the correct namespace. We may even add the ability to create a business readable tests using tools such as SpecFlow or BDDfy.

Another aspect that we might want to ensure doesn’t change unexpectedly is the public API that our code exposes to callers.

Using PublicApiGenerator to Generate a Report of our Public API

The first step of ensuring our public API hasn’t changed is to be able to capture the public API in a readable way. The PublicApiGenerator NuGet package (from Jake Ginnivan) gives us this ability.

Suppose we have the following class defined:

public class Calculator
{
    public Calculator()
    {
        CurrentValue = 0;
    }

    public int CurrentValue { get; private set; }

    public void Clear()
    {
        CurrentValue = 0;
    }

    public void Add(int number)
    {
        CurrentValue += number;
    }
}

Notice here that this code defines the public API that consumers of the Calculator class can use. It’s this public API that we want to test to ensure it doesn’t change unexpectedly.

We might start with some unit tests as shown in the following code:

public class CalculatorTests
{
    [Fact]
    public void ShouldHaveInitialValue()
    {
        var sut = new Calculator();

        Assert.Equal(0, sut.CurrentValue);
    }

    [Fact]
    public void ShouldAdd()
    {
        var sut = new Calculator();

        sut.Add(1);

        Assert.Equal(1, sut.CurrentValue);
    }
}

These tests help us ensure the code is doing the right thing but do not offer any protection against the public API changing. We can now add a new test that uses PublicApiGenerator to generate a string “report” detailing the public members of our API. The following test code shows this in use:

[Fact]
public void ShouldHaveCorrectPublicApi()
{
    var sut = new Calculator();

    // Get the assembly that we want to generate the public API report for
    Assembly calculatorAssembly = sut.GetType().Assembly;

    // Use PublicApiGenerator to generate the API report
    string apiString = PublicApiGenerator.PublicApiGenerator.GetPublicApi(calculatorAssembly);

    // TODO: assert API has not changed
}

If we debug this test and look at the content of the apiString variable we’d see the following text:

[assembly: System.Runtime.InteropServices.ComVisibleAttribute(false)]
[assembly: System.Runtime.InteropServices.GuidAttribute("c2dc3732-a4a5-4baa-b4df-90f40aad1c6a")]
[assembly: System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.5.1", FrameworkDisplayName=".NET Framework 4.5.1")]

namespace Demo
{
    
    public class Calculator
    {
        public Calculator() { }
        public int CurrentValue { get; }
        public void Add(int number) { }
        public void Clear() { }
    }
}

Using Approval Tests to Assert the API Is Correct

Now in our test we have a string that represents the public API. We can combine PublicApiGenerator with the Approval Tests library to check that this API text doesn’t change.

First off we go and install the Approval Tests NuGet Package. We can then modify the test as shown below:

public class CalculatorApiTests
{
    [Fact]
    public void ShouldHaveCorrectPublicApi()
    {
        var sut = new Calculator();

        // Get the assembly that we want to generate the public API report for
        Assembly calculatorAssembly = sut.GetType().Assembly;

        // Use PublicApiGenerator to generate the API report
        string apiString = PublicApiGenerator.PublicApiGenerator.GetPublicApi(calculatorAssembly);

        // Use Approval Tests to verify the API hasn't changed
        Approvals.Verify(apiString);
    }
}

The first time we run this it will fail with a message such as “Failed Approval: Approval File "c:\…\Demo.Tests\CalculatorApiTests.ShouldHaveCorrectPublicApi.approved.txt" Not Found”. It will also generate a file called CalculatorApiTests.ShouldHaveCorrectPublicApi.received.txt. We can rename this to CalculatorApiTests.ShouldHaveCorrectPublicApi.approved.txt, run the test again and it will pass.

If we now modify the public API by changing a method signature (e.g. to public void Clear(int someParam)) and run the test again it will fail with a message such as “Received file c:\...\Demo.Tests\CalculatorApiTests.ShouldHaveCorrectPublicApi.received.txt does not match approved file c:\...\Demo.Tests\CalculatorApiTests.ShouldHaveCorrectPublicApi.approved.txt”.

Modifying the test and adding an Approval Tests reporter attribute ([UseReporter(typeof(DiffReporter))]) and running the test will now gives us a visual diff identifying the changes to the public API as shown in the following screenshot.

Approval Tests Diff Screenshot

To learn more about the features of Approval Tests, check out my Approval Tests for .NET Pluralsight course.

3 Tools for Choosing and Working with Color in Apps, Websites, and Print

When developing apps, websites, or even presentations for your team or management it can be difficult to come up with a working color scheme.

Below are three useful tools that can be of help.

Adobe Color CC (formerly Adobe Kuler)

Adobe Color CC Screenshot showing color wheel

Adobe Color CC is a classic color scheme designer based around the concept of the color wheel. You can choose a starting color and then one of the standard color schemes from color theory (complimentary, triadic, etc). This then gives you you the related colors based on the chosen color scheme.

For each color you can get the RGB, HEX, CMYK, LAB, and HSB values to use in whatever application your working on.

You can also explore a range of pre-built palettes created and shared by other users.

Paletton

paletton screenshot

Paletton is another tool based around the concept of the color wheel that offers a choice of color schemes. You can also use its “vision simulator” to simulate what the colors might look like to users with some kind of vision impairment.

The following image shows the same color sheme with no vision simulator (left) and protanopia – a form of color blindness (right).

paletton screenshot simulating color blindness

 

Multicolr

multicolr screenshot

Multicolr is an interesting tool that can help find images that match one or more colors. If you need to find images matching a set of colors this can be useful. To use Multicolr you start by selecting from one to five colors, in the preceding screenshot I have a chose a purple and white. The images come from flickr and you can select and image from the search results and view the original.

Winning in 2016

As the year 2015 starts its last slide into 2016, it’s the time of year that I start to think about what my 3 Wins are going to be for next year.

If you’re not familiar with the 3 Wins concept, it’s similar to goal setting but rather than focus on “what will I tick off my todo list” it’s more along the lines of “what will make me feel great, like I’ve accomplished something, like I’ve made progress…”. One way to help come up with three wins is to imagine how your future self will feel when you look back on the year and have accomplished all your 3 Wins.

It’s important to make your 3 Wins achievable, otherwise not achieving any of them could be disheartening and demotivating.

One technique to guide you, while being sounding very “managementy”, is the concept of SMART criteria.

SMART is an acronym that stands for:

  • Specific
  • Measurable
  • Attainable
  • Realistic
  • Time-related (or Time-bound)

Using SMART may help if you are struggling to create your own 3 Wins.

You might have 3 Wins for your work/career and you may also have 3 Wins for personal/health/family/etc. related things. Also you can use 3 Wins daily, weekly, monthly, quarterly, or at any scale you wish; you could even have decade or lifetime 3 Wins.

Testing Akka.NET Actor Systems

My new Pluralsight course Akka.NET Testing Fundamentals is now available.

Testing actor system brings a number of additional considerations over and above the concepts of traditional object oriented unit/integration testing.

While some additional testing support is required, for example as provided by Akka.NET’s TestKit, concepts such as “unit” and “integration” do translate to the testing of actors. For example a “unit” test becomes a test of the behaviour of a single actor in isolation and an “integration” test may involve multiple actors being testing together.

Just as with traditional OO testing where object dependencies can be mocked, so to with actor tests. For example, TestKit provides a number of pre-built mock actors that can be used if the actor(s) being tested need to be isolated. The simplest of these pre-built mock actors is the BlackHoleActor that will simply and silently accept any message sent to it and “swallow” the message. The EchoActor is another pre-built mock actor that will echo any message sent to it back into the test actor system instance as well as optionally back to the sending actor. The TestProbe pre-built mock actor is a more generalised mock actor and can be used in a number of useful ways.

To get access to the benefits of the actor testing infrastructure, the test class inherits from the TestKit base class. By doing this we get access to an automatically created actor system instance into which we can instantiate the actor(s) that need testing.

When testing an actor, it can be treated as a black or white box. A black box test would involve sending a message to the actor and examining (and asserting on) response message(s). Utilising TestKit we can also write white box actor tests where we can get access to the “internal” actor state directly and make asserts on this internal state.

If you’re new to the Actor Model or Akka.NET, check out the docs or my introductory Pluralsight course: Building Concurrent Applications with the Actor Model in Akka.NET.

Painless .NET Windows Service Creation with Topshelf

Windows Services allow us to run code in the background, without needing (for example) a console application running continually. Windows Services can run as various system users or specific local/domain users.

To see what Windows Services are installed on your (Win 8+) PC, hit Win+x then hit G. In the Computer Management window that opens, click the Services option under Services and Applications as shown in the following screenshot.

Computer Management window showing installed Windows Services

As the preceding screenshot shows, a Service has a (Display) Name, a Description, a Status (e.g. Running or not), a Startup Type (Manual, Automatic, Disabled, etc), and a Log On As that specifies in which user context the Service executes.

We can create Windows Services to run arbitrary .NET code such as:

  • Self-hosted web server using Owin
  • File system watcher and batch processing (e.g. image file conversion, video encoding)
  • Host remote Akka.NET actor system (such as in my Pluralsight course)
  • Process messages from a message queue as they arrive (e.g. MSMQ)
  • Mail, FTP, etc. servers
  • Integration/gateway, e.g. receive data from external systems

Using Topshelf

Topshelf is an open source project that greatly simplifies the creation of Windows Services.

The overview of creating a Service using Topshelf is:

  1. Create a Console application project in Visual Studio
  2. Add the Topshelf NuGet package
  3. Create a class to represent your service logic
  4. Configure your Service using the Topshelf API
  5. Build your Console application
  6. Execute your Console application passing Topshelf parameters to install/uninstall your Service


So assuming we have a new Console project called “Time” and the following NuGet packages are installed:

<packages>
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net451" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net451" />
  <package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net451" />
  <package id="Microsoft.AspNet.WebApi.OwinSelfHost" version="5.2.3" targetFramework="net451" />
  <package id="Microsoft.Owin" version="2.0.2" targetFramework="net451" />
  <package id="Microsoft.Owin.Host.HttpListener" version="2.0.2" targetFramework="net451" />
  <package id="Microsoft.Owin.Hosting" version="2.0.2" targetFramework="net451" />
  <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net451" />
  <package id="Owin" version="1.0" targetFramework="net451" />
  <package id="Topshelf" version="3.2.0" targetFramework="net451" />
</packages>

We can create a self-hosted OWIN service that tells us the time.

First off we create an API Controller to return the time and then create an OWIN startup configuration class:

public class TimeController : ApiController
{
    [HttpGet]
    public string Now()
    {
        return DateTime.Now.ToLongTimeString();
    }
}

public class Startup
{
    public void Configuration(IAppBuilder appBuilder)
    {
        var config = new HttpConfiguration();

        config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{time}");
        config.Formatters.Remove(config.Formatters.XmlFormatter);
        config.Formatters.Add(config.Formatters.JsonFormatter);

        appBuilder.UseWebApi(config);
    }
}

Next we create a class that represents our Topshelf Windows Service:

class TimeService
{
    private IDisposable _webServer;

    public void Start()
    {
        // code that runs when the Windows Service starts up
        _webServer = WebApp.Start<Startup>("http://localhost:8084");
    }

    public void Stop()
    {
        // code that runs when the Windows Service stops
        _webServer.Dispose();
    }
}

Now in the Console applications main method we can use Topshelf’s HostFactory to configure what our Windows Service will do (via the TimeService class) and how it will be configured in Windows:

class Program
{
    static void Main(string[] args)
    {
        HostFactory.Run(
            configuration =>
            {
                configuration.Service<TimeService>(
                    service =>
                    {
                        service.ConstructUsing(x => new TimeService());
                        service.WhenStarted(x => x.Start());
                        service.WhenStopped(x => x.Stop());
                    });

                configuration.RunAsLocalSystem();

                configuration.SetServiceName("ASimpleService");
                configuration.SetDisplayName("A Simple Service");
                configuration.SetDescription("Don't Code Tired Demo");
            });
    }
}

Once the solution is built, navigate to the bin/debug directory in a admin command prompt and type:

time.exe install

This will install the Service into Windows as the following screenshots show.

command prompt showing Topshelf service installation


Service installed in Windows


In the command prompt window type:

time.exe start

This will start our new service.

Now in a browser, navigate to http://localhost:8084/api/time/now and you’ll see the current time come back as JSON

screenshot showing browser getting time

To learn more about Topshelf, check out my Pluralsight course: Getting Started Building Windows Services with Topshelf.

30 Pluralsight Courses

My new Pluralsight course Stateful Reactive Concurrent SPAs with SignalR and Akka.NET was just published, this brings my total number of courses to 30.

I’ve always loved teaching and sharing and being a Pluralsight author is a great way to continue to do this.

I’d also like to take a moment to say a thankyou to everyone that’s watched my courses and for all the kind words. Thank you.

Improving Message Throughput in Akka.NET with Routers

One of the things I cover in my new Pluralsight course is the awesome feature of routers in Akka.NET.

Routers, with very little code/config change, allow us to spread messages across multiple instances of actors. This means we can process messages concurrently and thus improve the overall throughput of messages in the actor system.

Routers distribute message to a set of actor instance “routees”.

Router Types

Routers can be grouped into two categories: Group routers and Pool routers.

Group routers distribute messages to actors that have already been created in the actor system, this means that a Group router does not supervise its routees.

A Pool router on the other hand does create and supervise its routees.

Routing Strategies

Both Pool and Group routers use routing strategies to determine which routee(s) a message should be routed to. Not all routing strategies are available in both Group and Pool routers.

One of the routing strategies is the Round-Robin strategy. This strategy will route incoming messages in turn to each routee in order, then return back to the first routee and continue around all routees.

An Example

As an example, consider the following console application that simulates some work being done with a Thread.Sleep(200).

using System;
using System.Diagnostics;
using System.Threading;
using Akka.Actor;

namespace ConsoleApplication1
{
    public class CompletedSomeWorkMessage
    {
    }

    public class DoSomeWorkMessage
    {
        public DoSomeWorkMessage(int workItem)
        {
            WorkItem = workItem;
        }

        public int WorkItem { get; private set; }
    }

    public class WorkerActor : ReceiveActor
    {
        private readonly IActorRef _counterActorRef;

        public WorkerActor(IActorRef counterActorRef)
        {
            _counterActorRef = counterActorRef;

            Receive<DoSomeWorkMessage>(
                message =>
                {
                    Console.WriteLine("Working on {0}", message.WorkItem);

                    // simulate some work
                    Thread.Sleep(200);

                    _counterActorRef.Tell(new CompletedSomeWorkMessage());
                });
        }
    }


    public class WorkCounterActor : ReceiveActor
    {
        private int _workLeft;

        public WorkCounterActor(int workToBeDone)
        {
            _workLeft = workToBeDone;

            Receive<CompletedSomeWorkMessage>(
                message =>
                {
                    _workLeft--;

                    if (_workLeft == 0)
                    {
                        // all work is done so shutdown actor system
                        Context.System.Shutdown();
                    }
                });
        }
    }

    internal class Program
    {
        private static void Main(string[] args)
        {          
            const int totalWorkToBeDone = 20;

            var system = ActorSystem.Create("MySystem");
            var counter = system.ActorOf(Props.Create(() => new WorkCounterActor(totalWorkToBeDone)));
            var worker = system.ActorOf(Props.Create(() => new WorkerActor(counter)));


            var timeTaken = Stopwatch.StartNew();

            for (int i = 1; i <= totalWorkToBeDone; i++)
            {
                worker.Tell(new DoSomeWorkMessage(i));
            }

            system.AwaitTermination();

            timeTaken.Stop();


            Console.WriteLine("Took {0}ms", timeTaken.ElapsedMilliseconds);
            Console.ReadLine();
        }
    }
}

Running this application results in the following screenshot:

Akka.NET console application screenshot with no router

Notice in the preceding screenshot that to process 20 work items took about 4 seconds.

We can increase the concurrency in the system by adding a Round Robin Pool router.

The following modified code shows the creation of 5 worker actors as part of a pool.

var worker = system.ActorOf(Props.Create(() => new WorkerActor(counter)).WithRouter(new RoundRobinPool(5)));

Now when we execute worker.Tell(new DoSomeWorkMessage(i)) the message will be routed to one of five automatically created WorkerActor instances.

Running the program now results in an execution time of about 1.5 seconds rather than the non-router version that took about 4 seconds.

Akka.NET console application screenshot with a round robin router

To learn more about the different types of routers and other ways to improve message throughput check out my Pluralsight course: Improving Message Throughput in Akka.NET or check out the Akka.NET documentation.

Akka.NET Dispatchers and User Interface Thread Access

Akka.NET actors typically run in their own (non-UI) threads. This means by default accessing UI objects (for example setting some text in a text box) will cause a thread access exception.

For example the following code shows an actor trying to set the text of the button. The actor is not running in the UI context but the Button is so we’re trying to cross threads which causes the exception shown below.

Screenshot of Visual Stuid showing thread access exception in debugger

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <Button Click="Button_OnClick">Say Hi</Button>
        <TextBox Name="GreetingTextBox"></TextBox>
    </StackPanel>
</Window>

public class HelloWorldActor : ReceiveActor
{
    public HelloWorldActor(TextBox textBox)
    {
        Receive<string>(s => textBox.Text = s);
    }
}
public partial class MainWindow : Window
{
    private ActorSystem _actorSystem;
    private IActorRef _actor;

    public MainWindow()
    {
        InitializeComponent();

        _actorSystem = ActorSystem.Create("MySystem");

        _actor = _actorSystem.ActorOf(Props.Create(() => new HelloWorldActor(GreetingTextBox)));
    }

    private void Button_OnClick(object sender, RoutedEventArgs e)
    {
        _actor.Tell("G'day");
    }
}

The thread on which an actor runs can be configured, either in code or in the app/web HOCON config.

We can modify the actor props in code as follows:

_actor = _actorSystem.ActorOf(Props.Create(() => new HelloWorldActor(GreetingTextBox))
                                   .WithDispatcher("akka.actor.synchronized-dispatcher"));

Now the HelloWorldActor will run on the UI thread and be able to access the text box as the following screenshot shows:

screenshot of WPF application running and updating the TextBox from another thread

 

MVVM and INotifyPropertyChanged

When using MVVM and a view-model, rather that passing the UI element to the actor, the view-model can instead be passed. The actor now updates the view-model which the textbox is databound to. In this situation the data-binding mechanism/INotifyPropertyChanged will take care of marshalling changes to the UI thread. This means that the actor no longer needs to be configured to run on the UI thread. The following code shows these changes:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <Button Click="Button_OnClick">Say Hi</Button>
        <TextBox Text="{Binding Greeting}"></TextBox>
    </StackPanel>
</Window>

using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using Akka.Actor;

namespace WpfApplication1
{    
    public partial class MainWindow : Window
    {
        private ActorSystem _actorSystem;
        private IActorRef _actor;
        private ViewModel _viewModel ;

        public MainWindow()
        {
            InitializeComponent();

            _viewModel = new ViewModel();

            _actorSystem = ActorSystem.Create("MySystem");

            _actor = _actorSystem.ActorOf(Props.Create(() => new HelloWorldActor(_viewModel)));
            
            DataContext = _viewModel;
        }

        private void Button_OnClick(object sender, RoutedEventArgs e)
        {
            _actor.Tell("G'day");
        }
    }

    public class HelloWorldActor : ReceiveActor
    {
        private readonly ViewModel _viewModel;

        public HelloWorldActor(ViewModel viewModel)
        {
            _viewModel = viewModel;

            Receive<string>(s => _viewModel.Greeting = s);
        }
    }

    public class ViewModel : INotifyPropertyChanged
    {
        private string _greeting;

        public string Greeting
        {
            get { return _greeting; }
            set
            {
                _greeting = value;
                OnPropertyChanged();
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

You can read more about dispatchers in the Akka.NET docs and learn more about using Akka.NET with WPF in my Pluralsight course: Building Reactive Concurrent WPF Applications with Akka.NET.

EDIT: fixed up typo in source, changed to _actor.Tell("G'day");

Using Predicates in Akka.NET Receive Actors

When using the Receive actor API in Akka.NET, we can take advantage of overloads of the Receive method that allow us to specify predicates.

A message will now be handled if it is of the correct type and the predicate is met.

Take the following actor that sends emails with a different message if a customer is “high value”:

class WelcomeEmailSender : ReceiveActor
{
    public WelcomeEmailSender()
    {
        Receive<SendNewCustomerWelcomeEmail>(message => HandleMessage(message));
    }

    private void HandleMessage(SendNewCustomerWelcomeEmail message)
    {            
        if (message.IsHighValueCustomer)
        {
            SendEmail("Dear high value customer...", message.EmailAddress);
        }
        else
        {
            SendEmail("Yo! ...", message.EmailAddress);
        }
    }

    private void SendEmail(string greeting, string emailAddress)
    {
        Console.WriteLine("{0} to {1}", greeting, emailAddress);
    }
}

In the preceding code, the if statement is deciding what action is taken – the welcome message to be sent.

Using an overload of the receive method, we can add a predicate that replaces this if statement:

class WelcomeEmailSender2 : ReceiveActor
{
    public WelcomeEmailSender2()
    {
        Receive<SendNewCustomerWelcomeEmail>(
            message =>
            {
                SendEmail("Dear high value customer...", message.EmailAddress);
            },
            handleIf => handleIf.IsHighValueCustomer);

        Receive<SendNewCustomerWelcomeEmail>(
            message =>
            {
                SendEmail("Yo! ...", message.EmailAddress);
            }, 
            handleIf => handleIf.IsHighValueCustomer == false);
    }

    private void SendEmail(string greeting, string emailAddress)
    {
        Console.WriteLine("{0} to {1}", greeting, emailAddress);
    }
}

In the preceding code the predicate (represented by the lambda: handleIf => handleIf.IsHighValueCustomer) replaces the if.

In these example we only have two possible predicates because we are looking at the boolean “IsHighValueCustomer”. The following code shows predicates being defined for non-boolean (string) values:

class SomeActor : ReceiveActor
{
    public SomeActor()
    {
        Receive<string>(message => Console.WriteLine("Knock knock..."), handleIfMessage => handleIfMessage.Equals("Tell me a joke"));
        Receive<string>(message => Console.WriteLine("Hello There!"), handleIfMessage => handleIfMessage.Equals("Say Hi"));
        Receive<string>(message => Console.WriteLine("Woof"), handleIfMessage => handleIfMessage.Equals("Bark like a dog"));
    }
}

If we were to send this actor the following messages they would be received and handled:

IActorRef someActor = actorSystem.ActorOf<SomeActor>("Some");

someActor.Tell("Tell me a joke");
someActor.Tell("Say Hi");
someActor.Tell("Bark like a dog");

However, the following would not be received as it has no matching predicate (even though the message is still of type string):

someActor.Tell("Say bye");

To learn more about Akka.NET, check out the docs or my Pluralsight courses: Building Concurrent Applications with the Actor Model in Akka.NET and Implementing Logging and Dependency Injection in Akka.NET.