Beruflich Dokumente
Kultur Dokumente
ABAP Development: ABAP News for Release 7.50 - Test Seams and Test Injections
The test method of a test class that is a friend of the class to be tested can influence the method by setting the
test flag.
CLASS tst DEFINITION FOR TESTING
RISK LEVEL HARMLESS
DURATION SHORT
FINAL.
PRIVATE SECTION.
METHODS test_input FOR TESTING.
ENDCLASS.
CLASS tst IMPLEMENTATION.
METHOD test_input.
DATA(oref) = NEW cls( ).
oref->test_flag = abap_true.
DATA(input) = oref->get_input( ).
cl_abap_unit_assert=>assert_equals(
EXPORTING
exp = 'xxx'
act = input ).
ENDMETHOD.
ENDCLASS.
Bad style and not governed by any conventions. To overcome this, with ABAP 7.50 the concept of test seams
and test injections is introduced:
CLASS cls DEFINITION.
PUBLIC SECTION.
METHODS get_input
RETURNING
VALUE(input) TYPE string.
ENDCLASS.
CLASS cls IMPLEMENTATION.
METHOD get_input.
ABAP Development: ABAP News for Release 7.50 - Test Seams and Test Injections
TEST-SEAM fake_input.
cl_demo_input=>request( CHANGING field = input ).
END-TEST-SEAM.
ENDMETHOD.
ENDCLASS.
With TEST-SEAM - END-TEST-SEAM a part of the code is defined as a test seam that can be replaced by
test friendly code during testing. No selfdefined attribute is necessary and the test class does not have to be
a friend of the class to be tested any more (as long as public methods are tested only). You don't need an
alternative implementation inside the production code because this is transferred to the test code The test
method might look as follows now:
CLASS tst DEFINITION FOR TESTING
RISK LEVEL HARMLESS
DURATION SHORT
FINAL.
PRIVATE SECTION.
METHODS test_input FOR TESTING.
ENDCLASS.
CLASS tst IMPLEMENTATION.
METHOD test_input.
TEST-INJECTION fake_input.
input = 'xxx'.
END-TEST-INJECTION.
DATA(input) = NEW cls( )->get_input( ).
cl_abap_unit_assert=>assert_equals(
EXPORTING
exp = 'xxx'
act = input ).
ENDMETHOD.
ENDCLASS.
With TEST-INJECTION - END-TEST-INJECTIONM a test injection is defined that replaces the test seam of
the same name during test execution. A test injection can be empty and then simply removes the respective
test seam during testing. Test injections can be defined in test includes of global classes and function groups.
ABAP Development: ABAP News for Release 7.50 - Test Seams and Test Injections
For more information, more use cases, and more examples see Test Seams.
2885 Views Tags: abap
ABAP Development: ABAP News for Release 7.50 - Test Seams and Test Injections
Cheersy Cheers
Paul
Gabor Farkas
27 Jan, 2016 1:33 PM
I think this can be useful but it should be emphasized that the primary (or sole) use of the test seams is to
make legacy code testable - using it for new code seems to be bad practice.
Klaus Ziegler in response to Lucas Ttreault on page 7
3 Dec, 2015 12:18 AM
For example TEST SEAMS do a great job to get totally untested legacy code under test initially. After the initial
tests have been established one has the option to apply further reworks / refactorings.
The use of TEST SEAMS as step stone towards clean code, seems to me as working effectively with legacy
code.
See also
Working effectively with ABAP legacy code - ABAP Test Seams are your friend
Klaus Ziegler in response to Jacques Nomssi on page 6
2 Dec, 2015 11:54 PM
Hello Jacques,
ABAP TEST-SEAMS are available only for programs with dedicated test includes, that is class.pools and
function-pools. Within these program types one can inject into any executable location, including methods of
local classes or even forms.
The package SABP_UNIT_SAMPLE contains the class-pool CL_AU_SAMPLE_TEST_SEAMS which
showcases the use of TEST SEAMS in combination with local classes.
Hope this clarifies
Klaus
See also
Working effectively with ABAP legacy code - ABAP Test Seams are your friend
Horst Keller in response to Jacques Nomssi on page 6
10 Nov, 2015 8:07 AM
ABAP Development: ABAP News for Release 7.50 - Test Seams and Test Injections
Hmm, the translation to English changed the original sentence a bit. A better translation might be "Testseams
do not influence the productive usage of programs". Nevertheless also the above sentence is OK, because test
seams are ignored by the compiler in production systems.
the limit to global classes and function pools is a hindrance for those like me who favor local
classes.
Unfortunately, test injections are possible in test includes only. And test includes are possible for class pools
and function groups only. For other program types there are technical restrictions. (pls. don't ask me why ...)
Horst
Jacques Nomssi
9 Nov, 2015 11:06 PM
Hello Horst,
from the documentation:
Test seams are ignored in production use of programs.
ABAP Development: ABAP News for Release 7.50 - Test Seams and Test Injections
Cheers,
Wilbert
Lucas Ttreault in response to Suhas Saha on page 7
5 Nov, 2015 8:29 PM
The only reason to go write tests for legacy applications is if you intend to make changes to it. Otherwise you're
writing tests for fun and wasting your time.
If you're already making changes to the program then you can figure out a way to build real 'test seams' and
not use these features. Michael Feathers defines test seams as "a place where you can alter behaviour in your
program without editing in that place" in his book Working Effectively with Legacy Code.
I would suggest that anyone who thinks these new features are a good idea go read that book...
Suhas Saha in response to Lucas Ttreault on page 7
5 Nov, 2015 8:14 PM
Writing test code in with your production code is just pollution and I will make sure that my
development team never uses this functionality.
Horst has already made it clear at the very beginning of the blog
If you cannot redesign and rewrite the whole application, as a workaround you make the
code test dependent. This is regarded as bad style, but it helps.
If you need to maintain legacy code without proper SoC, i think this construct is really helpful. If you are
building a new application that's a separate story altogether!
Lucas Ttreault
5 Nov, 2015 7:42 PM
This is crazy! And not at all in a good way.
Writing test code in with your production code is just pollution and I will make sure that my development team
never uses this functionality.
If you can't figure out how to achieve the same with mocks, stubs, test doubles, etc then you have some
seriously bad code that needs refactoring.
Building in ways for people to avoid writing good testable code is not the way to improve the ABAP language.
Tests shouldn't care about the details of HOW something is implemented... Let alone be PART of that
implementation!
Horst Keller in response to Suhas Saha on page 8
5 Nov, 2015 6:53 PM
I thought you're the ABAP boss
ABAP Development: ABAP News for Release 7.50 - Test Seams and Test Injections
Just hope that the real ABAP Boss(es) don't see that ...
Suhas Saha
5 Nov, 2015 4:09 PM
your boss wants you to increase the test coverage of the department - a real life scenario?
Yes, at least in my life.
I thought you're the ABAP boss (at least for me). #justkidding
Anyway i have to admit that with each release ABAP is getting cooler
Horst Keller in response to Wilbert Sison on page 8
5 Nov, 2015 4:01 PM
Hi Wilbert,
I discussed the idea of implicit test seam points, where only the positions after METHOD/FUNCTION and
before ENDMETHOD/ENDFUNCTION make sense, but the result is, that it is not worth the effort. Since Seams
and Injections are located in the same compilation unit anyway, it is not too big an effort to declare the seams
explicitely.
Regards
Horst
Wilbert Sison in response to Horst Keller on page 9
5 Nov, 2015 5:28 AM
Hi Horst,
ABAP Development: ABAP News for Release 7.50 - Test Seams and Test Injections
Hi Wilbert,
I wonder how the unit framework should know which code to replace with what if you do not instrumentalize the
application explicitly.
Are you thinking in the direction of implicit test seam points, similar to the infamous implicit enhancement
points? Or do you think about something like "replace lines from n1 to n2 in procedure x" (application code
must be stable, then)? Or did I miss something obvious?
Best
Horst
Wilbert Sison
29 Oct, 2015 5:01 AM
Hi Horst,
ABAP Development: ABAP News for Release 7.50 - Test Seams and Test Injections
Nice! Locally, we argued a lot about the "mock frameworks". We tried local adapter classes/our custom
Z*Mock/ MockA/ Test Double Framework. Nothing seems to have really bedded down and it's a real pain
getting people to agree on it.
One of the issues was the amount of code that has to be put in place to encapsulate non-testable code. This
is both a time issue (ie to the point where it has to be approved for build) or as you've put it - an issue with
conventions (ie diff developers with different ideas on how to create the testable layer).
This may just help reduce that issue and get people over the line.
Just for consideration : I'd like to be able declare a TEST-INJECTION for a method/function and the unit test
execution can dynamically make the substitution - without the application having defined a TEST-SEAM first.
Is this a possibility? I'm not sure if that dynamic approach will lead to worse code in general. As you've alluded
in your blog - separation of concerns (data/logic/ui) is something that we should aspire to. But we do seem
to have a lot of non-testable OO/Non-OO codebase. Taking it one step further and having the dynamic SEAM
may just lead to more adoption of unit testing.
Kind Regards,
Wilbert
Horst Keller in response to Victor Ionescu on page 10
26 Oct, 2015 11:30 AM
syntax check, yes (of course)
code completion, up to now no, neither in SE80 nor in ADT
Victor Ionescu
26 Oct, 2015 11:20 AM
Nice! I wonder if during implementation of the unit test you actually have access to the context of the source
code being tested.
e.g. does syntax check & auto-complete work within a TEST-INJECTION?