Unit testing advantages
Defining unit classes
Exception handling in unit testing
Using the unit test browser
We will start with a brief explanation of testing and its various types. We will then see what unit testing and test-driven development are. We will also cover the advantages of unit testing. We will then cover creation of the unit test method and classes in detail and the relevant coding and class and methods involved. Finally, we will see a full-fledged programming demo.
We cover how to execute the unit test and check results with and without the Code Inspector. We end the chapter with a note on the unit test browser that is available for searching and displaying unit test classes residing in the ABAP system.
Testing Need and Phases
Before going into the details of unit testing, let’s first see why the need for testing arises in program development.
Within a project’s development lifecycle, there may be a number of stages and phases. There is a need to test programs or products in both the development and integration stages.
There is less chance of bugs and problems arising in the product. Testing allows us to make a more accurate and better quality product for our customers.
Good testing done in the early stages is more cost effective than later testing.
Testing improves customers’ confidence in the products.
- 1.
Unit testing. This is the initial testing level. Basic (individual) units of codes are checked in order to ensure they work as required. Each code portion is subjected to a set of test scenarios or cases. Unit testing may be done manually or be automated. However, developers usually perform automated tests.
- 2.
Integration component testing. As the name indicates, this checks the integration testing of different units (or modules) that have been unit tested. These are grouped in a number of ways to confirm the correctness of integration and communication.
- 3.
System/UI testing. This emphasizes the UI (User Interface) and can be done manually or via automated tools. It confirms the characteristics and state of the user interface elements. This may be done by sets of test cases.
- 4.
Acceptance testing. This is based on the Quality Assurance (QA) approach and determines which features of an application work (or do not work). The team has the option to discover and test the applications(s) in real-time. Usually, test cases are not made in advance. While testing, the team decides which application is next to be tested and how many days are to be given to a feature during the testing phase.
Note
Other than unit testing, the internal details of an application are visible as a “black box” to the test team during the testing stage.
Basics of ABAP Unit Test Driven Development
While writing the test code, we must keep in mind several aspects pertaining to the requirements, code test, and production methods. These aspects include definition of the attributes and the method parameters.
As mentioned, there are two separate methods—test methods and production methods. The production methods are also called the methods under test, whereas the class where the production code resides is known as the class under test.
Every time we want to check a small unit and its functioning is working as normal, we use unit testing. A unit is simply termed the smallest testable part of an application. This can be a class or a method, which can be separated from the other code while being checked if it functions correctly.
You should also consider and manually compute the expected result corresponding to the respective inputs. For example, if you have a method for doubling a number, we can first expected value (2 ∗ X ). We can then compare this with the actual value computed by the program code.
We specify the Risk Level and Duration test properties while designing the test.
Risk level, as the name indicates, is the risk of the test.
Harmless. As the name indicates, executing this test will not affect a process and will not make any changes to the database. This is the default.
Dangerous/alarming. Such tests change data in the database.
Critical. These are the critical tests and changes that customize the database/persistent data.
As far as Duration goes, the ABAP unit framework does not run tests with a higher duration than that specified in the client level configuration in the SAUNIT_CLIENT_SETUP transaction.
Short. Refers to tests that run very quickly (default setting at the client level). Typically, this is less than 60 seconds.
Medium. Refers to tests running slightly longer than short values. These lie in the range of 60 to 600 seconds.
Long. These tests take a considerable amount of time to execute; more than 600 seconds.
Unit Test Benefits
Are very fast in execution. Many thousands of tests can be executed per second.
Emphasize small portions of the product.
Are written separately from the production code.
Unit tests cover 75 to 85 percent of the code. They are fast and accurate. Unit tests help point to the exact location where the code is buggy. Consistent unit test repetition helps make an application more stable and perform better.
In contrast to the other tests mentioned earlier, when using unit testing you need to have a good knowledge of system architecture. Unit testing is referred to gray box (or white box) testing and are defined by the ABAP developer.
Like other programming languages, ABAP has a unit testing framework. Within the framework, the processes needed for testing are embedded into the IDE. This allows developers to run unit tests in each compilation of the test program.
Unit tests do not interact with external coding or external systems. They are executed in a secluded environment. Unit tests are typically run on test methods, which reside in test classes.
Unit testing is applicable in situations where carrying out tests serves a definite purpose or meaning. Usually, the business layer is good for executing tests and is where unit testing mainly focuses.
You must code automated tests as well as testable code. After executing the unit tests, you can amend the source code in order to fix bugs and bring the code to a testable state.
You have to ensure that when a correction is done in one unit that no other code units are affected.
A test method can have a number of input (importing) parameters and usually a single output parameter. You can use transactions SE38 and SE80 to create an ABAP unit. You also have another option for doing unit testing in the ABAP Unit Framework, which is via the Eclipse IDE. This is contained in the ABAP Development Tools (ADT), so you need to only install the respective add-on in Eclipse. We discuss unit test using Eclipse in Chapter 8.
Within the “then” portion of the test method, the resulting value is checked by comparing the expected value with the actual value the method under test returns. If the two results differ, the ABAP Test Framework issues an error. Say we have a class called CL_AUNIT_ASSERT, which provides a number of utility methods. For comparison purposes, we use the ASSERT_EQUALS method of the CL_AUNIT_ASSERT class .
The main challenge is to figure out the cases to cover during testing. Unit tests are made by the developer, since the developer who coded the product is the best person to know how the functionality can be tested. When we do ample testing of the small parts of our product, there will be less time and effort needed in debugging and fixing issues later on.
Demo Example
As mentioned earlier, the ABAP Unit Framework allows developers to test program coding at the unit level, i.e., check each unit code independently and separately without worrying about the entire solution. Checking these smaller units ensures that when they are all put together into a bigger solution, they will function without error. This unit framework allows us to use what is called the test-driven development approach.
Our code has a class called my_class and has a method called SQUARE . The purpose of the method is to square the number it imports and return the square as a parameter. The square method is called the production method, whereas my_class is referred to as the production class in the Unit Test Framework.
We will now code a class to act as a test class. We call this mytestclass. In order to code it, we need to add FOR TESTING to the method definition. Likewise, we add the keyword FOR TESTING to our CHECK_SQUARE method to designate it as a test method. These additions separate the class from the productive code.
Note
Before ABAP 7.02, pseudo comments allowed the framework to learn about the ABAP unit class. From 7.02 onward, we use addition RISK LEVEL and DURATION in the class definition.
Recall that the risk level can be critical, dangerous, or harmless and the duration can be short, medium, and long.
- 1.
Create an object of my_class.
- 2.
Call the SQUARE method of this class. A value will be supplied to the method and the result will be calculated in the method and returned (if we supplied 10, we would expect a squared value of 100 to be returned).
- 3.
Compare the actual value returned from the square method to our expected result.
If these two match, no error is present.
On the other hand, if actual and expected result do not match, we need to inform the ABAP Unit Framework of this erroneous state.
- 4.
For this, we use methods of the standard class CL_AUNIT_ASSERT. In our example we will use the ASSERT_EQUALS method of this class.
As you can see, we called the square method . We then call the ASSERT_EQUALS method . This method has three parameters—expected (EXP), actual (AC), and message (MSG). We supply the expected value 100 to the method, the actual value of the square computed by the test method square, and the message to be displayed if the values do not match.
Note
It is not mandatory for a test method to have this pattern. We show this style for consistency and better understanding
Executing a Unit Test
Now that the code is complete, we will execute the unit test and check the results.
For Class Builder, use Class ➤ Unit Test.
For programs using SE38, use Program ➤ Execute ➤ Unit Tests.
For the Function Module (transaction SE37), use Function Module ➤ Test ➤ Unit Test.
The task is shown in the form of a tree showing the program name, class name, and method name. We also see the test class and method in which the problem has occurred. Here, we are also shown the number of failed assertion(s).
On the right-bottom part of screen (see Figure 7-6), we can see the actual and expected values shown as 20 and 100, respectively. This clearly shows the developer that the production method implementation is not correct. We also can display the line number where the error occurred. By simply double-clicking the line number, we can go to the exact line within the source code.
As mentioned earlier, there is a mistake in the implementation of the production method. Instead of multiplication. we used addition. Once we correct the method and rerun the test, the results will not show any error messages.
Methods in CL_ABAP_UNIT_ASSERT for Testing
The CL_ABAP_UNIT_ASSERT class has several methods, known as assertion methods. They are used to pass messages to the ABAP Unit engine.
ASSERT_EQUALS
ASSERT_DIFFERS
ASSERT_BOUND
ASSERT_NOT_BOUND
ASSERT_INITIAL
ASSERT_NOT_INITIAL
ASSERT_CHAR_CP
ASSERT_CHAR_NP
ASSERT_EQUALS_F
FAIL
ABORT
ASSERT_EQUALS. Checks if two data objects are equal.
ASSERT_DIFFERS. Checks if two data objects are different.
ASSERT_BOUND. Checks if the reference variable is pointing to a valid reference.
ASSERT_NOT_BOUND. Checks for the invalidity (initial) of the reference of a reference variable.
ASSERT_NOT_INITIAL. Determines whether a data object is storing its initial value.
ASSERT_SUBRC. Determines whether the return code variable SY-SUBRC has a specific value.
ACT. Actual result
EXP. Expected result
MSG. Message to be displayed
LEVEL. Error level (tolerable/critical/fatal)
- Quit. Defines how the flow level is controlled when the test fails. Possible values of Quit include:
No (0). No action taken. The execution of the current test method continues.
Method (1). The test method is interrupted.
Class (2). The test class is interrupted.
Program (3). All test classes in the tested program are stopped.
- Level. Has the following values:
Tolerable
Critical
Fatal
TOL. Tolerance
Actual result: 99
Expected result: 100
Tolerance specified as 0.9999
Difference = Expected Result - Actual Result
In this case, the difference is 100 – 99 = 1. Since 1 is greater than the tolerance limit (.9999), this is above the tolerance limit. Hence, an error would be displayed.
SETUP( ). An instance method run prior to each test or execution of a test method.
TEARDOWN( ). An instance method run after execution of a test method.
CLASS_SETUP( ). A static method run once prior to all the tests of a given class. This is used for initializing variables that will be used in the tests.
CLASS_TEARDOWN( ). A static method that is run after all tests of the class have been run. This is used for clearing any data variables used.
These optional methods are also known as fixture methods . These names are predefined so they can be recognized at execution time.
ABAP Unit Results in Code Inspector
We also can see the ABAP unit test results using the Code Inspector. Within the variant, we need to check the ABAP unit test within the Dynamic Tests category. Let’s see how this is done.
Once this is done, we can use this variant in our code inspections.
As an example, we have executed this inspection on the program we earlier created in the chapter involving squares. Clicking the message will take us to the exact location where the error occurred.
Exceptions in ABAP Unit Tests
As with classes in general, exceptions may occur in unit test classes as well. If an exception occurs with a method, the unit test fails. The exception may be reported as the reason for the failure. If the method declares and includes the exception in the signature, the test exception may be propagated to the ABAP runtime.
Enabling and Executing ABAP Unit Browser
SAP provides an ABAP unit browser for searching and viewing unit test classes residing within the system. The ABAP unit browser is embedded in transaction SE80. By default, the ABAP unit browser is switched off, and should be first switched on in order to be used.
Call transaction SE80. By default, the screen on the left side will appear, as shown in Figure 7-14.
As you will see, there is only a Repository Browser button on the top. We want to include a second button by the name Unit Browser over here.
- Choose Utilities ➤ Settings. This will open the dialog box shown in Figure 7-15.
Click the Workbench (General) Settings. Then, in the browser selection, click the ABAP Unit Browser button and click the Continue button.
- Next, you will see that the ABAP Unit Browser button will appear, as shown in SE80. It’s shown in the left pane in Figure 7-16.
- Now click the ABAP Unit Browser button and choose Package in the first list box. Enter $tmp in the field provided (see Figure 7-17). We will then click the Display button. (As an example, we will browse through local objects, so we have used $tmp.) Then, click the Display button.
- You will see that the various unit test classes appear, as shown in Figure 7-18. As a matter of example, we had earlier created a global test class by the name ZSt19_class.
Double-clicking the unit class name in the left pane will show details of the class in the right pane.
Summary
In this chapter, we covered various types of testing. We learned what unit testing and test-driven development are and covered the advantages of unit testing. Finally, we saw a full-fledged programming demo. We also executed a unit test and checked the results with and without the Code Inspector. We ended the chapter with a note on the unit test browser, which is available for searching and displaying unit test classes residing in the ABAP system.