Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
former_member249109
Active Participant
If you go and ask 10 experienced programmers about what is their biggest professional fear, 7 would say to become obsolete. I don’t have any hard data to support such a statement, it was pure empirical, literally I went and asked this to 9 of my colleagues and got these answers. Some more serious people concluded than one in three developers fear A.I will replace them, but that’s another discussion.

So here I am, 10 years old ABAP developer trying to catch up with SAP’s latest technology. I’m starting this blog as kind of a journal in which I could come back to it one year later, and let 1-year future me decide whether there have been any improvements, or it was just a waste of time -although no time in educating yourself is wasted time, I believe.

Hopefully we won’t get to this point anytime soon.

After reading bfeeb8ed7fa64a7d95efc21f74a8c135 ABAP to the future book -make yourself a favor and get it, the topics to improve became clear:

  • Object-oriented programming in general.

  • Test-Driven development and ABAP Unit.

  • Business Object Processing Framework (BOPF).

  • Floorplan Manager and other UI technologies (SAP UI5 perhaps).

  • ABAP for SAP HANA.


To improve in OOP, I decided to take some examples out of the book Head First Object-Oriented Analysis and design, which is also very good and fun to read. The first chapter describes a guitar store owner who decided to ditch his paper-based system for keeping tracks of guitars and start using a computer system to manage his inventory.  Naturally, he bought SAP ERP and hired a consultant to implement his system.
Here’s the initial class diagram design for Mike, our guitar shop owner:


Ok, that was a bit disappointing, but still a good place to start. Each of the guitars are represented by the abstraction ZCL_GUITAR, which has the same structure as the database table ZGUITARS.



Nothing much to see in ZCL_GUITAR, as it represents just a data structure, there’s no behavior inside. Instead of creating setters and getters methods, thought it would be a good idea just to create a public attribute and make it read-only.
class zcl_guitar definition public final create public .

public section.

data: guitar_record type zguitars read-only.

"! <p class="shorttext synchronized" lang="en"></p>

"! Creates a guitar object from a guitar structure

"! @parameter i_guitar_record | <p class="shorttext synchronized" lang="en"> Guitar structure </p>

methods constructor importing i_guitar_record type zguitars.

protected section.

private section.

endclass.


class zcl_guitar implementation.

method constructor.
me->guitar_record = i_guitar_record.
endmethod.

endclass.

In TDD methodology, before creating any production code you should first create failing tests, and then just write enough code for the test to pass. This is supposed to ensure that all of your code is properly tested, and your system is working correctly. So if I want to add guitars to the inventory, first thing I need is to create a test method. This is a really cool thing to do in Eclipse, go to the test classes tab in the bottom of the source code, type the word ‘test’, press CTRL + SPACE and there is a template waiting to be inserted within the code
 class ltcl_inventory definition final for testing duration short 
risk level harmless.

private section.

methods:

setup,

add_guitar_test for testing raising cx_static_check.

data inventory type ref to zcl_inventory.

endclass.


class ltcl_inventory implementation.

method setup.
inventory = new zcl_inventory( ).
endmethod.

method add_guitar_test.
data(guitar_record) = value zguitars( serialnumber = 'FE34000'
price = '1745.43'
builder = 'Fender'
model = 'Stratocaster'
type = 'Electric'
backwood = 'Maple'
topwood = 'Maple' ).
inventory->add_guitar( new zcl_guitar( guitar_record ) ).

cl_abap_unit_assert=>assert_subrc( exp = 0 act = sy-subrc ).

endmethod.

endclass.

The add_guitar method is empty, so after running this test ( CTRL + SHIFT + F10 ), the Eclipse IDE shows me the failed test:
Fair enough, just need to fill in some code into the add_guitar method to past the test. The method add_guitar is supposed to add guitars to the inventory, which is represented as  a hashed table from within the class
types: begin of ty_guitar,
serial_number type z_serial_number,
guitar type ref to zcl_guitar,
end of ty_guitar.

types: guitars_tab type hashed table of ty_guitar with unique key
serial_number.

Then the class definition would go like this
class zcl_inventory definition public
final create public.

public section.

"! <p class="shorttext synchronized" lang="en"></p>
"! Adds a guitar to the inventory
"! @parameter i_guitar | <p class="shorttext synchronized" lang="en"> Guitar object to add</p>
"! @parameter r_ok | <p class="shorttext synchronized" lang="en"> Guitar was added to inventory</p>
methods add_guitar importing i_guitar type ref to zcl_guitar
raising zcx_guitar.

protected section.

private section.

data guitars type guitars_tab.

endclass.

One pretty cool thing about hashed tables is that they throw exceptions when you try to insert a duplicate record. The annoying thing is that this feature apparently only works for the secondary key. This left me no other choice than checking for SY-SUBRC in the test method.
method add_guitar.
data(guitar_record) = value ty_guitar( serial_number = i_guitar->guitar_record-serialnumber
guitar = i_guitar ).

try.
insert guitar_record into table me->guitars.
catch cx_sy_itab_duplicate_key.

raise exception type zcx_guitar
exporting
textid = zcx_guitar=>duplicate_record.
endtry.
endmethod.

Run the test again and great! First test passed.


Now let’s create a test in which you add a duplicate record. Here what’s got me thinking is how to manage that exception raised from the add_guitar method?. According to SAP a test method should not catch an exception

But what about when you are provoking an exception and this one does not get raised? The recommended solution in the previous link did not work for me. Even after the second call to the method under test, the exception did not stop the execution of the test method and I got the wrong error that an exception was not raised. After removing the cl_abap_unit_assert=>fail call the test passed, though.

Anyways here’s the whole test class
 class ltcl_inventory definition final for testing duration short
risk level harmless.

private section.

methods:
setup,
add_guitar_test for testing raising cx_static_check,
duplicate_guitar for testing raising zcx_guitar.

data inventory type ref to zcl_inventory.

endclass.


class ltcl_inventory implementation.

method setup.
inventory = new zcl_inventory( ).
endmethod.

method add_guitar_test.
data(guitar_record) = value zguitars( serialnumber = 'FE34000'
price = '1745.43'
builder = 'Fender'
model = 'Stratocaster'
type = 'Electric'
backwood = 'Maple'
topwood = 'Maple' ).

inventory->add_guitar( new zcl_guitar( guitar_record ) ).
cl_abap_unit_assert=>assert_subrc( exp = 0 act = sy-subrc ).
endmethod.

method duplicate_guitar.
data(guitar_record) = value zguitars( serialnumber = 'FE34000'
price = '1599.95'
builder = 'Fender'
model = 'Stratocaster'
type = 'Electric'
backwood = 'Maple'
topwood = 'Maple' ).

data(guitar1) = new zcl_guitar( guitar_record ).
data(guitar2) = new zcl_guitar( guitar_record ).

inventory->add_guitar( guitar1 ).
inventory->add_guitar( guitar2 ).

* Supposed to fai the test only if no exception has been thrown by the previous method call
* Seems not to work
cl_abap_unit_assert=>fail( msg = 'ZCX_GUITAR not raised'
level = if_aunit_constants=>critical ).
endmethod.

endclass.

 

Well that’s gonna be it for this time, next time I’ll come up with more tests to make and will try to improve the design of this simple application.
17 Comments