1. Code
  2. Testing

Unit Testing Succinctly: How Does Unit Testing Work?

Read Time:4 minsLanguages:
This post is part of a series called Unit Testing Succinctly.
Unit Testing Succinctly: Look Before You Leap
Unit Testing Succinctly: Unit Test Tools

This is an extract from the Unit Testing Succinctly eBook, by Marc Clifton, kindly provided by Syncfusion.

A unit test engine in a reflective language (such as any .NET language) has three parts:

  • Loading assemblies that contain the tests.
  • Using reflection to find the test methods.
  • Invoking the methods and validating the results.

This article provides code examples of how this works, putting together a simple unit test engine. If you’re not interested in the under-the-hood investigation of unit test engines, feel free to skip this article.

The code here assumes that we are writing a test engine against the Visual Studio unit test attributes defined in the Microsoft.VisualStudio.QualityTools.UnitTestFramework assembly. Other unit test engines may use other attributes for the same purposes.

Loading Assemblies

Architecturally, your unit tests should either reside in a separate assembly from the code being tested, or at a minimum, should only be included in the assembly if it is compiled in “Debug” mode. The benefit of putting the unit tests in a separate assembly is that you can also unit test the non-debug, optimized production version of the code.

That said, the first step is to load the assembly:

Note that professional unit test engines load assemblies into a separate application domain so that the assembly can be unloaded or reloaded without restarting the unit test engine. This also allows the unit test assembly and dependent assemblies to be recompiled without shutting down the unit test engine first.

Using Reflection to Find Unit Test Methods

The next step is to reflect over the assembly to identify the classes that are designated as a “test fixture,” and within those classes, to identify the test methods. A basic set of four methods support the minimum unit test engine requirements, the discovery of test fixtures, test methods, and exception handling attributes:

Invoking Methods

Once this information has been compiled, the engine invokes the test methods within a try-catch block (we don’t want the unit test engine itself crashing):

Finally, we can put this code together into a simple console application that takes the unit test assembly as parameter results in a usable, but simple engine:

The result of running this simple test engine is displayed in a console window, for example:

Our Simple Test Engine Console ResultsOur Simple Test Engine Console ResultsOur Simple Test Engine Console Results
Our Simple Test Engine Console Results
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.