Test seams are language constructs designed especially for unit tests and are implemented using the following statements:
Test seams have the following properties:
- Test seams do not affect the production use of programs. No injection takes place, rather the original code is executed.
- A program can contain more than one test seam.
- Multiple injections can be defined for a single test seam.
- Injections can only be created in test classes that are defined in a test include. Test seams can be used in all executable units of a master program that includes a test include , including local classes and subroutines .
- Unit tests can make injections while test methods or the
setupmethod are being executed.
- If injections are repeated in the same test seam, the last injection is the active injection.
7.31 | 7.40 | 7.54
- Test seams are a simple way of replacing or expanding source code in production parts of a program for test purposes. If, for example, the behavior of certain statements prevents tests from running, the unit test can replace them with suitable alternatives. Typical scenarios are:
- Authorization checks
- Reading persistent data
- Modifying persistent data
- Creating test doubles
- Test seams are intended mainly for use with legacy code that, due to separation of concerns, is no suitable for unit tests. New programs, on the other hand, should be modular in such a way that test seams are made unnecessary.
Example for authorization checks
An injection can use the statement
to bypass the dependency of a unit test on the authorizations of the current user by setting a suitable return code.
AUTHORITY-CHECK OBJECT 'S_CTS_ADMI'
ID 'CTS_ADMFCT' FIELD 'TABL'.
|IF sy-subrc = 0.
is_authorized = abap_true.
sy-subrc = 0.
Example for reading persistent data
It is often not possible to make assumptions about the content of database tables or other repositories in unit tests. Using test seams, unit tests can bypass the dependencies of persistent data by replacing it with constructed data.
WHERE carrid IN @carrid_range AND
fldate EQ @sy-datum
INTO TABLE @flights.
VALUE #( ( carrid = 'LHA'
connid = 100 )
( carrid = 'AFR'
connid = 900 ) ).
Example for changing persistent data
When they run, unit tests must not modify production content of database tables or other repositories. Using test seams, unit tests can record the operands of modifying database operations or compare actual changes with expected changes. In the following source code section compares, the injection compares the change values with a public static attribute.
FROM TABLE @new_flights.
act = new_flights
exp = global_buffer=>exp_flights ).
Example for a test double
In the following source code section, the production source text of class that is dependent on database content is instantiated. The unit test injects the instantiated test double at the location of the production object.
me->oref = NEW #( ).
me->oref = NEW dummy_class( ).
See also the class CL_AU_SAMPLE_TEST_SEAMS in the package SABP_UNIT_SAMPLE.