Testing an IVI.NET Driver
One of the most important aspects of IVI driver development is authoring and maintaining a suite of driver tests. Nimbus provides integrated unit testing support for IVI.NET drivers.
Creating an IVI.NET Driver Unit Test
Section titled “Creating an IVI.NET Driver Unit Test”All of the unit test code for an IVI.NET driver is housed in a single Visual C# project created by Nimbus. Typically, this project is created upfront with the other driver projects after the New IVI.NET Driver Wizard runs. This is controlled by the Create unit test project check box on the Projects page of the New IVI.NET Driver Wizard.
If the unit test project is not created by the wizard, then it can always be generated at any stage of driver development by right-clicking on the solution node in Solution Explorer and choosing Add New Project….
Structure of an IVI.NET Driver Unit Test
Section titled “Structure of an IVI.NET Driver Unit Test”The IVI.NET driver unit tests are contained within the unit test project, named as follows:
<driverName>UnitTest
This Visual C# project contains one source file per IVI.NET driver interface. Each source file contains one test class for the interface, and the test class contains one test method per driver method or property in that interface.
In addition, one unit test class and file is created for each additional class or struct that is used as a parameter type or return value type. Nimbus refers to these types as free-standing types.
The code below shows an example of a test class.
[TestClass]public class IIviScopeTriggerEdgeTest : BaseTest{ protected IIviDriverIdentity Interface { get; private set; }
public override void _Init() { base._Init();
this.Interface = (this.Driver as IIviScopeTrigger); }
[TestMethod] public void Configure() { string source = "Internal"; double level = 0.1; Ivi.Scope.Slope slope = Ivi.Scope.Slope.Positive; this.Interface.Configure(source, level, slope); }
[TestMethod] public void Slope() {` Ivi.Scope.Slope inVal; Ivi.Scope.Slope outVal;
inVal = Ivi.Scope.Slope.Positive; this.Interface.Slope = inVal; outVal = this.Interface.Slope; Assert.AreEqual(inVal, outVal);
inVal = Ivi.Scope.Slope.Negative; this.Interface.Slope = inVal; outVal = this.Interface.Slope; Assert.AreEqual(inVal, outVal); }}The above test shows the IIviScopeTriggerEdgeTest class that is used to test the methods and properties in the IIviScopeTriggerEdge interface. The class is adorned with a [TestClass] attribute to indicate that the class contains unit test methods. Similarly, each test method within the class is adorned with a [TestMethod] attribute to indicate that it is a test method.
The Slope test method in the example above is used to exercise the IIviScopeTriggerEdge.Slope property in the driver. Note that a single test method is used to test both the property getter and the property setter. In this example, the test method sets the Slope property to the enum value Positive and then immediately reads back the value of the property. The Interface property is used to access driver methods and properties on the IIviScopeTriggerEdge interface. The Assert class is used to compare the value written with the value read back. If the comparison fails, then an exception is thrown and a test failure is reported in the Driver Test Results window. The process is repeated for the Negative enum value.
Test Initialization and Shutdown
Section titled “Test Initialization and Shutdown”Each test class in a unit test project derives from a BaseTest class. The BaseTest class is defined in the BaseTest.cs file of the unit test project. It serves two purposes in driver unit testing:
- It provides a place to define common member variables that many test classes might need, such as the
Driverproperty that can be used by any test method to access any driver method or property. - It defines the
_Initand_Closemethods that are executed before and after each test method in the unit test project.
The key methods of interest in the BaseTest class are the _Init and _Close. and is marked with the [Setup] attribute. This method is executed before each test method. The _Init method is responsible for instantiating the driver and performing any other driver-specific setup the test methods may require. Since every test class derives from the BaseTest class, they all share the same _Init method. If a particular set of unit tests need interface-specific initialization, then the test class can override the definition of _Init in the BaseTest class.
The code below demonstrates how a test class overrides _Init in order to initialize the Driver property and to call the ConfigureWaveform method.
[TestClass]public class IIviScopeTriggerEdgeTest : BaseTest{ protected IIviScopeTriggerEdge Interface { get; private set; }
public override void _Init() { base._Init();
this.Interface = (this.Driver as IIviScopeTriggerEdge);
this.Driver.Waveform.ConfigureWaveform(Waveform.Sine, 1000, 0.1); }
// ... test methods}The _Close method on the BaseTest class is executed after each test method. As with the _Init function, the _Close method can also be customized on a per-test-class basis by overriding it in the test class.
Running Unit Tests
Section titled “Running Unit Tests”The unit tests generated by Nimbus integrate directly with Visual Studio’s native unit testing features. The starting point for executing tests is to bring up the Visual Studio Test View, which is typically docked as a tab within Solution Explorer. To bring up Test View for executing unit tests, click on the Test menu, then choose Windows and select Test View.
Once the Test View window is shown, executing tests proceeds in the exact same fashion as any other Visual Studio unit test. For details on working with the Visual Studio unit testing features, see the MSDN topic Verifying Code by Using Unit Tests.