A Spotlight on ABAP Unit Part 1
What ABAP Unit is All About
So you are an ABAP developer and want to write more tests, if it was not too difficult and took too long. You would like to achieve higher quality of your programs, and are unsure of how to accomplish this. After all, you are looking for a way to improve your code without investing much additional effort.
The solution for these problems is ABAP Unit, which is available with ABAP 6.40. This tool brings the well-known benefits of unit testing into the ABAP world. With ABAP Unit, testing for developers has become comfortable and far less time consuming than testing is supposed to be.
This tool is highly integrated both in the programming language and the development environment you are familiar with as an ABAP developer. Above all, it supports individual and mass testing equally well. So ABAP Unit reduces the testing effort during implementation in such a way that once you have understood the way it works you will enjoy
Surely, you are primarily interested in going directly into the matter without much ado. So before giving you any further explanations, let us start by giving you an impression of what working with ABAP unit is like.
This is part 1 of a weblog series on ABAP Unit. If you are interested, you find the other weblogs of the series here: A Spotlight on ABAP Unit Part 2, A Spotlight on ABAP Unit Part 3, A Spotlight on ABAP Unit Part 4, A Spotlight on ABAP Unit Part 5.
Getting Started – a Simplistic Example Program
With this tool you test small portions of code and write the test straight into the ABAP program you want to test. Let us start with a very simple program, for those who have always felt uncomfortable with percentages:
Our first ABAP Unit Test
Now we write a test which checks whether or not, for a given value, our little form does its job correctly:
The tests are implemented in plain ABAP Objects as methods of local test classes. The test classes are part of the program under test (PUT). This can be an executable program, a module pool, a function group, or class pool. The PUT can contain many test classes, and a test class can contain many test methods. All unit tests belonging to one PUT are organized in a test task.
In our fairly basic example there is only one test class with one test method. Both have FOR TESTING added to the declaration. Never forget this specification. The test method should be declared in the private section, because normally it is only called automatically by the test driver of the framework, when the test is executed, but not explicitly by any other part of your code.
In our example the test method test_minus_ten_percent first calls the form minus_ten_percent and sets the change parameter to 200. We compare the result of this calculation with the value we expect (180), by passing them as the parameters act and exp respectively to the method assert_equals of the service class cl_aunit_assert.
It is this method supported by the framework which offers a great service. If there is an error, for example: if the value expected and the actual value differs, the error is shown in the ABAP Unit result view, after the test is executed. By pushing just one button, or rather selecting a menu entry (in our case it is the menu path: Program->Test->Unit Test in the ABAP Editor), all the tests belonging to one task are run, and the errors will be presented to you in a clear and concise display. In case of our example, in the result display you are easily lead to the form:
Obviously, we have mistaken the global data field price for the change parameter fprice. We change the line to: fprice = fprice * ‘0.9’, and run the test again. This time, we get the information that the test was successfully processed, which means: There was no error.
You see, with ABAP Unit the original error we had in our program was easily detected and tracked down. I will treat the details of the result display in another weblog when your knowledge of the ABAP Unit has increased after reading some of my subsequent weblogs. For the time being, I would like to address an objection that seems pretty natural, looking at the simplistic test we have written.
The Strong Use Cases For ABAP Unit: an Outlook
You have now received a first impression of how easy it is to work with ABAP Unit, and you are perhaps convinced that this tool is easy to use. But you might still be a bit undecided and might harbor a slight suspicion: Of course, ABAP Unit is uncomplicated to handle, but what it does is very elementary indeed. Why should I bother to write ten lines of test code to check something I can see at a glance? Does it pay at all to write such simple tests?
Regarding our frugal Percentages program with its minimal form, these objections do not seem utterly pointless. But, first you should remember that the Percentages-report containing the faulty form worked properly. It was only detected by the ABAP Unit test that the report yielded a correct output in the end only by accident and that the form itself was programmed incorrectly.
As a matter of fact, the real strong use cases for ABAP Unit tests are more complex programs, where you want to run a whole battery of small tests at the touch of one button after each modification. This way, you can easily detect side effects when minor changes in one part of a program affect another part which worked correctly so far. I will give you an example for this in part two of this spotlight on ABAP Unit.
Some immediate questions that came to my mind are :
a) If some reports/dialog module programs, get real complex, how useful would this ABAP Unit be ?
b) Does it go beyond subroutines ? Can I check Function Modules , RFC's , BAPI , Class methods ?
c) What is the scope we are talking about ? As we know that subroutines are specific to a program, can we write a class using SE24 and check a particular subroutine in a report program or an include ?
I am sure, in your upcoming weblogs, you would be answering many of these. I did check the help, but I felt it lacked the depth(probably its new).
It is well-known that given a program, 80% of the issues are trivial/oversight and if these can be resolved quickly, then nothing like it.
I would also be interested in how are we going to integrate Code Inspector and ABAP Unit.
the test classes are part of the program under test (PUT).
In fact, this approach is explained in the "NetWeaver Developer’s Guide Using ABAP" (https://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/docs/library/uuid/c1be1003-0701-0010-3795-f87160de6483):
In ABAP Unit, test classes are part of the production code of the TU. This avoids problems arising from the test code being separate from the production code:
- Programs and tests must be kept synchronized.
- You have to ensure that the test and program code are transported together.
- External test code only enables black box tests with an outside perspective of the tested program.
Since the test code is part of the production code, it is easy to keep the unit tests and the
production code up to date if the latter is changed.
Although the test code and the production code are transported through the system landscape, ABAP unit tests do not increase the load on the production system. By default, the test code is not compiled in the production system. Therefore, the test code can never be executed in the production system.
On the other hand, this idea is quite different from what suggested by other unit testing frameworks.
For instance, the documentation of "Test::Unit - Ruby Unit Testing Framework" (http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html) reads:
It‘s handy to collect a bunch of related tests, each test represented by a method, into a common test class that knows how to run them.
The tests will be in a separate class from the code they‘re testing for a couple of reasons. First of all, it allows your code to stay uncluttered with test code, making it easier to maintain. Second, it allows the tests to be stripped out for deployment, since they‘re really there for you, the developer, and your users don‘t need them. Third, and most importantly, it allows you to set up a common test fixture for your tests to run against.
Programs and tests might be kept synchronized even if they don't belong to the same compilation unit.
Moreover, you can assure that the test and program code are transported together by saving them in the same package.
Finally I don't have a thourough understanding of the reason why external tests only allow "black box tests with an outside perspective".
Can you drill down a bit deaper into these aspects?
Thanks & Reagards, Davide
Possibly there is a slight confusion because the article focuses on good unit tests in ruby and not on unit testing in general.
For good reasons the article highlights that a strict separation between test and domain code is necessary. Well ABAP Unit complies with excellence, the compiler enforces domain code not to mix up or grab into test code. There is a clear distinction between test and domain code. By the unique feature of ABAP to strip the test byte code in production systems it is also guaranteed that there will be no extra load on such systems.
If you should give make your tests public or not feels a like bit a philosophic question to me. Well formed test code not only serves for verification but also for documentation purposes. Moreover it is a feature not a must. If you prefer having a strong separation you can do. Just put your unit tests into programs of another package and transport layer.
Can ABAP UNIT be used for Interaction Center Web client or Webdynpro ABAP ? If that is the case i can just run the UNIT test to check if the IC application is running fine ..
I have FM within FM. Can we implement unit tests for such types of development too?
If yes than can I get some such examples please.