ABAP UnitMotivationTesting is a substantial part of the program development process. Tests verify the intended program behaviour. In that sense also debugging or simple text traces are tests. Nevertheless these two methods require human judgement. This soon limits the test possibilities when coming to more complex test scenarios: debug information must be checked step by step and text output very easily becomes so voluminous that they are hardly manageable ("scroll-blindness"). A long-term benefit from testing is only achievable by automation. A unit test tool solves the mentioned problems with developer tests. ABAP Unit is the new unit test tool for ABAP. Tests can be conveniently grouped into test tasks. Test results are condensed and become at once evident. Test tasks can be performed automated. First Steps with ABAP UnitImplementationTests are defined and implemented as local classes inside a main program.
class ltc_Wallet definition for testing. private section. methods check_Liquidity for testing. endclass. class ltc_Wallet implementation. method check_Liquidity. data: my_Wallet type ref to cl_Wallet, liquidity type i. create object my_Wallet. liquidity = my_Wallet->get_Liquidity( ). cl_Aunit_Assert=>assert_Equals( act = liquidity exp = 0 msg = 'New wallet assumed empty' ). my_Wallet->put_In( euros = 12 ). cl_Aunit_Assert=>assert_Equals( act = my_Wallet->liquidity exp = 12 msg = 'As many euros as put in before' ). endmethod. endclass. Note: You might wonder why the test method is defined as a private method. The answer is that all test classes grant friendship to the ABAP Unit test driver. So you should use the visibility of test methods to express if the test method should only be performed when running the respective test class (private), if it should also be performed when running test classes derived from this test class (protected) or if you want to allow delegation, i.e. to offer the execution from other test classes (public). The most common case is certainly the exclusive use of a test method in the context of its test class, so in case of doubt define the test methods in the private section. Test Simplification: Common Test Objects, Test-FixtureTests usually employ well-known, prepared objects. The complete set of such objects is called the "test fixture". Easily the set up of the test fixture can become more laborious as the actual testing itself. Hence the test framework offers two special test methods, which serve for the "setup" and the "teardown" of the test fixture. In continuation of the above example one might need to employ two test wallets with different amounts of money: class lcl_2nd_Wallet_Test definition for testing. private section. methods: setup, check_Withdrawal for testing, check_Remainder for testing. data: f_Wallet type ref to cl_Wallet, f_Balance type i. endclass. class lcl_2nd_Wallet_Test implementation. method setup. create object f_Wallet. f_Balance = 20. f_Wallet->put_In( f_Balance ). endmethod. method check_Withdrawal. data: liquidity type i. f_Wallet->take_Out( f_Balance ). liquidity = f_Wallet->get_Liquidity( ). cl_Aunit_Assert=>assert_Equals( act = liquidity exp = 0 msg = 'Higher debt than liquidity!' ). endmethod. method check_Remainder. data: withdraw type i, liquidity type i. withdraw = f_Balance - 4. f_Wallet->take_Out( withdraw ). liquidity = f_Wallet->get_Liquidity( ). cl_Aunit_Assert=>assert_Equals( act = liquidity exp = 4 msg = 'Reminder after withdrawal wrong!' ). endmethod. endclass. Note the private definition of the fixture method "setup". Fixture methods always apply to their test classes and must neither be inherited by derived test classes nor be called explicitely from other test code. The (befriended) test driver calls the fixture methods in a prescribed order. Test Execution and Test Task CreationWithin the development environment all tests for one program frame can be started using the command "Unit test" under the menu "Execute". The main program is either a class pool (SE24) a function group (SE37) or a report (SE38). Collections of tests can be run by using the code inspector (transaction SCI). There under dynamic tests, you can add unit tests to your test variant. Result PresentationThe result presentation is designed in three detail levels. On the left side the test task is presented hierarchically. A test task contains main programs, which contain test classes. Test methods are part of test classes. Select (double click) a branch of this test task tree. On the right hand side you will find all problems with type and message corresponding to your selection. If you select a message in the upper right window frame, you get detail information for this problem in the lower window: a problem analysis and possibly the failure stack where the problem occurred. You can navigate to the corresponding source by double clicking the failure stack line. |
Further ReadingA Spotlight on ABAP Unit TDD - Test Driven Development |
Comments (3)
Sep 26, 2007
Mike Schernbeck says:
How to test private components of global Classes? To test private or protected ...How to test private components of global Classes?
To test private or protected components of a global class (defined in SE24), simply add the following lines to the local definitions (SE24 -> Goto -> Class-local types -> Local Class Definitions/Types) of the global class to be tested:
Now the test methods defined in your local test class can access all components (attributes, methods, ...) defined as private or protected of the global class to be tested.
Happy Hackin9!
--MIKE
Apr 12, 2008
yudong Geng says:
how to startup debug model ? can i use setp debug?how to startup debug model ? can i use setp debug?
Nov 18, 2008
Will Loew-Blosser says:
Other language NUnit test frameworks similar to ABAP Unit (AUnit) commonly have ...Other language NUnit test frameworks similar to ABAP Unit (AUnit) commonly have project extensions for storing test results. On large applications these are useful for the unit level regression (did a new change break any existing functions). History of test results, help narrow down the nature of a current failure by answering the question of 'When did this break?' or when did it last pass? In systems dependent upon outside components the history can provide a pattern for occasional failures due to factors outside the system under test.
I see that ABAP unit test results can be added into the Code Inspector under the Check Variant.
1. Is it common to use the Code Inspector (SCI) to store AUnit test results?
2. Is it common to use Code Inspector Object variants to collect individual AUnit tests for a regresssion style 'TestSuite'?
3. What reporting or tools exists for Code Inspector history?