ABAP Test Seam for Unit Test with external dependencies – Personal guideline
After 1 1/2 years of using the ABAP Test Seam statement, it is time for a blog where I describe the patterns I am using when I use this statement.
You can use Test Seam in classes and functions. It is also possible to use Test Seams in local classes of programs, but that is quite uncommon.
The ABAP Test Seam statement makes it very easy to write Unit Tests for ABAP code with external dependencies. There are other techniques to handle external dependencies, but these require more sophisticated object oriented coding patterns and increase normally also the runtime. This happens because they typically require additional method executions (To move the coding with external dependencies into a separate class that can be replaced by mock logic during the test).
The runtime is increased significantly if methods are called, because ABAP is not developed to enable fast method calls. It contains instead powerfull complex statements whose performance is optimized. The last time I measured the time needed to call a ABAP method I measured 160 ns. This is small but not in all cases neglible. In C this time for instance will often be zero because the compiler inserts the called coding directly.
The main advantages of Test Seams are in my understanding:
- They can be used with most coding styles with minor modifications. No need to learn a new coding style.
- They can be used also for very performant code, as there is no need to use extra method calls that increase the run time.
- They are simple to understand and handle.
The ABAP statements TEST-SEAM and TEST-INJECTION are available since ABAP 7.50 and already explained elsewhere:
The blog where Horst Keller introduced the statement: ABAP News for Release 7.50 – Test Seams and Test Injections
The next blog is by Klaus Ziegler, who is in my understaning one of the inventors of the statement: Working effectively with ABAP legacy code – ABAP Test Seams are your friend
This is my first blog on this topic: Test Seams and Test Injections simplify ABAP Unit Tests
And the SAP Help: Test Seams Documentation
I found three rules and one pattern very helpfull when ABAP Test Seams are used. These are:
Rule 1 – Implement inserted test coding correctly
Example: A Select statement in a Test Seam
A select statement is correctly replaced by an If condition where the SY-SUBRC is correctly set:
During my first experiments with Test Seams I did not do this. This caused a lot of confusion when I changed the coding and expected the test to fail. But they did not. Assume that in the example above the injected coding would be
carrnam = |Lufthansa|.
The initial Test would pass. But it would also pass if the value of carrid would not be LH.
Rule 2 – Monitor whether all Test Seams have a Test Injection
Add for each Test Seam a Test Injection in the setup method of the unit test. Normally I insert a fail statement here. This makes it easy to recognize if it was forgotten to implement a test injection in a test. If this pattern is not used it can happen that test injections are in a unit test only to prevent that an injection is forgotten. This makes unit tests more difficult to read.
I then add the Test Injection in the test methods as required. Sometimes I might insert an empty coding in th setup method or add a comment in the setup method, that there is no Test Injection in the setup method. This depends on the details what is tested.
Sometimes it is helpfull to use a variable that is set in the test in the test injection. This has to be done with a trick. The reason is, that the coding in the Test Injection is checked in the context of the tested coding. Instead the following pattern is to be used. I found it in the blog by Klaus Ziegler Working effectively with ABAP legacy code – ABAP Test Seams are your friend and described it in my blog in more detail: Test Seams and Test Injections simplify ABAP Unit Tests
Pattern 1 – Use static attributes of a local class for testing
Static attributes of a local class with the attribut “for testing” can be used in the Unit Test and in the injected code between the TEST-INJECTION statement.
Rule 3 – Use static attributes of local class only for a single injection
If you use static attributes for a specific tests do not use it for another injection also. If you do, the second time you set it will have the wrong value for the first injection you wanted to use it.
(This rule was added 18 July 2018)