Skip to Content
Technical Articles

 ‘ABAP Unit’ Test…Initial few Steps before the SPRINT!!

I was exploring on the topic ‘ABAP Unit test ‘ and while doing so , read few very good  blogs , like the one by Nithya Murugesan (can be accessed here ) . Another good one here and the standard sap help .  I found the information is scattered and more can be added to it as well, so i thought of writing my own blog on the topic.

Before I show you how to do it with very simple example, let’s try to answer some basic questions…

What is ABAP Unit?

ABAP Unit is a unit-testing framework that is integrated into the ABAP language.

Unit tests are to ensure the correct behavior of the smallest testable units – such as the methods of classes , performs, .. ABAP unit lets you test the code at unit level like testing each piece separately.

What are the features of ABAP Unit?

  • ABAP Unit tests are written in ABAP. You do not have to learn an additional scripting language for testing.
  • You write tests with the standard ABAP Development Tools (ADT). You do not have to use additional tools for developing tests.
  • ABAP Unit tests are transported with the ABAP repository objects that they test. They are therefore available in all of the systems of your development and testing landscape.
  • You can run ABAP Unit tests as you develop code. You can start tests, for example, directly from the ABAP editor in the ADT.
  • Code coverage measurement is integrated into ABAP Unit testing, so that you can verify the thoroughness of your unit testing and easily find untested code.
  • ABAP Unit is integrated into the Checking Quality of ABAP Code with ATC, so that unit testing can be automated and is part of mass quality testing
  • ABAP Unit test methods have no parameters. No special knowledge or test framework is required to run ABAP tests; they can be run by anyone, and not just by the developer.
  • ABAP Unit tests cannot be executed in productively used ABAP systems.

 

How to write these unit tests?

For writing Unit tests, methods in global class CL_AUNIT_ASSERT  are used . Local classes are implemented to insert test cases. Inside the local class the required method from the global class can be called for testing. These test classes can be written inside the program for which the test is to be done. Production code is not affected by this in anyways.

The class CL_AUNIT_ASSERT contains the following static methods for the verification of test expectations within ABAP Unit test methods:

Method Description
ASSERT_EQUALS Ensures the equality of two data objects. Please note that the arguments are passed by reference. Don’t pass system fields like SY-SUBRC.
ASSERT_EQUALS_F Ensures the inequality of two elementary data objects.
ASSERT_EQUALS_FLOAT Ensures the equality of two decimal floats with a relative tolerance.
ASSERT_DIFFERS Ensures the inequality of two elementary data objects.
ASSERT_BOUND Ensures whether the reference of a reference variable is valid.
ASSERT_NOT_BOUND Ensures whether the reference of a reference variable is invalid.
ASSERT_INITIAL Ensures that a data object has its initial value.
ASSERT_NOT_INITIAL Ensures that a data object does not have its initial value.
ASSERT_SUBRC Requests specific value of SY-SUBRC which is passed by value.
ASSERT_THAT Ensures that the actual value adheres to a given Constraint. Such a constraint can be used to implement custom assertions.
FAIL Terminates the test with an error
ABORT Cancels the test due to a missing context (ideally in setup method).

All the methods have the optional importing parameters MSG, LEVEL, and QUIT, which always have the same meaning:

Parameter Type Description
MSG CSEQUENCE Contains a more detailed description of the error (if applicable)
LEVEL AUNIT_LEVEL

Indicates the severity of the error; the following values are possible

·      TOLERABLE – Minor error (may be tolerable)

·      CRITICAL – Critical error (default value)

·      FATAL – Fatal error

QUIT AUNIT_FLOWCTRL

Determines the flow control in the case of an error. The following values can be passed:

·         NO – No termination in the case of an error; processing of the current method continues after the relevant method is called

·         METHOD – The currently processed test method is terminated (default value)

·      CLASS – The currently processed test class is terminated

·         PROGRAM – The test of the currently processed main program is terminated: The current test class is terminated and all other test classes in the program are ignored.

All the assert methods have the following mandatory importing parameter:

Parameter Type Description
ACT Any The object to be verified

The comparing method ASSERT_EQUALS additionally requires a parameter for the expectation:

Parameter Type Description
EXP Any The identically expected object
TOL f Allows you to compare floating point numbers for the passed  tolerance

What’s the difference between Normal class and Test Class?

Test class and the methods in the test class need to have “FOR TESTING” added in the definition. For e.g.

CLASS demo_class DEFINITION FOR TESTING.

      PRIVATE SECTION.

      PUBLIC SECTION.

      METHODS demo_method FOR TESTING.

 ENDCLASS.

Enough of talking let’s see some code in action. I will show a very basic example to show how it works. The flow will remain same but the code complexity can go to any level.

So, I taking example where in my program ZDEMO_ABAPUT I have class lcl_Customer_SOCount with method Order_Count. The method takes Customer number as input and returns the count of sales orders created for this customer. Very simple isn’t it!!!

As you can see, nothing in the Start-of-Selection yet.

So, now we want to write ABAP unit test to check if this method works fine. To achieve that, we need to implement the local testing class with addition “For Testing” as mentioned earlier.

In the implementation of the test method, m_count in this case, we will call the ABAP unit that we want to test i.e. method lcl_Customer_SOCount to fetch the order count for customer ‘0001000030’.

The method’s result is stored in variable lv_result. Now, we can use methods of global class CL_AUNIT_ASSERT to compare the result with expected result. So in this case, we will use method ASSERT_EQUALS to check is the result value is matching with expected value or not. We need to the Expected value in parameter EXP (hardcoded here). In case the value doesn’t match the expected value it will result in test case failure and message “Something wrong” will be returned.

OK, we are done with the implementation of our test class and method. Now is the time to run the Unit test.

Shall I just execute the program?? And the answer is NO!!

The direct execution with run the program and not the Unit test and nothing will happen in this case as we have actual not written anything in the “Start-of-Selection” event. So, blank screen as shown below will appear if we try to execute the program.

How to do it then??  The answer is, we need to run the program as ABAP unit. That will call the test class and the static method that we have implemented above. To do so, right click on the program and select Coverage As=>ABAP Unit test as shown below.

As a result, you will see the ABAP unit test is trigger and we will see details like what all unit tests passed or failed or caused warning. In this case, out test method m_count got tested and passed the result as the count matched the expected value as is shown in screen shot below.

Now, let’s try the negative test case. To do so, let’s change the expected value to ‘60’ instead of 55 and see what happens.

Let’s run the ABAP Unit test again and see the result.

This time, the result is failed unit test as expected. We can see the message “something wrong’ in the output. Along with that result tells you that there is difference in Expected and Actual value as highlighted in screen shot below.

We can also check, which all pieces of code is code is covered in the ABAP Unit test in the form of code coverage. The same can be checked under “ABAP Coverage” tab as shown below. As we have only one method and we have tested it, it shows 100% covered.

We can also execute the Unit Test from SAP GUI T-Code SE38 also as is shown below.

 

Before we wrap this topic up, let me tell you about Test Fixture.

What is this Test Fixture now?? That’s what you must be thinking now… right?

Test fixture is the test configuration like test data or test objects. This data would be used within the test methods. Fixture methods would be executed before the actual test method gets executed. So when the test is getting performed, the test data or test objects setup in fixture method can be done. In ABAP, the test fixture is achieved using predefined methods. These methods would be called automatically by ABAP framework if they exist in the test class.

Fixture Method Description
SETUP Instance method SETUP would be called before each test within the test class. In this method, you should generally setup your test data which can be leveraged by various different test within the same test class.
TEARDOWN In contrary to SETUP, instance method TEARDOWN would be called after each test within the test class. You should use this method to clear the test data and make sure they are ready to use by the next Test method.
CLASS_SETUP Similar to SETUP, static method CLASS_SETUP would be used to set up the data once before the first test in the class gets executed. The purpose of CLASS_SETUP is to set up the same data like a configuration which would be used by all test methods but NONE of the test method would be modifying it.
CLASS_TEARDOWN Like TEARDOWN, static method TEARDOWN would be used to clear the data once after the last test in the class gets executed.

 

So with inclusion of Fixture methods, the changed code will be like as shown below.

 

Test Class Definition

Test Class Implementation

So, to summarize, we saw how we can write test methods and call the ABAP unit test to test different pieces (units) of our code. Hope you finds this useful.

Keep Learning and Keep Sharing!!

18 Comments
You must be Logged on to comment or reply to a post.
    • Hi Stallone,

      The whole concept of ABAP Unit depends on modularization of your code. We need to write out code in such packets or units at the first place itself so that we can call those units from our test class.

      The ABAP Unit concepts goes well along with Test Driven Development (TDD) approach, that is we design the test case first and the write our productive code.

      Thanks

      Vijay

    • There are Test-Double Frameworks which can help in such situations. For Select-Statements you use the class cl_osql_test_environment.

      You give a table to the class and some entries which you “create” manually. Then everytime you do a select on this table, the select will only return those entries.

       

  • I like your post, it’s a short abstract, well presented, and it’s original because I don’t remember of any other blog post like yours (although there are many ones about ABAP Unit).

    Note that CL_AUNIT_ASSERT is obsolete and was superseded by class CL_ABAP_UNIT_ASSERT since ABAP 7.02 (it’s more about using the right Design Pattern rather than a technical improvement, by making it FINAL). But since then, new methods are only introduced in CL_ABAP_UNIT_ASSERT. And there’s a template in Eclipse ADT that one can invoke by typing “assert” + ctrl-space.

    Also, your post misses a reference to the official ABAP Unit documentation.

  • The more blogs about unit testing and test driven development the better. Far too few people in the ABAP world make use of this.

    I would note that a unit test should not actually read the database. You need a test double of some sort to mock “dependencies” e.g. database access, user input and so forth. These test doubles get created in the SETUP method.

    Actual database access can be tested using the SQL test double framework, though this is only available in the latest ABAP releases.

    Two years ago there was a wonderful open SAP course about unit testing and test driven development.

    The most important point to be made is that if you use unit tests you are forced to make your code testable, and this makes the code better in and of itself i.e. more SOLID.

    Cheersy Cheers

    Paul

    • Totally agree.

      For my point of view, ABAP Unit should not used real data. All the data used in the test should be provided in the “Given” part.

      For the database access, I replace the real class by a mock class.

       

      Your doc is really good, maybe it could be nice to speak about the “Given” “When” “Then”  it helps a lot when you start Abap Unit.

      Thanks

      Fred

    • Thanks Paul for your comments and feedback.

      I actually am glad to see that you read my blog and commented on that too..

      motivated to to more and better..

      Regrads

      Vijay

  • Oh yes, and please do not mention TEST SEAMS as has been requested. They are an abomination.Production code should not know when it is being tested otherwise you end up with what is known as the “Volkswagen Effect” where code behaves one way in real life and another way during a test.

    In order to use a test seam you have to change the productive code, and if you are doing that anyway, then why not change the code to make a call to an instance of a class that can be mocked?