Skip to Content
Author's profile photo Jelena Perfiljeva

ABAPosaurus Takes openSAP Course

Folks,

In a brief moment of insanity I decided to sign up for openSAP course Writing Testable Code for ABAP. After completing the first week of the course I feel a bit like Vicky Pollard from Little Britain: “yeah but no but yeah but”. Let me explain.

Testing seems to be all the rage these days in software development. One might ask: why just these days, haven’t we been testing our programs all along? Of course (well, most of us did, anyway), but folks, it looks like we’ve been doing it either all wrong or not good enough.

The book Clean Code, which is to programming what Karl Marx’s The Capital is to communism, goes on about how the programmers are afraid of making improvements because they might break something. And if only we had a simpler, more efficient way to test our changes then we would be free to change the code without a fear of breaking it.

Now enter ABAP Unit Test which is supposed to be the best thing since sliced bread, according to Paul Hardy himself, as well as other SCN luminaries. Very well. I guess we need to find more about it.

In the first week of this openSAP course, we learned about the motivation to do more unit testing and had a small programming exercise to just dip our digital toes into the waters of ABAP Unit Test.

The “motivation” part can be nicely summarized by this slide:

This is just a small sample of the code being discussed in Unit 3:

The demo program this week was a convertor of Roman numerals (i.e. I, II, III, etc.) to Arabic ones (1, 2, 3). The instructors showed us how the test methods can be generated easily in the Editor. Note how the one_in_1_out method declaration here does not have RAISING clause. It’s because that line was just typed in by an instructor while the next two lines were generated automatically in the editor.

Later in the unit, this code is refactored (i.e. updated / rewritten with the goal to improve it) to remove some redundancies and improve readability. More test methods are added as well.

Tips and tricks wrap up the week nicely.

So far we are off to a good start with this course but I hope that somewhere in the coming weeks we will get to my main gripe with ABAP Unit Test: practical application in real life.

It seems that in any blog or book or TechEd session pretty much the same scenario is involved. It goes like this: oh, we have this object and it does these things. So we create zcl_something class and a do_something method with 3 lines and then a test method is generated, this is awesome, any questions?

OK, but here I am, working on yet another Jumbo ALV Report and how exactly will Unit Test help me? I just gather the data from a bunch of tables and then use SALV. I know the data selection will be fine (and if it’s not then it’s because the users forgot to mention some detail). ALV method call is rather difficult to mess up, it either works or it doesn’t and you’ll find out as soon as you run the program.

The most common ABAP tasks (at least for not-so-cutting-edge developers) either don’t really lend themselves easily to tiny unit-testable methods or that would not help to prevent any potential real life issues anyway. With ALV, most common issue is wrong specification, as I mentioned. With “read a spreadsheet and use BAPI to post a journal entry” the usual problem is the BAPI that returns mystery error messages that have nothing to do with the actual problem.

While it would be hard to deny that ABAP Unit Test concept indeed has some value, I can’t help but wonder whether it’s like many vendor solutions presented at TechEd: solving the problems that I don’t have.

Well, there is still time for the course to address this and hey, maybe we can use Unit Test to catch a bug in this slide? 🙂

It’s still not too late to join the course. The first assignment is due on March 21st 2018. After a fiasco with the openSAP Fiori course I was concerned about the time commitment. But, fortunately, the whole week 1 took just a single afternoon.

The course pace seemed adequate to me. Personally, I’d prefer a bit faster cadence but the slower speed is easier for the students with less fluent English. And there is always fast-forward.

The discussed ABAP code requires at minimum version 7.4. You can either use your own system or sign up for a cloud version (some cost involved). So far, however, I had no problem participating somewhat passively, just watching the videos and answering the questions.

The authors caved in under the participants’ pressure and posted the source code on abapGit as well: http://docs.abapgit.org/

The best part of these courses though is always in the discussions. Would you like to find out if there was 0 in Roman numerals or whether KISS actually stands for “keep it sunny, Superman”? Then join us in week 2!

 

P.S. For a slightly different take on the course read this blog by Paul Hardy

Image source: SAP, https://open.sap.com/courses/wtc1

Assigned Tags

      33 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Bärbel Winkler
      Bärbel Winkler

      Thanks for your write-up, Jelena!

      I'm also taking this course and like you have some doubts about how useful it'll be for the type of programs I usually write (along the lines of grab some data from tables, fiddle a bit with the data and then let ALV do the rest). But, I guess it's at least helpful to know that this exists and how it looks like in order to add it to my "passive" ABAP vocabluary for instances when I'm doing code reviews and thereby might just see it in code created by others.

      Cheers

      Baerbel

       

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva
      Blog Post Author

      Exactly! This would cover at least 50% of my work. But when people talk about how awesome OOP or this and that is the examples used couldn't be farther from most common ABAP reports.

      So yeah, right now I'm just following this so that I could carry on a conversation or criticize the concept with more authority. 🙂

       

      Author's profile photo Thomas Hammer
      Thomas Hammer

      Hi Jelena,

      Jürgen posted some thoughts around the goals we had with this training in a blog. Maybe this helps to put things into perspective.

      All the best, Thomas

       

      Author's profile photo Matt Harding
      Matt Harding

      Hi Jelena,

      I'm with you to a degree but I'm still at the verge of starting the course so we'll see - I would sum it up as  "Hopeful but skeptical"...

      I actually attempted this back many years ago when ABAP Unit was in it's infancy; and there were 3 issues I hit:

      • I had no idea what I was doing; as writing ABAP scenarios was nothing like writing a sort routine which all the unit test examples used and there were no examples as a guide in SAP itself; (hopefully this course will help with this one)
      • I was in a development team of about 2-3 people at this point with deadlines and no one with budget and timeline control who understood why you would spend time doing this for a customer; and most importantly; (no idea how to fix this one - it will take more effort initially to do this)
      • Except for utility style classes; how do you mock up something that calls a few BAPI's in a way that would actually protect you from an upgrade where SAP changes (pretty sure all ABAP units will pass after each upgrade if we mocked up responses from BAPI's!) - Our utility classes after all are typically not the data integration the customer cares about.

      I've actually asked others to blog how to do this for real for something like an enhancement that helps protect you from upgrades by SAP (since enhancements rarely change) and I'm really hoping this course covers this (or ALV) scenarios in a way that I can see the benefit, but I'm still skeptical.

      Anyway, sounds like the place to hang out is in the open.sap.com forums and actually do this first week!

      Cheers,

      Matt

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva
      Blog Post Author

      Thanks for chiming in, Matt!Glad to know it's not just me. Sometimes it feels awkward pointing out that the Emperor has no clothes when so many people insist otherwise.

      I'm also in the "hopeful but skeptical" camp. Not denouncing the concept but scratching my head how it could be useful to me personally.

      If SAP and independent TDD evangelists are serious about it they should simply offer more practical examples instead of just banging a drum and proclaiming that "other developers" have already been doing unit tests all along. Well, if all other developers jump off the bridge, should we too? 🙂

       

      Author's profile photo Mike Pokraka
      Mike Pokraka

      Hi Jelena,

      Nice write-up, and I can sort of understand why you question the usefulness in legacy code. Yet I disagree on that point, I’ve actually got a whole counter-blog in my head, but won’t manage to write that on my train journey I’m on right now.

      So how do you test legacy code? I will admit it takes practice to really get into the mindset, but today this fellow ABAPosaurus wouldn’t do it any other way. Hence I encourage anyone to do the practical side of the course too.

      I’m hoping this will be covered by the course, but my simple approach is to add a test for what you’re doing right now. If it’s a bug, write a test that reproduces it. If you need to add colors to a status column, write a test for it.

      The initial effort does take a bit of time but the next time it’s much quicker (you already have the data structure etc) and it does pay off reasonably quickly. The days where I have to start a report and enter a particular document number and repeat a setup sequence 15 times to debug it are much reduced. Place breakpoint, ctrl-f10, run. Repeat. This to me is a is a major time-saver that isn’t emphasised in the course.

      Author's profile photo Mike Pokraka
      Mike Pokraka

      Oh … so there seems to be a new code editor on this platform and it just lost my code above! Saved, vanished, just like that. I really really do hate this platform.

      Author's profile photo Mike Pokraka
      Mike Pokraka

      Ok, let me try again (on the bus now):

      Class ltcl_formatting for testing...
      ...
      Methods setup.
        “Fill in a couple of lines of alv data
      Endmethod.
      
      Method Color.
        Perform update_colors importing/exporting ... “form in the report under test
        Loop at alv_data.
          Cl_abap_unit_assert=>...
        Endloop.
      Endmethod.

      The idea here is that it's not realistic to go and retrofit a whole report with unit testing, but it's reasonably easy to start adding them going forwards. OK, so maybe one needs to do a bit of refactoring here and there, such as isolating a BAPI call into a method/class, but that's usually not a bad thing.

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva
      Blog Post Author

      Mike, thank you for the comment and example! Well, it kind of goes along the same lines as the examples in the course. It's a very small piece and what are actually the chances that anything breaks there? It's neat but I just don't see any real ROI in this case.

      I'm really hoping to see more impressive examples in the coming weeks.

      P.S. Nice to see your in the discussions there as well. 🙂 I'm sure I'll have more silly questions this week.

       

      Author's profile photo Mike Pokraka
      Mike Pokraka

      All I can say is it took me a while to really see the benefits. Yes, my example simple, but that's just to illustrate the point that it doesn't need to be time-consuming. And it's a start for building up a test dataset.

      And besides, people do come along and change structure definitions and stuff like that - trivial unit tests can catch some unintended situations which you would otherwise only notice as dumps in Test.

      One of my Eureka moments was working on a complex piece of framework for four days with just unit tests, then plugging it in to the main project and it almost worked first time (two minor fixes, 10 minutes).

      Author's profile photo Matthew Billingham
      Matthew Billingham

      “I’m hoping this will be covered by the course, but my simple approach is to add a test for what you’re doing right now. If it’s a bug, write a test that reproduces it. If you need to add colors to a status column, write a test for it.”

      That’s exactly what I did today. I had a bug in a program. I wrote a test for it, and, of course, since there’s a bug in the the program, it failed exactly as I expected it to.

      From the TDD course, I understood about constructor injection. My local class had a private constructor  – I'd already implemented the factory pattern for other design reasons. That made refactoring uncomplicated and low risk. All I had to do was make the local class in the report a friend of my test class, enabling me to call the constructor directly with my injection.

      Once my test was in place, I changed the productive code to correct my error. Then I ran my unit test again and it passed. I got the expected result.

      I then took a bold step. I changed the production code. I changed it in such a way that I was highly confident it would work, but that without the 7.52 SQL Code Doubling technique for which I mourn, wasn’t testable. It did make the code far more performant.

      The point is, I could have made the bold step immediately. But I wasn’t sure that the error I saw really was the error. By using TDD techniques to write a test class, I was able to establish it was.

      I knew for sure that I wasn’t running any code except what I was testing.

      That meant I was able to establish that my initial fix was robust with a high level of confidence. Consequentally, the simple code transformation which made the test method obsolete was similarly low risk. So when I ran the integration test and saw the results I expected, I was able to hand it over to my tester confident that she wasn’t going to shout at me… ?

      Author's profile photo Mike Pokraka
      Mike Pokraka

      Maybe it's not just me, but here's something weirdly satisfying about having full confidence in your work without having fired up the application 🙂

      Author's profile photo Robert Forster
      Robert Forster

       

      Hi Jelena,

      nearly all trainig examples are solving non Business application examples.

      Maybe my blog with a real world example helps here

      https://blogs.sap.com/2017/03/22/enhance-sap-objects-with-great-and-testable-code/

       

      Best reagrds

      Robert

       

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva
      Blog Post Author

      Thanks for the comment, Robert! I checked the blog but it's also an example along the same lines: relatively small piece of code with clearly defined expectations. User exit is actually the only use case I can easily imagine. 🙂 But it makes up very low percentage of my work.

       

      Author's profile photo Paul Hardy
      Paul Hardy

      I recall writing a blog a few years back when I first started investigating unit testing, and I raised the exact same point i.e. for a report that reads data, and then outputs it using the ALV, what is the point?

      After all to do unit testing properly you have to mock the database access , and mock the UI, and in the above example that does not leave anything left to test.

      Over my career I have written more ALV reports than there are stars in the sky. They all start off the same way – read the data and then output it .

      However of those million reports there is not a one that just does that. At the very minimum some columns need to be hidden, or made editable, or coloured or the length changed, or sorted a funny way and so on – the good old FIELDCAT and SORTCAT type of thing, now handled with objects in SALV world.

      I read the other day that if a programmer wrote a program without bugs then the world would cease to exist.

      I put it to you, ladies and gentlemen of the jury, that as soon as you do ANYTHING more complicated than just a SELECT and then a call to the SALV then the possibility of a bug is introduced.

      In my case my big fat fingers spell the field names that I am trying to hide or enable drill down on wrongly. This leads to a dump, or more accurately an exception that I catch.

      This has happened so many times, I have a generic sort of unit test I run to make sure that every field the code tries to adjust actually exists in the output. It might be just me, but that test fails every single time initially, if I have ten fields I just am bound to spell one wrong e.g. VBLN instead of VBELN or some such.

      I also find that a report that starts life as a straight SELECT and output the result, gets business logic added to it over it’s lifetime, and in one case the two things become three – SELECT, adjust data, output data. the “adjust data” bit in one program ran to thousands of lines of code after ten years. It is that adjusting bit that needs testing.

      One example was where I had a procedural program that looked at the customer open items, and based on some logic from the credit manager, tried to group the items together to match invoices (no-one ever just pays one invoice in my industry). I had about ten different strategies and did unit tests for all of them. At one point I found that my maths was so wrong instead of an equal positive and negative number coming to zero, the result was one million dollars. I am really glad I caught that in development, as opposed to an end user finding it in production.

      When it did go to production there were naturally bugs I had not caught, and new requirements. In both cases I used unit tests to recreate the situations in development, and could be sure the exact cases would work when they hit production, and that my existing tests showed that the changes I made did not break anything existing.

      I also tell the story of when unit tests were first added to the ABAP2XLSX classes. There was one test done on the method that formatted the date. The test was that if a blank date was passed in, a blank date got passed out. That test failed. There were only two lines of code in the method. I was looking at those two lines for an hour before I realized what was wrong. Without the test I would never have spotted that error – after all with two short lines of code what could possibly go wrong?

      In other words I am not looking for anything earth shattering in my tests. I am looking for schoolboy errors that I make, so i find them before anybody else.

      Another example I upload a file from a customer and use that data to create sales orders. Some of the incoming data is in free text format e.g. “09:00" sometimes and “9AM” other times. So I wrote a method to analyse the free text and come up with the time in SAP format. I put in a bunch of possible input values and the expected outputs. I found a whole bunch of errors in my code things like filling a variable with the entire structure rather than just the field I want from the structure. I keep doing that.

      Now it is possible that not everybody keeps making the sort of bonehead errors I tend to make during my first versions of programs, but just in case, it could be said that the worse programmer you are, the more benefit you get from unit tests….

      As I have said I reckon a developer, if they try to use unit tests in anger on a real program, even to test something really basic like have I hidden that field (by querying the object that stores the fact that fields should be hidden) after a very short period of time indeed they will find a bug they never would have caught otherwise.

      At that point they get hooked, my work here is done…

      Author's profile photo Nabheet Madan
      Nabheet Madan

      Wow, Thanks for the detailed reasoning of getting hooked to unit tests.  Does not matter what kind of developer you are good or bad, if a developer tries to implement unit test he/she will for sure benefit of it.

      All ALV reports have same stories over time, start with simple one then changes, more IF's and ELSE's and on and on.   Any code written without a unit test class is a bad code, i agree now:)

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva
      Blog Post Author

      Since I witnessed how someone else made a typo in the ALV field catalog I simply never type in any names there manually. I just maniacally copy-paste everything. That's my kind of "experience driven development" (c). 🙂

      P.S. As a side note, why do even still have to write any code for ALV manually? It should be some simple tool with check boxes, like SAP Query.

       

      Author's profile photo Matthew Billingham
      Matthew Billingham

      My favourite error is missing the not out of any logical expression. I’ve been making this error since I began ABAP in 1996. I last made it yesterday…

      How I love unit tests.

      Author's profile photo Michelle Crapo
      Michelle Crapo

      Unit tests - the bane of my existence. Jelena, your simply ALV report can become a huge monster thing that at the end of it displays the ALV. Why? Because that's what seems to happen every now and then. So writing some simple quick tests at the end might help you when you go in for that one line fix that breaks the whole thing!

      The openSAP course. Well I was told that they present the basics so that you can dive in deeper with a book, an SAP course, or just by educating yourself. Claire Donelon

      I find them pretty darn good. They go a bit deeper than the above paragraph for me. Anyway - I know sflight and get/put were my ABAP examples. Learning from my first 5 week ABAP course. Yes, those were thrown away the first time I wrote a program. These I haven't had to throw away, just build on. Pretty cool.

      Anyway back to ABAP Tests. I think it's a matter of does it make sense? Sometimes it does, sometimes it doesn't. But that's just me. And the old SAP answer "It depends".

      I wasn't able to take this course as like you, I thought it would take too much of my time. Still reading books though. And of course every blog that I can.

      Awesome blog - great discussion!

      Michelle

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva
      Blog Post Author

      Thanks for the comment, Michelle!

      I agree that it's not all black and white and we may need to be flexible while applying different techniques. This hasn't happened so far (and I'm done with week 2 already, which was - spoiler alert! - rather disappointing) but I hope to see some kind of "when you should use unit test and when you probably shouldn't" diagram.

      Author's profile photo Egor Malov
      Egor Malov

      Some thoughts from Kent Beck (not at all idealistic as I expected, no 100% coverage, etc recommended):

      https://stackoverflow.com/questions/153234/how-deep-are-your-unit-tests/153565#153565

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva
      Blog Post Author

      Thanks for the link! Quote: "Ten or twenty years from now we'll likely have a more universal theory of which tests to write, which tests not to write, and how to tell the difference."

      Well, we are already 10 years from the date it was originally posted (2008) and I don't believe we have a good understanding of how to tell the difference. Still, the dogma "always 100% TDD" is alive even though it is as wrong as pretty much any "always 100%" things. The only thing we can all be sure of is that "everything breaks all the time". 🙂

       

      Author's profile photo Simon Rotherham
      Simon Rotherham

      I'm also doing the OpenSAP course with some degree of skepticism.  Why would I write another set of code to test the functional code I am writing? etc...

      However I do think the principles they are teaching are sound and can be applied in the real world.

      For example:

      There is a large legacy interactive ALV report that requires changing to add additional functionality (let's say it is additional validation).  A decade ago, I would have inserted the code in a new form, using globally declared variables and tested by executing the report.  Today, I may create a new class and methods with fixed parameters to encapsulate my code using SE24 and use the test function in SE24 to manually test  my methods prior to inserting the methods into the legacy ALV report.  I would of course test the report as a whole once I had inserted my new methods

      Because I now encapsulate my changes within classes and methods, I could take the next step and use a test class.  One advantage being that I will have documented the tests that I had carried out to prove the functionality of my code.

      One advantage of doing this course for me, is picking up on some of the short cuts within eclipse (which is still not widely used among the abaposauruses I come across) and some of the ABAP 7.5 syntax which is used in the samples.

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva
      Blog Post Author

      Having gone through 3 weeks of the course already, I feel the authors did everyone a disservice trying to pack as much unrelated general development practice stuff (like TDD and pair programming) into this course and stretching it for 6 weeks.

      IMHO it should've been 3 weeks tops and should've concentrated on ABAP Unit Test features, use cases and such. I agree with you that we do write tests in some form (naturally) and ABAP Unit Test provides a neat way of storing those tests. That should've been the main message of this course IMHO. But then they had to drag TDD into it and it didn't help at all, I believe.

      Also Paul Hardy brings up an interesting point in his blog here that TDD is really nothing new for this exact reason - we've been testing all along.

      Author's profile photo Thomas Hammer
      Thomas Hammer

      I would be interested in the bug you suspect in the unit test benefit slide. Maybe it can be improved. Thanks.

       

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva
      Blog Post Author

      Thomas, it's revealed at the end of my second blog. 🙂

      Author's profile photo Thomas Hammer
      Thomas Hammer

      Ok, can live with that 🙂 Thank you for pointing it out. Will throw that in the next time I give this course in classroom again ...

       

      Author's profile photo Kenneth Moore
      Kenneth Moore

      I attended the first two weeks of the course.  Just couldn't make myself continue this week.  I just don't see a lot of value for the amount of effort.  Or maybe I'm missing something critical.  And the testing is only as good as the test.  If my test is very narrow, it will still miss other errors.  Can't test for everything.

      I like the idea or theory, but I just couldn't get into this course.

      Author's profile photo Thomas Hammer
      Thomas Hammer

      Too bad, week 4 + 5 are the heart of the course. Without test isolation there is no unit test in the real world.

       

      Author's profile photo Kenneth Moore
      Kenneth Moore

       

      Then maybe they should start with 4 & 5 earlier.

      Author's profile photo Thomas Hammer
      Thomas Hammer

      Good one. 🙂

       

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva
      Blog Post Author

      I'm still following along but only because I'm not actually doing the (optional) exercises and the videos / quiz alone don't take that much time. If I was investing more time in the exercises, I'd probably also feel very disappointed by now. Unfortunately, we can't see the content of the upcoming weeks but if the "good stuff" only starts on week 4 it seems to me like a very bad choice for the course structure.

       

      Author's profile photo Kenneth Moore
      Kenneth Moore

       

      I agree.