ABAP Unit Test Driven Development – Basic Example

By | April 18, 2013 | ABAP Objects, ABAP Unit Test | 42,555 | 5

ABAP Unit is an embedded framework to develop using the Test Driven Development approach. ABAP unit lets you test the code at unit level, independent of the entire solution.

Preface

I have mentioned many times in the various articles about ABAP Unit. With this new series of articles, I would try to help you understand the ABAP Unit and encourage you to leverage it.

ABAP unit lets you test the code at unit level like testing each piece separately. Thus making sure it would function and produce desired results when those piece would be put together in the puzzle.

In this series, I’m planning for these articles:

  1. ABAP Unit Test Driven Development Basic Example
  2. ABAP Unit Test Driven Development Basics
  3. ABAP Unit Test Fixture methods
  4. ABAP Unit Test Global class usage
  5. ABAP Unit Test Wizard to generate Test class – This article
  6. ABAP Unit Test Real time example
  7. ABAP Unit Test Advantages

Basic Example:

As a starting point, let’s start with a basic example so you can get introduced to the framework. This basic example has a class LCL_SUM with a method SUM. This method’s responsibility is to ADD up the numbers. It takes a number as importing parameter and then adds it to itself to derive the result. This method SUM is referred as Production Method in Unit Test concept. I will cover more on the concepts in next article.

The code for Production class method is like this:

 
*
CLASS lcl_sum DEFINITION.
  PUBLIC SECTION.
    METHODS: sum IMPORTING iv_1 TYPE i
                 RETURNING value(rv_sum) TYPE i.
ENDCLASS.                    "lcl_sum DEFINITION
*
START-OF-SELECTION.
* Nothing here yet
*
*
CLASS lcl_sum IMPLEMENTATION.
  METHOD sum.
    rv_sum = iv_1 * iv_1.
  ENDMETHOD.                    "sum
ENDCLASS.                    "lcl_sum IMPLEMENTATION
 

Test Class setup

To declare a class which acts as test class, you would need to add the keyword FOR TESTING when defining the class. This addition separates this class from the production code. Similarly, you need to add the keyword FOR TESTING to the method to make a test method.

 
*
CLASS lcl_test DEFINITION FOR TESTING
  "#AU Risk_Level Harmless
  "#AU Duration   Short
.
  PUBLIC SECTION.
    METHODS: m_sum FOR TESTING.
ENDCLASS.                    "lcl_test DEFINITION
*
CLASS lcl_test IMPLEMENTATION.
  METHOD m_sum.
  ENDMETHOD.                    "m_sum
ENDCLASS.                    "lcl_test IMPLEMENTATION
 

As you might notice here, I have also added pseudo comments #AU Risk_Level and #AU Duration. Prior to ABAP 7.02 Pseudo comments are used to let the framework know more about the ABAP unit class. In the version 7.02 on wards, it has be replaced with addition RISK LEVEL and DURATION.

Test method implementation

In this test method, what you need to do is – Test the production code. So, to be able to test method SUM of LCL_SUM, you would need to instantiate a object reference to LCL_SUM, call the method SUM sending the dummy value. Based on the Dummy value, the method would send you the result – the actual result from the method. Based on Dummy value, you know what would be expected value. E.g. If you pass number 3 to SUM method, it would give you the result of 6 as it is adding 3 to 3.

Once you receive the actual result from the production code or method under test, you need to compare the results. If the actual vs expected is not matching, you need to let the ABAP Unit framework know that something is wrong with the actual vs Expected. To be able to do this you can use the methods from the class CL_AUNIT_ASSERT. For this demo purpose, we would use method ASSERT_EQUALS.

 
*
CLASS lcl_test IMPLEMENTATION.
  METHOD m_sum.
    DATA: o_cut TYPE REF TO lcl_sum.
    DATA: lv_result TYPE i.
*
    CREATE OBJECT o_cut.
    lv_result = o_cut->sum( 3 ).
*
    cl_aunit_assert=>assert_equals(
        exp                  = 6
        act                  = lv_result
        msg                  = 'something wrong'
           ).
  ENDMETHOD.                    "m_sum
ENDCLASS.                    "lcl_test IMPLEMENTATION
 

Initial Run

Now you have your test class and a test method ready. Its time to run it and verify the result. You can run the ABAP Unit from the menu Program → Test → Unit Test.

ABAP Unit Run from Menu

When you see the ABAP Unit Results Display, you would know that there is something wrong. On the right bottom side of the screen, You would see both of the values – Actual 9 vs Expected 6.

ABAP Unit Results Screen

This tells me that, there is something wrong the production method implementation. Yeah, If you look closely the method implementation of the SUM, I have a typo – instead of using Summation, I had used Multiplication. So, I would correct it and re-run the test. This time, since I have a correct code, you would see the ABAP unit results like this:

ABAP Unit Success message

On to Next Article

In the next article, I would cover basics of ABAP Unit along with Test Driven Development (TDD) as well. Stay tuned!

Like It? Share!!

Don't miss an Update

Get notified of the new post, right into your inbox

Naimesh Patel{274 articles}

I'm SAP ABAP Consultant for more than a decade. I like to experiment with ABAP especially OO. I have been SDN Top Contributor.
Follow :

Explore all of his 274 articles.

Load comments

5 Comments

  • NorthernGuy

    Hello Naimesh,

    thanks for this. ABAP Unit is really a black hole for me. So we will see it this will light up the whole thing a bit. First question.
    lcl_test is only for testing. I assume you have to create a normal class for productive use, too. Does it mean you always have to cretae a test class, to the the respective productive class?

    Best regards,

  • Hello Tapio,

    Testing class would always reside within the code. Means, if you have a program where you want to implement ABAP unit, you need to create a Test Class with a test method which can test your productive code. This code would be migrated to Quality and Production systems eventually but ABAP Unit does not get executed in Productive System. I would cover more on this topic in next post – ABAP Unit Basics.

    Thanks,
    Naimesh Patel

  • Wouter Peeters

    Hello Naimesh,

    I’ve read some of the blogs on SCN before, but I cannot imagine creating unit tests. What if you create some complex report or application and it only uses transactional data? Do you build a unit test based on a created example and hope nobody changes it in the future so the tests continue to succeed ( sales order, delivery , … )?

    Regards,
    Wouter

    ( btw, you should repost your blogs on SCN – discussions would be more heavily )

  • Hello Wouter,

    Your thoughts are exactly correct – that many times we develop something which involves DB and other lot of stuff and that makes it very difficult to use the same test over and over.

    I generally, don’t write a Unit test around DB operations Like Selecting the data and Creating SO as they are dependent on so many external factor. When you say complex report, generally it involves like lot of conditions and filling up the final table from several table. What you should do in this case, if you want to write ABAP Unit for that, you populate all the several tables with dummy data, and fill up the expected Final table to compare with the final table from the production method in your test. I would try to cover on this in upcoming articles.

    Regarding SCN – I know SCN would have more discussions but since SCN probably would have similar content I don’t want to re-iterate the same thing.

    Thanks,
    Naimesh Patel

  • NorthernGuy

    Hello Wouters,

    there is a blog in SCN which covers the same topic regarding database dependency.

    http://scn.sap.com/community/abap/testing-and-troubleshooting/blog/2013/03/21/abap-unit-tests-without-database-dependency–dao-concept

    Best regards,
    Tapio

Comments on this Post are now closed. If you have something important to share, you can always contact me.

You seem to be new here. Subscribe to stay connected.