
{"id":7853,"date":"2019-02-08T14:44:22","date_gmt":"2019-02-08T14:44:22","guid":{"rendered":"https:\/\/rax-stg-wp-aws.com\/blogs\/abap-programming-approach-to-writing-testable-code\/"},"modified":"2026-11-03T19:29:06","modified_gmt":"2026-11-03T19:29:06","slug":"abap-programming-approach-to-writing-testable-code","status":"publish","type":"blogs","link":"https:\/\/www.rackspace.com\/en-gb\/blogs\/abap-programming-approach-to-writing-testable-code\/","title":{"rendered":"ABAP Programming approach to writing testable code"},"content":{"rendered":"<p><strong>&nbsp;Introduction<\/strong><\/p>\n<p>No matter how good our code is, if we cannot test it properly, it is a tedious&nbsp;task to modify or enhance it. This situation results in problems for both users and&nbsp;developers.<\/p>\n<p>Because requirements frequently change during the development process, you&nbsp;constantly need to modify the code. Sometimes the requirement changes might&nbsp;involve a complete change in the process.<\/p>\n<p>Writing testable code is always more difficult than actually testing your code.&nbsp;However, in the long run, testable code makes life easier for the developer&nbsp;than the one who is testing the code.<\/p>\n<p>You may face the following situations:<\/p>\n<ul>\n<li>You are asked to change your own code. You might like this idea, but you&nbsp;don&#8217;t remember the details of the code that you originally wrote.&nbsp; &nbsp;You have to change someone else\u2019s code. This situation is not ideal, but it&nbsp;is common.<\/li>\n<\/ul>\n<p>\nHow can you be sure that you won\u2019t break anything after implementing changes&nbsp;if you cannot test the code? The traditional approaches that we\u2019ve seen over&nbsp;the years include the following:&nbsp;<\/p>\n<p>Write some tests in the development environment, and check that there are no<br \/>\ndumps.<\/p>\n<ul>\n<li>Transfer to the quality testing environment, and test again.<\/li>\n<li>Deliver to the functional consultant to let them test at their end.<\/li>\n<li>Release to the user for User Acceptance Testing (UAT).<br \/>\n\t&nbsp;<\/li>\n<\/ul>\n<p>When someone encounters an issue with the code, we&#8217;re likely to blame a&nbsp;difference in test data. Even if it\u2019s true, the real issue is that the&nbsp;software is poorly written and not robust enough. You cannot test it without&nbsp;real data. In other words, the program has dependencies, and you can&#8217;t test it.&nbsp;<\/p>\n<p><strong>Test-driven development and ABAP<\/strong><\/p>\n<p>Test-driven development (TDD) solves these issues by enabling you to deliver&nbsp;high-quality software and products.<\/p>\n<p>TDD is a software development process that relies on the repetition of a very&nbsp;short development cycle: requirements turn into very specific test cases,&nbsp;then the software is improved to pass only the new tests. (Wikipedia)<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/blog_article_images\/26521-body-Picture1_32.png\" alt=\"ABAP Pic 1\" \/><\/p>\n<p>In ABAP, all of the code gets converted into an ABAP Unit, which is nothing&nbsp;more than a specific piece of code. Testing ABAP units is not necessarily a&nbsp;purely technical process performed by the developers. Because you don&#8217;t need a&nbsp;developer key to run unit tests for an ABAP program, anyone with the proper&nbsp;authorization to display programs or classes should be able to run the tests.&nbsp;As a best practice, involve our business experts and functional consultants in&nbsp;testing whenever you can.&nbsp;<\/p>\n<p><strong>&nbsp;Behavior-driven development<\/strong><\/p>\n<p>Behavior-driven development (BDD) is a software development process that emerged from TDD. BDD combines the general techniques and principles of TDD&nbsp;with ideas from domain-driven design and object-oriented analysis and design to&nbsp;provide software development and management teams with shared tools and a&nbsp;shared process to collaborate on software development. (Wikipedia)<\/p>\n<p>BDD simplifies testing methods, so the methods labeled for testing in an ABAP&nbsp;unit should have descriptions that make sense to a developer, business analyst,&nbsp;and users. You can achieve this by setting each test method so that it fulfills&nbsp;the phrase `IT SHOULD`.Then inside of this method, you create three helper methods by using the&nbsp;following pattern:<\/p>\n<ul>\n<li><em>`GIVEN<\/em>`: Include inputs or initial conditions that the program receives.<\/li>\n<li>`<em>WHEN<\/em>`: Describe the activities that you are going to test.<\/li>\n<li>`<em>THEN`:<\/em> Specify the success and failure outcomes.<\/li>\n<\/ul>\n<p><strong>Sample refactored test class<\/strong><\/p>\n<p>The following code sample, which uses dummy code to define the process, is a&nbsp;sample refactored test class for the <strong>zcl_instruments<\/strong>&nbsp;class.<\/p>\n<p><em>class lcl_test_class definition deferred.<\/em><\/p>\n<p><em>&#8220;Allow access to private components within the class<\/em><\/p>\n<p><em>class zcl_instruments definition local friends lcl_test_class.<\/em><\/p>\n<p><em>class lcl_test_class definition final for testing<br \/>\n&nbsp; duration short<br \/>\n&nbsp; risk level harmless.<\/em><\/p>\n<p><em>&nbsp; private section.<\/em><\/p>\n<p><em>&nbsp; &nbsp; types: ty_guitars type standard table of zguitars with empty key.<\/em><\/p>\n<p><em>&nbsp; &nbsp; data: mo_class_under_test type ref to zcl_instruments,<br \/>\n&nbsp;&nbsp; &nbsp; &nbsp; guitar_instance type ref to zcl_guitar,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;guitars type ty_guitars.<br \/>\n&nbsp;&nbsp; &nbsp; &nbsp; guitar_to_add type ref to zcl_guitar.<br \/>\n&nbsp;&nbsp; &nbsp; &nbsp; guitar_to_search type ref to zcl_guitar.<br \/>\n&nbsp;&nbsp; &nbsp; &nbsp; mo_exception_raised type abap_bool.<br \/>\n&nbsp;&nbsp; &nbsp; &nbsp; found_guitars type zcl_instruments=&gt;guitars_tab.<\/em><\/p>\n<p>You should include `IT SHOULD` methods that come right out of the functional specification document.<\/p>\n<p>In this example, the **zcl_instruments** class should be able to:<\/p>\n<ul>\n<li>Add guitars to instruments.<\/li>\n<li>Restrict duplicity.<\/li>\n<li>Search for any specific guitar in instruments.<\/li>\n<\/ul>\n<p>\n<em>&nbsp; &nbsp; methods:<br \/>\n&nbsp; &nbsp; &nbsp; setup,<br \/>\n&nbsp; &nbsp; &nbsp; &#8220;User Acceptance tests:<\/em><\/p>\n<p><em>&nbsp; &nbsp; &nbsp; &#8220;IT SHOULD&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..<br \/>\n&nbsp; &nbsp; &nbsp; add_guitar_to_instruments for testing,<br \/>\n&nbsp; &nbsp; &nbsp; add_duplicate_and_get_error for testing,<br \/>\n&nbsp; &nbsp; &nbsp; search_within_the_instruments for testing,<\/em><\/p>\n<p><em>&nbsp; &nbsp; &nbsp; &#8220;GIVEN &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..<br \/>\n&nbsp; &nbsp; &nbsp; given_guitar_attribs_entered,<br \/>\n&nbsp; &nbsp; &nbsp; given_initial_instruments,<\/em><\/p>\n<p><em>&nbsp; &nbsp; &nbsp; &#8220;WHEN &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..<br \/>\n&nbsp; &nbsp; &nbsp; when_guitar_is_added,<br \/>\n&nbsp; &nbsp; &nbsp; when_same_guitar_twice,<br \/>\n&nbsp; &nbsp; &nbsp; when_guitar_is_searched,<\/em><\/p>\n<p><em>&nbsp; &nbsp; &nbsp; &#8220;THEN &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;..<br \/>\n&nbsp; &nbsp; &nbsp; then_instruments_has_guitar,<br \/>\n&nbsp; &nbsp; &nbsp; then_exception_is_raised,<br \/>\n&nbsp; &nbsp; &nbsp; then_guitar_is_found,<\/em><\/p>\n<p><em>&nbsp; &nbsp; &nbsp; &#8220;Other helper methods<br \/>\n&nbsp; &nbsp; &nbsp; load_mockups returning value(re_guitars) type ty_guitars.<\/em><\/p>\n<p><em>endclass.<\/em><\/p>\n<p>You should include `<em>IT SHOULD<\/em>` methods that come right out of the functional&nbsp;specification document.<\/p>\n<p>In this example, the <strong>zcl_instruments<\/strong>&nbsp;class should be able to:<\/p>\n<ul>\n<li>Add guitars to instruments.<\/li>\n<li>Restrict duplicity.<\/li>\n<li>Search for any specific guitar in instruments.<\/li>\n<\/ul>\n<p>The following sample shows an implementation of the&nbsp;`add_guitar_to_instruments()` method:<\/p>\n<p><em>&nbsp;method add_guitar_to_instruments.<\/em><\/p>\n<p><em>&nbsp; &nbsp; given_guitar_attribs_entered ().<\/em><\/p>\n<p><em>&nbsp; &nbsp; when_guitar_is_added ().<\/em><\/p>\n<p><em>&nbsp; &nbsp; then_instruments_has_guitar ().<\/em><\/p>\n<p><em>&nbsp; endmethod.<\/em><\/p>\n<p>To add a guitar to the instruments, you start with some guitar attributes,&nbsp;add the guitar to the instruments, and check if is successfully added. If there\u2019s&nbsp;no green light when you run a test for this method, that indicates that&nbsp;something is wrong with this part of the process.<\/p>\n<p>The following `given_guitar_attribs_entered()` method just initializes oneguitar object<em>.:<\/em><\/p>\n<p><em>&nbsp;method given_guitar_attribs_entered.<\/em><\/p>\n<p><em>&nbsp; data: guitar_spec_attributes type zcl_guitar_spec=&gt;ty_guitar_attributes.<\/em><\/p>\n<p><em>&nbsp; &nbsp; guitar_spec_attributes-builder = zcl_enum_builder=&gt;fender.<br \/>\n&nbsp; &nbsp; guitar_spec_attributes-model &nbsp; &nbsp;= &#8216;XYZ&#8217;.<br \/>\n&nbsp; &nbsp; guitar_spec_attributes-type &nbsp; &nbsp; = zcl_enum_guit_type=&gt;electric.<br \/>\n&nbsp; &nbsp; guitar_spec_attributes-backwood = zcl_enum_wood=&gt;maple.<br \/>\n&nbsp; &nbsp; guitar_spec_attributes-topwood = zcl_enum_wood=&gt;maple.<\/em><\/p>\n<p><em>&nbsp; &nbsp; data(guitar_spec) = new zcl_guitar_spec (guitar_spec_attributes).<\/em><\/p>\n<p><em>&nbsp; &nbsp; data(guitar_record) = value zcl_guitar=&gt;ty_guitar_attributes (serialnumber = &#8216;ABC0001&#8217;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;price = &#8216;1000&#8217;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;specs = guitar_spec).<br \/>\n&nbsp; &nbsp; guitar_to_add = new zcl_guitar (guitar_record).<\/em><\/p>\n<p>\n<em>&nbsp; endmethod.<\/em><br \/>\n&nbsp;<\/p>\n<p>The `<em>WHEN<\/em>` part of the BDD description, from the class under test, enables you&nbsp;to test the method.<\/p>\n<p><em>&nbsp;method when_guitar_is_added.<\/em><\/p>\n<p><em>&nbsp; &nbsp; try.<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; mo_class_under_test-&gt;add_guitar (guitar_to_add).<br \/>\n&nbsp; &nbsp; &nbsp; catch zcx_guitar.<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &#8220;Oops<br \/>\n&nbsp; &nbsp; endtry.<\/em><\/p>\n<p><em>&nbsp; endmethod.<\/em><\/p>\n<p>Finally, you can check that the object instruments have a guitar by using the&nbsp;following method. This check represents the helper method for the `<em>Then`<\/em> part of BDD.<\/p>\n<p><em>method then_instruments_has_guitar.<\/em><\/p>\n<p><em>&nbsp; &nbsp; data(guitar) = mo_class_under_test-&gt;guitars [ serial_number = &#8216;ABC0001&#8217;].<\/em><\/p>\n<p><em>&nbsp; &nbsp; cl_abap_unit_assert=&gt;assert_not_initial (act = guitar<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;msg = &#8216;Guitar is not in instruments&#8217;).<\/em><\/p>\n<p><em>&nbsp; endmethod.<\/em><\/p>\n<p>&nbsp;<\/p>\n<p><strong>Conclusion<\/strong><\/p>\n<p>This blog highlights the importance of writing testable code and shows how to do&nbsp;that. By focusing on test-driven development, you can adapt your programming&nbsp;style to include testable code. As a result, you end up with clean, easy-to-maintain, and reusable code. Writing testable code helps you to become a better developer.&nbsp;Sometimes, when you have tighter delivery deadlines, it is easy to ignore the testability aspects of the code, and by doing so, you might save time. However,&nbsp;in the long run, you end up spending more time and resources fixing bugs.&nbsp;Therefore, by adopting the test-driven development concepts described here, you&nbsp;not only make your own life easier, but you also help the next developer who&nbsp;works on your code.<\/p>\n<p><strong>Optimize your environment with expert administration, management, and configuration<\/strong><\/p>\n<p><a href=\"https:\/\/www.rackspace.com\/application-management\/managed-services\">Rackspace&#8217;s Application services<\/a><br \/>\n<strong>(RAS)<\/strong>&nbsp;experts provide the following <a href=\"\/\/www.rackspace.com\/application-management\/professional-services\">professional services<\/a>&nbsp;and&nbsp;[<a href=\"https:\/\/www.rackspace.com\/application-management\/managed-services\">managed services<\/a>&nbsp;across&nbsp;a broad portfolio of applications:<\/p>\n<ul>\n<li><a href=\"https:\/\/www.rackspace.com\/ecommerce-digital-experience\">eCommerce and Digital Experience platforms<\/a><\/li>\n<li><a href=\"https:\/\/www.rackspace.com\/erp\">Enterprise Resource Planning (ERP)<\/a><\/li>\n<li><a href=\"https:\/\/www.rackspace.com\/business-intelligence\">Business Intelligence<\/a><\/li>\n<li><a href=\"https:\/\/www.rackspace.com\/email-hosting\">Databases- [Email Hosting and Productivity<\/a><\/li>\n<\/ul>\n<p>We deliver:<\/p>\n<ul>\n<li><strong>Unbiased expertise<\/strong>: We simplify and guide your modernization journey, focusing on the capabilities that deliver immediate value.<\/li>\n<li><strong>Fanatical Experience<\/strong>&nbsp;We combine a Process first. Technology second\u00ae&nbsp;approach with dedicated technical support to provide comprehensive solutions.<\/li>\n<li><strong>Unrivaled portfolio<\/strong>: We apply extensive cloud experience to help you&nbsp;choose and deploy the right technology on the right cloud.<\/li>\n<li><strong>Agile delivery<\/strong>: We meet you where you are in your journey and align&nbsp;our success with yours.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>ABAP Programming approach to writing testable code<\/p>\n","protected":false},"author":2,"featured_media":7855,"menu_order":0,"comment_status":"open","ping_status":"open","template":"","format":"standard","meta":{"content-type":"","nid":"26521","content_type":"blog","created_by":"10130","authored_on":"2024-01-21T14:44:22+00:00","field_article_industries":"","tag_category":"Technical","field_blog_author_text":"by  Akash Jain, Business Systems Consultant, Rackspace Technology","seo_description":"Gain insights into Oracle Demantra and advanced Supply Planning Work Area (SPWA). Explore architecture, installation, and integration.\r\n","field_featured_image":"","insights_image":"\/wp-content\/uploads\/2026\/blog_technical_images\/26521-insights_image-erp-technical-blog-1-insights.jpg","field_partners":"","rxt_platforms":"SAP, SAP ERP","product":"","publisheddate":"2019-02-08T14:44:22","rxt_solutions":"","opengraph_tag":"","x_tag":"","teaser_flag":"Technical Blog","seo_titile":"ABAP Writing Testable Code | Rackspace Technology","field_topics":"","field_slug":"abap-programming-approach-to-writing-testable-code","footnotes":""},"categories":[178],"tags":[204],"class_list":["post-7853","blogs","type-blogs","status-publish","format-standard","has-post-thumbnail","hentry","category-blog","tag-technical"],"_links":{"self":[{"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/blogs\/7853","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/blogs"}],"about":[{"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/types\/blogs"}],"author":[{"embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/comments?post=7853"}],"version-history":[{"count":3,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/blogs\/7853\/revisions"}],"predecessor-version":[{"id":9711,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/blogs\/7853\/revisions\/9711"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/media\/7855"}],"wp:attachment":[{"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/media?parent=7853"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/categories?post=7853"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rackspace.com\/en-gb\/wp-json\/wp\/v2\/tags?post=7853"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}