Unit Test Framework

Applies To: Microsoft Dynamics AX 2012 R3, Microsoft Dynamics AX 2012 R2, Microsoft Dynamics AX 2012 Feature Pack, Microsoft Dynamics AX 2012

The Unit Test framework is tightly integrated into the MorphX IDE of Microsoft Dynamics AX. This integration is very important to test-driven development (TDD) because a unit test can be created alongside the feature code it is testing. For more information about TDD, see Guidelines for Test-Driven Development.

What is a Unit Test

A unit test is code that verifies that feature code has been implemented correctly. If you adhere to the principles of TDD, it is best for the developer who is writing the feature code to first write the unit tests. This puts emphasis on how feature code is consumed and creates a more user friendly application programming interface (API). A unit test, in the context of the Unit Test framework, includes test cases, how test cases are staged with data, and the organization of test cases. A test case is a class that extends the SysTestCase Class class. You can add test methods to test each requirement of the feature code. You should execute test cases when code is changed.

Aa874515.collapse_all(en-us,AX.60).gifNaming Convention

You should name the test class by using the same name as the class it is testing followed by the word Test. This associates the test with the test case. It also enables the Unit Test framework to collect code coverage data for the class. If this naming convention does not fit you testing needs, see the following table for options that exist.

Naming option

Description

Override the SysTestCase.testsElementName Method

Associates the correct class with the test.

Use this option if you do not want to use the naming convention of the same name as the class it is testing followed by the word Test.

Override the SysTestCase.testsElementType Method

Associates the correct type with the test.

Use this option if you want to test a type other than a class. For example, you may want to associate a test with a table.

If code coverage is enabled and the type and name point to a valid code element, then code coverage data is collected.

Aa874515.collapse_all(en-us,AX.60).gifExample

This example illustrates how to declare a test class. You can attach an attribute to the class. This example attaches the SysTestTargetAttribute attribute to specify the target class that is tested Employee. This is usually used to redirect the target to a table.

    [SysTestTargetAttribute('Employee', UtilElementType::Class)]
    class EmployeeTest extends SysTestCase
    {
    }

Aa874515.collapse_all(en-us,AX.60).gifTest Creation Guidelines

The following list contains suggested guidelines for creating tests.

  • You must name the test class using the same name as the class you are testing followed by the word Test.

  • Group tests in a meaningful way. Do not create many similar tests, group them to recognize redundancy.

  • Do not create one test per property or method. That will lead to many simple tests with an unnecessary overhead when you set prerequisites.

  • Refactor your tests to be clean. If it is code shared by test methods on the same class, create a new private method.

  • Avoid complexity and dependencies. It may be better to avoid code sharing in unit testing.

  • Use attributes to add metadata to tests.

The following sections describe the concepts of the Unit Test framework.

Aa874515.collapse_all(en-us,AX.60).gifRun a Test Case

The Unit Test framework provides the following ways to run a test case:

  • From the Unit Test toolbar

  • Programmatically in code from the command prompt

  • From the version control functionality during code check-in

  • From the shortcut menu

For the complete steps, see How to: Run a Test Case.

Aa874515.collapse_all(en-us,AX.60).gifTest Attributes Available

The Unit Test framework provides predefined attributes that you can attach to a test class or test method to provide more information. For example, you can attach the SysTestCheckInTestAttribute attribute to indicate that the test case should be run as a check-in specific test. You can define your own attributes. For more information, see define your own attributes.

The following table describes the predefined attributes.

Test attribute

Description

Where the attribute can be applied

SysTestMethodAttribute

Indicates that a method is a unit test.

Apply the attribute to a method.

SysTestCheckInTestAttribute

Indicates the test is a check-in unit test. A check-in test is run when checking in code to a version control system to ensure a proper level of quality.

Apply the attribute to a method or class.

SysTestNonCheckInTestAttribute

Indicates the test is not a check-in test.

Apply the attribute to a method.

SysTestTargetAttribute(<name>,<type>)

Indicates the application object that is being tested by the test case. Examples of tested objects are class, table, and form.

This attribute take two parameters:

  • Name - string value name of the code element to test.

  • Type - the type of the code element to test. This is optional because a class or table type can be determined by Microsoft Dynamics AX.

Apply the attribute to a class.

SysTestInactiveTestAttribute

Indicates the class or method is deactivated.

Apply the attribute to a method.

Aa874515.collapse_all(en-us,AX.60).gifTest Methods Available

The Unit Test framework provides methods that may meet your testing needs. When you create a test case you will create a class and extend SysTestCase.

The following list contains suggested guidelines when you use assertion methods.

  • Do not assert conditions for which you already have a test.

  • Reference assertion methods where an expected value is specified.

  • Use labels instead of constant strings when you compare strings.

The following table describes the assertion methods on the SysTestCase class. For more information, follow the link for each method.

Method

Description

SysTestAssert.assertEquals Method

Tests if two values are equal.

SysTestAssert.assertFalse Method

Tests if the value is false.

SysTestAssert.assertNotEqual Method

Tests if two values are different.

SysTestAssert.assertNotNull Method

Tests if the value is not null.

SysTestAssert.assertNotSame Method

Tests if the objects referenced are not the same.

SysTestAssert.assertNull Method

Tests if the value is null.

SysTestAssert.assertRealEquals Method

Tests if real values differ by the amount specified in the delta.

SysTestAssert.assertSame Method

Tests if the objects referenced are the same.

SysTestAssert.assertTrue Method

Tests if the value is true.

SysTestAssert.fail Method

Enables you to create your own validation logic and then call the fail method to integrate with the Unit Test framework.

SysTestCase.parmExceptionExpected Method

Tests for an exception that is expected.

Unit Test Toolbar

The Unit Test toolbar enables you to select a test case, run the test case, view the results, and access additional details. Access the toolbar within Microsoft Dynamics AX with the following steps, in a Development Environment, on the toolbar, click Tools, point to Development tools, point to Unit test, and then click Show toolbar.

You can also access the Unit Test toolbar with the following steps, right-click the test case, point to Add-ins, and then select Run tests. This will open the toolbar and click Run for you.

Unit Test Details

Unit Test details provide information about whether the test case passed or failed, when and by whom the test was created, code coverage, and environment settings. You can access these details from the Unit Test toolbar by clicking the Details button.

Aa874515.collapse_all(en-us,AX.60).gifCode Coverage

During test execution, each line of code that is run is recorded. This enables you to see how well the feature area is tested and uncovers where to focus your efforts when you improve tests.

You must enable the debugging feature to capture code coverage. Forms are in the Unit Test framework to provide information about the code coverage for a test case after it is run. For information about how to enable code coverage and access the forms that provide code coverage details, see How to: Access Code Coverage Details.

Aa874515.collapse_all(en-us,AX.60).gifTest Results Output

The Unit Test framework provides various reporting options called listeners. By default, the database is used as a listener when you run the test case using the Unit Test toolbar. You can add listeners in the Unit Test parameters form. For information about how to select additional listeners for your test cases, see How to: Display Test Case Results. The following is a list of the test listeners that the Unit Test framework provides:

  • Database

  • Infolog

  • Infolog (result only)

  • Print window

  • Progress bar

  • Text file

  • XML file

Test Organization

As the number of test cases grows it becomes increasingly more important to organize test cases into groups. Test cases can be grouped into test suites. A test suite can contain one or more test cases and other test suites. This enables test cases to be grouped in a hierarchy. For more information about how to create test suites and projects, see How to: Organize Test Cases.

You can also use attributes to categorize groups of test cases. For example, you might want to group all of the test cases that cross module boundaries as integration tests. You can define a new test attribute class that is named IntegrationTest that inherits from the base test attribute BaseTest. After you compile the attribute class, you can attach the attribute to test cases that you want to run when executing integration level testing. For more information, see How to: Categorize Test Cases Using Attributes.

Aa874515.collapse_all(en-us,AX.60).gifSet Up and Tear Down Shared Data

You can set up and tear down data at the test case or the test suite level. This provides benefits beyond having your test cases organized in a meaningful way. If all your tests share the same set up or tear down code then put it in setUp and tearDown methods of the test case. The framework makes sure that the code is executed before and after each test in your test class.

Another option exists if you want the code to be executed one time before the whole test class and after the last test method. You will create a test suite and override the setUp and tearDown methods.

For more information, see How to: Create Set Up and Tear Down Logic for a Test Case.

Aa874515.collapse_all(en-us,AX.60).gifIsolating Test Cases

The isolation level of a test case varies based on the changes that the test case will make to the data. Each test case could have different needs for isolation based on what data it will change. The Unit Test framework provides four test suites that provide different levels of isolation. The following table describes the test suites by the level of isolation that they provide.

Test suite

Isolation level description

SysTestSuite Class

Provides no isolation. This is the default test suite.

SysTestSuiteCompanyIsolateClass Class

Constructs an empty company account for the test class. All test methods run in this company account, and then the company account is deleted.

SysTestSuiteCompanyIsolateMethod Class

Constructs an empty company account for each test method. The company is used in each test method and then the company account is deleted. This provides the best isolation at the cost of performance. This is caused by a company account created and deleted for each test method.

SysTestSuiteTTS Class

Wraps each test method in a transaction. After the test method has executed, the transaction is aborted.

This isolation level performs well but there are two limitations.

  • Does not work for tests that commit data.

  • The parmExceptionExpected exception is not supported.

Aa874515.collapse_all(en-us,AX.60).gifExample

The following code example illustrates how to use one of the different levels of isolation. You will override the createSuite method in your test case and set the return value to the appropriate test suite.

    class SysTestSuite createSuite()
    {
        // Set the isolation level to construct a company account for the
        // entire test class.
        return new SysTestSuiteCompanyIsolateClass(this);
    }

For a detailed example that creates, runs, and evaluates a test case, see Walkthrough: Testing a Class Using the Unit Test Framework.

See also

How to: Create a Test Case

How to: Run a Test Case

How to: Display Test Case Results

How to: Access Code Coverage Details

How to: Organize Test Cases

How to: Create Set Up and Tear Down Logic for a Test Case

How to: Test Exceptions Using a Test Case

SysTestCase Class

Announcements: New book: "Inside Microsoft Dynamics AX 2012 R3" now available. Get your copy at the MS Press Store.