Framework Drivers
Framework Drivers are extensions that know how to create a driver for a particular framework. These allow the NUnit Engine to run tests for multiple different test frameworks. The NUnit engine provides drivers for both NUnit 3.x, whilst a separate extension can be installed to run NUnit 2.x frameworks. Third parties may provide drivers for other frameworks by creating extensions.
Implementation Details
The framework driver API is encapsulated in the IDriverFactory
and IFrameworkDriver
interfaces, which must be
implemented by all framework driver extensions to the engine.
IDriverFactory
The IDriverFactory
interface is called by the engine to determine if a particular extension is able to create a driver
for a particular framework assembly. The engine passes the AssemblyName of each assembly referenced by the test assembly
to the factory to see if it is a supported framework. If it finds one, then it uses that driver. If not, it goes on to
check the next driver extension.
The ExtensionPoint
for framework drivers uses the Path "NUnit.Engine.DriverService" and accepts an extension of Type
NUnit.Engine.Extensibility.IDriverFactory
. The definition of a driver factory might look like this:
[Extension]
public class MyOwnFrameworkDriverFactory : IDriverFactory
{
/* ... */
}
The IDriverFactory
interface is defined as follows:
public interface IDriverFactory
{
// Gets a flag indicating whether the provided assembly name and version
// represent a test framework supported by this factory
bool IsSupportedTestFramework(string assemblyName, Version version);
// Gets a driver for use with the specified framework assembly name and version
IFrameworkDriver GetDriver(AppDomain domain, string assemblyName, Version version);
}
IFrameworkDriver
The IFrameworkDriver
interface is returned from IDriverFactory
and is the key interface for actually loading,
exploring and running the tests in the test assembly. In theory, a single driver factory could return different drivers
in different situations, but we expect a one-to-one mapping of factories to drivers to be most commonly used.
As designed, the IFrameworkDriver
interface maps most directly to the requirements of the NUnit 3 framework. Drivers
for other frameworks need to function as an adapter to run tests and return understandable results to the engine.
The IFrameworkDriver
interface is defined as follows:
public interface IFrameworkDriver
{
// Gets and sets the unique identifer for this driver
string ID { get; set; }
// Loads the tests in an assembly
string Load(string testAssemblyPath, IDictionary<string, object> settings);
// Counts the test cases that would be executed
int CountTestCases(string filter);
// Executes the tests in an assembly
string Run(ITestEventListener listener, string filter);
// Returns information about the tests in an assembly
string Explore(string filter);
// Cancels an ongoing test run.
void StopRun(bool force);
The strings returned by Run and Explore are XML representations and the filter is also in XML format. See the source code for NUnit3FrameworkDriver and NUnit2FrameworkDriver for sample code.
The filter argument passed to several of the interface methods is an XML string representing the filter. See Test Filters for a description of the format, which is directly understood by the NUnit 3 framework, but which must be converted by the driver to something that is understood by other frameworks.
ITestEventListener
The ITestEventListener
interface is implemented by the Engine and used by each driver to report significant events
during the execution of tests.
namespace NUnit.Engine
{
/// <summary>
/// The ITestEventListener interface is used to receive notices of significant
/// events while a test is running. Its single method accepts an Xml string,
/// which may represent any event generated by the test framework, the driver
/// or any of the runners internal to the engine. Use of Xml means that
/// any driver and framework may add additional events and the engine will
/// simply pass them on through this interface.
/// </summary>
[TypeExtensionPoint(Description = "Allows an extension to process progress reports and other events from the test.")]
public interface ITestEventListener
{
/// <summary>
/// Handle a progress report or other event.
/// </summary>
/// <param name="report">An XML progress report.</param>
void OnTestEvent(string report);
}
}