Developing Automated Tests with PNUnit
Figure 1 shows the basic structure and main components of the PNUnit system. Launcher is the program responsible for launching test suites on test machines. It is called by a test configuration file as an argument, reads the file, and sends instructions to the testing machines. It then gathers test results and prints them on the screen. The test configuration (testconf) file is written in XML and contains a definition of the test scenario being created. It defines the appropriate assemblies, specifies where they have to run, and identifies the data to execute. Figure 2, a typical testconf file, contains at least one parallel test section (test group). Each test group runs sequentially. Several tests are defined inside the test group and identified with TestConf labels. Each test inside the group runs in parallel, so each test group defines a parallel scenario.
The TestConf section tells Launcher in which assembly the test resides, which method to invoke, and where the machine is to launch it. Launcher uses this information to communicate with the Agent. To handle communications, Launcher creates a Runner for each test defined in a test group. The Runner is the component that calls the Agent methods. More importantly, Runner handles synchronization via the IPNUnitServices interface that it exports to the tests. Runner also gathers test results and informs Launcher about them.
|Name||Test name you want displayed on the results screen.|
|Assembly||.NET Assembly in which the test resides.|
|TestToRun||Method name that defines the test to be run.|
|Machine||Machine where you want the test executed.|
Agents are located on test machines. Each test machine needs to have at least one Agent waiting to run tests. Agent is a small .NET application that, once started, registers a remote interface called IPNUnitAgent. This is the interface that Runner uses to launch the tests. PNUnitAgent is the actual component inside agents that handles the various processes.
Each time PNUnit receives a call in the IPNUnitAgent::RunTest method (meaning that a new test needs to be launched), it creates a new instance of PNUnitTestRunner. In NUnit parlance, PNUnitTestRunner is a real test runner. It creates a TestDomain instance, runs the test specified by the remote Launcher, collects the results, and notifies the remote Runner. Each test resides on regular assemblies, just as if they were normal NUnit tests.
Where does the NUnit framework fit in? It is the key layer in which PNUnitTestRunner resides. We take advantage of all of NUnit's functionality to load/run tests and collect results.