Skip to Content

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:

  1. They can be used with most coding styles with minor modifications. No need to learn a new coding style.
  2. They can be used also for very performant code, as there is no need to use extra method calls that increase the run time.
  3. 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:

Example: A Test Injection for a Select statement

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.

Example: Test Injection with Redefine Statement in Setup Method

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)

To report this post you need to login first.

2 Comments

You must be Logged on to comment or reply to a post.

  1. Suhas Saha

    Hi Rainer,

    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.

    If i understand correctly you place the TEST-INJECTION in the SETUP & don’t have separate injections in the individual test methods.

    Generally i write separate unit-tests for the positive & negative cases; i tend to use this pattern.

      METHOD positive_case.
        TEST-INJECTION sel_scarr.
          " Given select is successful
          rv_carrname = |flyEmirates|.
        END-TEST-INJECTION.
      ENDMETHOD.
    
      METHOD negative_case.
        TEST-INJECTION sel_scarr.
          " Given the select fails
          sy-subrc = 4.
        END-TEST-INJECTION.
      ENDMETHOD.

    Isn’t it more transparent with this pattern? The developer sees the “Given” clause in the context of the test-method. Your opinions?

    BR, Suhas

    (0) 
    1. Rainer Winkler Post author

      Hi Suhas,

      I place a Test Injection in the setup method normally only with the fail statement. And then I place Test Injections in the test methods. I added a few statements for this in the blog because it was not well written, sorry.

      But this may differ from test to test, because it is also a challenge to have a clear understandable test coding.

      I do not know your pattern with positive and negative case methods. Can you give a more complete example, so that I can understand it better?

      BR,

      Rainer

       

      (0) 

Leave a Reply