Implementing Code Tests with ABAP Unit

Objectives

After completing this lesson, you will be able to:

  • Implement a test class
  • Run an ABAP unit test

ABAP Unit

Module Tests

Whenever programmers write or change code, there is a fair chance that they introduce programming errors. Therefore, testing is a crucial part of every development project.

In modern programming, the code is structured in reusable classes and methods. To detect and localize potential programming errors, a thorough test of each modularization unit is needed.

Let's look at an example.

ABAP Unit - Implement Module Tests in ABAP

ABAP Unit is a technique that allows you to implement module tests with the ABAP language. You can trigger test execution manually during development but also automatically on a larger scale and a regular basis.

ABAP Unit tests are implemented as methods of specially designated ABAP classes. These test methods serves as test scripts, with which code under test can be run, and with which the results can be evaluated.

Let's continue with our example.

It is very important that once the tests are there, you can perform them any time and as often as you want: Before initial shipment, after having applied changes to the productive code, or for error analysis when a user reports a problem. And, executing the tests costs you only a few mouse clicks.

Important Features of ABAP Unit

Unit Test Classes

Addition, FOR TESTING, in the class definition distinguishes a test class from an ordinary ABAP class. The addition is available for local classes as well as for global classes.

Addition, RISK LEVEL, is used to assign a risk level to the test. If the addition is missing, risk level CRITICAL is used by default.

Central settings on client level can disallow the execution of tests with certain risk level.

The following risk level values are available:

CRITICAL

A test changes system settings or customizing data

DANGEROUS

A test changes persistent data

HARMLESS

A test does not change system settings or persistent data

Addition DURATION specifies the expected execution time. Central settings on client level can be used to define upper runtime limits for the three values.

The following duration values are available:

SHORT

An imperceptible execution time of some few seconds is expected.

MEDIUM

A noticeable execution time of around a minute is expected.

LONG

A very noticeable execution time of more than one minute is expected.

A test class can have two kinds of methods:

Test Methods

Test methods are defined with addition FOR TESTING after the method name. Each test method represents one test. The ABAP Unit framework performs this test by calling the related test method. Test methods must not have any parameters.

Helper Methods

Helper methods are ordinary methods of the test class. They are not called by the ABAP Unit framework. You can use helper methods to structure the code of your test methods or if you want to reuse the same functionality in several test methods. Helper methods can have any number of parameters.

Note
The ABAP Unit framework is able to call all test methods, even if their visibility is set to PRIVATE. Actually, it is recommended to define test methods in the private section of the test class to make sure the test classes are not called directly anywhere in the code.

A test class should contain at least one test method. A test method must not have any parameters.

When executing the tests of a test class, the ABAP Unit framework calls all tests in the test class in an undetermined order.

If you are going to define local test classes inside a global ABAP class, there is a dedicated place to do so. While ordinary local classes are defined on the Local Types tab, local test classes should be defined on the Test Classes tab.

As illustrated in the figure, to generate the definition part and implementation part of a local test class, ADT offers the code template testClass.

In the demonstration, How to Define and Implement a Test Class, you will see how to invoke this code template.

Unit Test Implementation

Service Class CL_ABAP_UNIT_ASSERT

In general, the implementation of a test method has the following structure:

  1. Execute the productive coding under test
  2. Analyze the outcome
  3. Report unexpected outcome to the ABAP Unit framework

For step 3, the ABAP Unit framework provides global service class CL_ABAP_UNIT_ASSERT. Test methods call the static methods of this class to report errors and to influence the test execution (for example, skip one or several tests because prerequisites are not met).

  • Method fail( ) reports an unconditional error. Usually, a call of this method is surrounded by a control structure like IF … ENDIF. or TRY … ENDTRY to ensure it only is reached under a condition.
  • Methods starting with assert_ check on a certain expectation and report an error if this expectation is not met.
    • Method assert_equals( ), for example, compares the content of two data objects and reports an error if they differ.
    • Method assert_differs( ) does the same but reports an error if the data objects have the same content.

Parameters of Method fail( )

Select each Parameter tab to learn more.

Parameters of Assert-Methods

All assert-methods have optional importing parameters MSG, LEVEL, and QUIT, which always have the same meaning as in method fail( ).

In addition, most assert-methods have an importing parameter ACT for the data object to be verified.

Comparing methods, like assert_equals( ), assert_differs( ), and so on, additionally have a parameter EXP for the expected value.

How to Define and Implement a Test Class

Prerequisites

  • You have an ABAP (Cloud) Project, a transport request, package ZS4D400_01.

  • Your package contains global class ZCL_00_UNIT_TEST_1 and the class is active.

  • You display the source code of global class ZCL_00_UNIT_TEST_1 (Global Class tab).

Unit Test Execution

There are two ways to execute ABAP Unit Tests: Interactive tests during development and Mass tests with ABAP Test Cockpit.

ABAP Unit Test Results

In ADT, the latest ABAP Unit test result is displayed in the ABAP Unit View.

The summary on top displays the total number of test methods that were executed and the overall duration of the test in milliseconds.

Use the check boxes in the summary to filter the result display: Only tests that failed, only tests with warnings, only tests the ended successfully, and so on.

The result itself is displayed as a tree with the repository objects on top, for example, the global class. The nodes on second level represent the local test classes, and the end points correspond to test methods. The icons help you to distinguish between successful tests, failures, and so on.

A left-click selects the test method and displays details on the right hand-side. In the example, you can see the severity (Critical Assertion Error for severity medium), the value of parameter MSG ('No Exception'), and the value of parameter DETAILS (the text expanded below Details).

How to Run a Unit Test and Analyze the Result

In this demonstration, you will see how to execute the unit tests and analyze the results.

Prerequisites

  • You have an ABAP (Cloud) Project, a transport request, package ZS4D401_00.

  • Your package contains global class ZCL_00_UNIT_TEST_2 and the class is active.

  • You display the source code of global class ZCL_00_UNIT_TEST_2 (Global Class tab).

Test Fixtures and Prerequisites

Methods for Test Fixtures

Sometimes a test needs a certain configuration before it can run properly. Such a test configuration is referred as test fixture. A test fixture may consist of test data, test objects, and resources.

To create and remove fixtures, you can implement additional methods in a test class. These methods have predefined names, and they are automatically called by the ABAP runtime environment when the test is executed.

Flow Logic of ABAP Unit Test

This graphic illustrates the program flow of ABAP UNIT for a single test class.

  • At first, the test class is loaded into the program memory. If the test class contains a static constructor (static method CLASS_CONSTRUCTOR) this method is executed as usual.
  • Then, the tests of this test class are performed. Each test starts with the creation of an instance of the test class. If the test class contains an instance constructor (Method CONSTRUCTOR) it is executed as usual.
  • Then, the ABAP Unit framework calls the test method.
  • After the test, the instance is discarded.

If there is more than one test method in the test class, a new instance is created for each test.

After the last test method, the processing of this test class is finished and the framework continues with the next test class, if any.

Phase Model of ABAP Unit Test

This graphic illustrates the Phase Model for ABAP Unit Tests, that is, the points in time at which the framework calls fixture methods.

CLASS_SETUP is called only once, after the static constructor and before the first test.

CLASS_TEARDOWN is called before the framework starts processing of the next test class.

SETUP is called after the instance constructor and before the test execution.

TEARDOWN is called before the framework discards the test class instance.

Reporting Missing Prerequisites

You already learned how to use methods of service class CL_ABAP_UNIT_ASSERT to report failed tests.

But what are you supposed to do in case of a missing prerequisite, for example, missing authorizations? Or a situation where a SETUP method has problems preparing the test?

Exactly for those situations, class CL_ABAP_UNIT_ASSERT contains a method skip( ) and several methods starting with ASSUME_.

The methods work quite similar to fail( ) and the assert-methods, but they look different in the UNIT test result. This makes it easier to distinguish between errors in the tested coding and errors in the system configuration or the test design.

Let's have a look at an example:

Method test_with_fail( ) calls method cl_abap_unit_assert=>fail( ). This method is counted as a failed test and the Failure Trace for this method displays Critical Assertion Error in front of the message text.

Method test_with_skip( ) calls method cl_abap_unit_assert=>skip( ). This method is counted as an aborted test and the Failure Trace for this method displays Missing Prerequisites in front of the message text.

Note
There are no parameters QUIT and LEVEL in methods skip( ) and the assume-methods. With missing prerequisites there is no point in continuing the test, and we do not distinguish between different severities.

How to Run a Complex Unit Test with SETUP

In this demonstration, you will see how to run a more complex test that contains a setup method.

Prerequisites

  • You have an ABAP (Cloud) Project, a transport request, package ZS4D401_00.

  • Your package contains global class ZCL_00_UNIT_TEST_3 and the class is active.

  • You display the source code of global class ZCL_00_UNIT_TEST_3 (Global Class tab).

Log in to track your progress & complete quizzes