Test Suites
Test suites serve two purposes:
Collection of test cases and test suites
A test suite can contain any number of test cases and other test
suites. This arrangement means that you can group test cases in a
hierarchy.
Test case isolation
Each test case could have different needs for isolation, depending on
what data it changes. In fact, each method within the test case could
have a need for isolation.
Dynamics AX includes the following five test suites that provide different levels of isolation:
SysTestSuite This test suite is the default. It provides no isolation. You can override the setUp and tearDown methods, if necessary. Note that these methods are not the same as the setUp and tearDown methods on the test case.
SysTestSuiteCompanyIsolateClass
This test suite constructs an empty company account for the entire test
class and runs each test method in the company account. After all test
methods have been executed, the company account is deleted.
SysTestSuiteCompanyIsolateMethod
This test suite constructs an empty company account for each test
method and runs the test method in the company account. After the test
methods have been executed, the company account is deleted. This test
suite provides the highest isolation level. It does, however, have a
noticeable effect on performance.
SysTestSuiteTTS
This test suite wraps each test method in a transaction. After the test
method has been completed, the transaction is aborted. This provides a
fast alternative to the company isolation suites, but it has a couple of
limitations:
Exceptions
can’t be handled. Exceptions thrown inside a transaction abort the
transaction automatically and can’t be caught inside the transaction.
Test cases that require data to be committed can’t use this test suite.
SysTestSuiteCompIsolateClassWithTts This test suite provides a combination of SysTestSuiteCompanyIsolateClass and SysTestSuiteTTS.
For each test case, you can override the createSuite
method to select the appropriate suite for your test case. The
following code shows how to use the company isolation test suite in the StackTest class.
public SysTestSuite createSuite() {; return new SysTestSuiteCompanyIsolateClass(this); }
|
We
recommend that you use test projects to group your test cases into
suites. You can, however, create your own class extending from SysTestSuite and programmatically add test cases and other test suites to it. You can run each test suite in one of the following ways:
Type the name in the Test toolbar, and then click Run.
Start the Dynamics AX client with the following command line:
StartupCmd=RunTestProject_<Name of test suite class>
Implement a static main method similar to the one shown in the test case example.
The following code shows the entire StackTest test case. Notice the refactoring and the changes in testQty to make the test case succeed.
class StackTest extends SysTestCase { Stack stack;
public SysTestSuite createSuite() {; return new SysTestSuiteCompanyIsolateClass(this); } public void setUp() {; super(); stack = new Stack(); } void testPushPop() {; stack.push([123]); this.assertEquals([123], stack.pop()); } void testQty() {; stack.push([100]); this.assertEquals(1, stack.qty()); stack.push([200]); this.assertEquals(2, stack.qty()); stack.clear(); this.assertEquals(0, stack.qty()); } void testFailingPop() {; //Assert that an exception is expected. this.parmExceptionExpected(true, "Stack is empty!");
//Call the method expected to throw an exception. stack.pop(); } static void main(args _args) { //This method illustrates how to run a test case programmatically. SysTestRunner runner = new SysTestRunner(classStr(StackTest)); SysTestListenerXML listener = new SysTestListenerXML(@"c:\tmp\StackTest.xml"); ; runner.getResult().addListener(listener); runner.run(); } }
|
Test Projects
The
easiest way to group test cases is to use a test project. You can
create a test project with the Project Designer in MorphX. The test
project can contain groups of test case classes and references to other
test projects. You create a new test project by selecting the project
type Test Project when creating either a shared or private project. A
test project can also contain references to other test projects, which
allows the project to scale across many development teams. You create a
reference by right-clicking the project root node and selecting New
Reference To Test Project.
Figure 1
shows a test project that includes a group of common tests containing
the test case example and references to two other test projects.
Each test project has its
own settings that are persisted with the project definition. This allows
you to specify test project settings that follow the project, even
through import and export, redeployment, and so on.
You can run a test project in several ways:
Right-click it, and then click Run.
Type the name in the Test toolbar, and then click Run.
Start the Dynamics AX client with the following command line:
StartupCmd=RunTestProject_<Name of test project>
Use
the version control functionality during check-in. Check-in stops if
the test fails. You specify the project to run during check-in: from the
Microsoft Dynamics AX drop-down menu, point to Tools\Development
Tools\Version Control\Setup\System Settings.
The Test Toolbar
When you’re working with unit testing, you should open the Test toolbar. You access the Test toolbar, shown in Figure 2, from the Microsoft Dynamics AX drop-down menu: Tools\ Development Tools\Unit Test\Show Toolbar.
You can type the name
of the test case, test suite, or test project you want to run, click Run
to execute it, and then, to get information about the result, click
Details to open the Test Jobs window. The Test Jobs window shows you the
following information collected during the test execution:
The status of each test case
Environmental information
Timing (when the test started and stopped, the duration of the test, and so on)
Code coverage, when enabled
Information sent to the Infolog during the test case execution
Note
The
database listener collects the information displayed in the Test Jobs
window. This listener is automatically registered when you run a test
via the toolbar. |
Code Coverage
The Unit Test
framework can collect code coverage information during execution,
including a percentage value that indicates how thoroughly you have
tested the unit. It also allows you to focus your implementation of the
test cases on the parts not covered by other test cases. In addition,
the Test Jobs window offers a line-by-line view of the code lines
visited. You can enable code coverage in the Unit Test Parameters dialog
box: from the Microsoft Dynamics AX drop-down menu, point to
Tools\Development Tools\Unit Test\Parameters. However, because much more
data is collected, enabling code coverage when executing unit tests
dramatically affects performance during execution. Figure 3 shows an example of the code coverage recorded by the testFailingPop method from the preceding test case example.
The
lines highlighted in gray (lines 1 through 5 and 15 through 16) are the
lines visited during execution. The lines not shaded (lines 6 through
14) haven’t been visited.
Test Listeners
The value of running a test
case is dramatically increased if good reporting options exist. When
running a test case or a suite of tests, you can enable one or more
listeners. Each listener produces its unique output. Dynamics AX
includes many listeners, allowing output to text files, XML files, the
database, the Infolog, the Message window, the Print window, and the
Progress bar. You can enable test listeners in the Unit Test Parameters
dialog box.
Here is the XML generated by the XML listener when you run the StackTest unit test.
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <!-- Created by SysTestListenerXML --> <test-results date="08-07-2008" time="10:51:34" success="false"> <test-suite name="stacktest" time="52" success="true" coverage="61.54"> <results> <test-case name="stacktest.testFailingPop" time="31" success="true" coverage="23.08" /> <test-case name="stacktest.testPushPop" time="0" success="true" coverage="50.00" /> <test-case name="stacktest.testQty" time="21" success="true" coverage="30.77" /> </results> </test-suite> </test-results>
|
Note
Listeners
that generate a file write the file to the application log directory.
The only way to change the file name and location is to manually
register a listener, which we demonstrated in the StackTest code on pages 102 to 103. |
If you must create a new listener to output to a type of media not supported by default, you can do so by following these steps:
1. | Create your own listener class implementing the SysTestListener
interface. Alternatively, you can inherit from one of the existing test
listeners. The methods on your class are invoked when events such as
the start and end of test suites and test cases occur and when test
cases fail. A SysTestListenerData
object is passed to each method. The object contains information about
the test case or suite, coverage data, and much more. By extracting the
information, you can generate output to suit your needs.
|
2. | Modify the base enumeration SysTestListeners.
You must add an entry that has the same name as your listener class and
a label of your choice. This causes the listener to appear in the test
parameters form.
|
Object Model
We’ve described the classes in the Unit Test framework and explained how they interact. Figure 4 shows this information as a UML object model.
The SysTestCase class implements quite a few interfaces. In fact, the Unit Test framework can use any class that implements the SysTestable
interface as a test case. You can implement the other interfaces if you
want more control. It’s far easier, however, to create test case
classes that extend the SysTestCase base class. (For simplicity, Figure 4 doesn’t show the SysTestSuite derived classes or the SysTestListener derived classes.)