On 09/06/2016 the SAP Inside Track event occurred in Hamburg and it was an absolute corker, just as high in quality as what you would get in SAPPHIRE or some such.
Naturally I feel a burning need to write a blog about it, whilst it is fresh in my mind, on the five hour train trip back to Heidelberg.
I was lucky enough to get invited to speak at the event by Peter Langer and as I live in Germany this year and I have never been to Hamburg so I thought why not….
Table of Contents
0 Too Much – The Magic Train
1 Jack and the Beanstalk – the ABAP Cloud
2 Collapsing Chairs – Test Drive Development
3 Grafitti#1 – Code Comments
5 Graffiti#2 – Code Noise
6 Barn Clearing – S/4 HANA Code Adaptation
7 War Story – history of EDI
8 You say Goodbye, I say Silo
9 Come on Baby, Light up the Requirements
10 Alte Madchen
0 Too Much – The Magic Train
The first step was getting from Heidelberg to Hamburg. I thought I would go and the train as although that takes five to six hours and I could work (and drink) during the journey, and the ICE trains have free Wi-Fi, very slow, but it works and that is all that matters. The beer price is quite reasonable as well.
In case you have never travelled inter-city on a German train this is how it works. You get a reserved seat, otherwise you have to sit in the corridor. This tells you on the ticket you are in carriage number four, seat 76, or some such.
On the train station platform there is a diagram saying for each train the exact place it will stop and that carriage four is opposite point C, and since this is Germany everyone obeys the rules and goes and stands in the correct place opposite where their carriage will stop.
Then of course the train stops somewhere different, and everyone has to run up and down the platform looking for where their carriage actually is.
The good news is that some of the carriages actually have their number written on them – some have the number on a little digital display near the ground, some have them written in crayon on the window, but a lot of them do not, and coming back from Hamburg I worked out which was the carriage I wanted by a lucky guess.
Anyway, once you find the right seat it is quite an enjoyable trip. I got to Hamburg with easily enough time to spare to get to the hotel and then to the beer event at the Alte Madchen (Old Girl). More on how that venue works at the end of the blog.
One important point to note is that in the Hamburg main railway stations there are loads of cash machines, which is important as (a) as far as I could see this is a cash only city and (b) outside of the station there are virtually no cash machines as the banks have been closing all their physical branches.
None of this seems odd to anyone.
In any event it was good to have a few pre-event beers with some of my fellow delegates. I always like the point where you are talking to someone and then suddenly realise you have read their blogs on the SCN.
At this point I could do some food reviews and talk about the dustbins but instead I think I will jump ahead to the next day and the actual content of the conference.
1 Jack and the Beanstalk – the ABAP Cloud – Frank Jentisch
The latest thing to climb the beanstalk into the cloud is the ABAP language. This was announced at SAP TECHED 2017 in Las Vegas by the CTO of SAP.
The conference started off with a talk about this – effectively the keynote speech – but I am not sure how much I can put in this blog about it because some of it was secret squirrel stuff and I don’t know what was secret and what was not so I am going to err on the side of caution and not say anything except it is fascinating and scary as hell.
Instead you will have to re-write 20 or 30 years of custom development in a new version of ABAP
Unless of course all your code is written in OO, and in a SOLID way at that, in such a way as it can easily have unit tests run against it. I imagine all of your custom code is like that and if so, it will be a breeze to migrate it to the ABAP Cloud.
If for some bizarre reason all your Z code is not all like that you may find it rather more difficult.
2 Collapsing Chairs – Test Driven Development – Me
Then it was my turn. I have given this speech (about my real life experiences with test Driven development) a few times now – to a special interest group in the UK, to an insurance company in Cologne and now to the SIT at Hamburg.
There is no point me re-iterating everything I keep saying, I will just add the links again here:-
I always start with Jelena’s quote about TDD being a colossal waste of time, sped a little time on the theory, most of the time on how I have been finding it in real life, trying to be as honest as possible, and ending by trying to refute some popular arguments against the whole concept.
Each time I give the speech I revise the content quite a bit based on the questions I get each time. I got some good questions this time as well – after the talk – and will be hopefully improving this once again for when (hopefully) I give it as SIT Rome on the 23rd of June.
As an example I got asked once or twice about what happens when a new set of configuration values go into production and your program breaks – do you have to re-do all the tests?
By the very nature of unit testing – using test doubles to read configuration – none of your existing test can possibly break due to a new entry in a database table – as that database table is not actually being read.
What you need to do as a first step is to create a test in development which exactly mirrors the situation in production i.e. have the test double return the values it would in production when presented with the inputs causing the problems in production.
You write the test first – not the solution – and fiddle with that test until you are getting the exact error that happens in production. Then you know that changing the production code such that the new test goes green will fix the problem at hand.
However I think what I am being asked is – what if making that change to fix the latest problem breaks a whole bunch of previous tests? Does that means that all the previous tests need to be re-written? Do you have to re-write all your tests on a regular basis?
If I was French I would say “Au Contraire!” If I was German I would say “DOCH!” As I am English I will say “No, not at all. Here is what happens”.
We had a previous situation where the production code handled (say) six different situations but not the new seventh situation. Following TDD precisely the production code was changed just enough so that the new test passes. This broke the previous six tests. To put this another way the more tests we have the more specific the tests are i.e. this must work is less specific than this and that must work which is less specific than this and that and the other thing must work. So over time as we get more problems the test become more specific.
So we went from a situation where six scenarios passed and one failed to the reverse.
It does not teak a mega-genius to realise that we now need t move to a situation where all seven scenarios pass.
It is highly unlikely the existing test need changing. Rather the production code needs changing until the point it can handle all seven scenarios without falling over in a heap and at that point all seven tests will pass.
The important point to note here is when making that change to the production code adding another branch to an IF or CASE statement is not the way to go, as then you will just run into the exact same problem down the track when yet another new combination is added.
Rather you must future proof the existing code to be able to handle that as yet non-existent new entry – by adding another layer of abstraction in some form which is, in a sense, what OO is all about. You tend to add abstractions each time you find an assumption the program is making turns out to be wrong. Adding these abstractions makes the production code more generic – in other words in can handle more current situations and potentially more unknown future situations.
Thus we end up at the Robert Martin quote namely “As the tests get more specific, the code gets more generic. Whoa Cowboy! Whoa Cowboy! Whoa Cowboy!”
Leaving the cowboy stuff aside hopefully that gives you an idea what he is on about. I will have a worked example ready for Rome. I would show it to you now but examples for Rome are not built in a day.
I would like to end this section with a description of how I went about creating a unit test this afternoon as part of my actual job.
This time the problem was that lots of users keep putting the ship-to (delivery address) number in the sold-to (customer) field. That situation is pretty easy to spot and the desired behaviour is that the ship-to number jumps down into the ship-to field without the user having to do anything. Then the actual customer is derived, but that is two things and we test one thing at a time. So I need to test for the jumping field. Here are the steps:-
- Create a new FOR TESTING method called MOVE_THE_ST_TO_RIGHT_FIELD as that is something “IT” (the application should do).
- That test method does not yet exist so do the CTRL+1 trick to auto-generate the definition and implementation.
- Inside the new test method create two GIVEN methods, one to say a ship-to record exists in the database, one to say the user has entered it in the wrong field
- One WHEN method to call the production code
- One THEN method to assert the correct result
- The two GIVEN methods and the THEN method do not yet exist so I auto-generate them.
- This is vital – code the THEN method next – add the assertion that the ship-to field is not blank. I recalled that BOOLC was the wrong function to use but I could not remember the correct one so I thought stuff it and used BOOLC – whereupon Eclipse popped up a message telling me to use XSDBOOL instead! That was spooky.
- Anyway now run the unit tests. The new one fails naturally.
- In the first GIVEN method I code a call to a not yet existing method in my test double database class to add a KNVP record for the ship-to. NB I have the test class code open on my left monitor, the test double code on my right monitor.
- I auto-generate the method in the test double and because I am passing in a KNVP structure it gets the type right. As the method auto-generates my right hand monitor starts bouncing up and down and ends up focussing on the newly created empty method that has just been created.
- So I add the code to add the record in the test double to a table that does not exist. Eclipse complains but lets me auto-generate the internal table declaration just like normal ABAP does.
- In the second GIVEN method I pass to my test double view some mock user input which has the ship-to number in the customer field and nothing in the ship-to field.
- I run the test again – it still fails as I have not yet written the production code.
- In the production code I now auto-generate my new method to look for the situation and move the field (this is a derivation in BOPF terms). The code is trivial.
- I re-run the test. It goes green. My existing tests are still green so I have not broken anything.
- If the whole cycle took more than ten minutes I would be surprised.
- Then I repeat the process for the next test i.e. getting the customer for the ship-to….
3 Grafitti#1 – Code Comments – Laurens van Rijn
I had heard the term “technical debt” many times before but never really understood what it means.
I now understand is that when you do something the easy way, or in a stupid way that still works, rather than in the best way (which might be a lot harder to do or take a lot of time) then you are creating a “debt” that someone at some point in the future has to repay by cleaning up your code once it starts causing a problem. That person who has to reap the debt might even be you.
The problem is you are often forced to do things the wrong way due to time pressure as in “do not add unit tests, we have to go live next week” where the debt is that a few weeks down the track you have to spend hours or days debugging to see where exactly the problem is.
I will say this again because I cannot say it enough – VIZ once advised Starship Captains to try the last thing that could possibly work first, thus saving themselves a lot of time trying other things.
In the same way about ten billion times I have spent all day debugging and then when I find the exact place the problem is, ten minutes later it is fixed. What if you could be directed to the exact place first where the problem is rather than having to go through all that agony? That is one of the promises comprehensive unit tests make to you.
I have gone off topic as usual.
Technical debt is usually thought of in terms of the actual code being sub-optimal. You would not think comments would fall into that category. However now the fact has been brought to my attention I could not agree more.
Going back to the “future you” situation, you probably have been in the situation where you look back at some code you wrote six months or five years ago and are really puzzled why you did it that way. There may have been a good reason or you may have been having an off day, anyway you change it to make it better and then when it hits production you suddenly realise the original problem when it re-occurs. A comment as to WHY you did it that way would save a lot of grief.
One of my colleagues sent me a joke about this as follows:-
My friend has just sent me a nice story “Why do I hate working with someone else’s code”. It was in Russian, but I do want to share it with you, so here is my translation
Let’s imagine that you need to finish the construction of a laboratory on an island. You come to the island to check and you see the half-ready building, huge ventilator (size of the building), a balloon and one room in the building is full of mops.
OK, you get rid of all the rubbish (i.e. the mops, the ventilator, the balloon) and finish the construction. The scientists move in, but after 5 minutes they run out screaming “Leak of poisonous gas!”
“WTF! It should have worked fine!” – you scream frustrated and call the previous building company (M – me, P – previous company responsible guy)
M – “We have a leak of poisonous gas! What can be the problem?”
P – “Did you change anything in the project?”
M – “A bit, got rid of the mops…”
P – “!!! They were holding the ceiling!”
M – “What?”
P – “I tell you they were holding the ceiling. There are tanks with gas upstairs, they are too heavy, I had to put the mops into the room below to hold it”
M – “You should have put a comment on the door! But what we do now? We have gas here you know”
P – “No problem, switch on the ventilator”
M – “I got rid of it!”
P – “Why?”
M – “Why the hell did you build the thing? You should have provided gas masks for everyone!”
P – “Masks cost money and this ventilator I had from my previous project”
M – “Anyway I have removed it, what should we do?”
P – “Get into the balloon and fly away…”
The whole idea here is that the “technical debt” with comments gets paid back when it comes to someone maintaining the code at a later point in time. The debt is either a lack of good comments which help them or an abundance of bad comments that get in their way.
Comments which say WHY something was done so the same problem does not re-occur
Unit Tests – though they are code not comments if done (named) correctly the test class and test methods names serve as “alternative comments” as they describe what the program is supposed to be doing, and even describe problems that have occurred in the past.
Bad comments are “noise” – they obscure the actual code by adding useless lines of nonsense which make you have to scroll up and down to see the real code which you are trying to understand thus making your life harder.
Changed on 02/07/2013 by BLOGGSJ – that adds nothing and you can find that out anyway by the version control
The actual transport number e.g. Begin of ABCK123456 / End of ABCK123456. Once again the version control systems can tell you this.
Commented out code of any sort – for the exact same reason as the last two. I delete any commented out code I find on the instant. I have seen routines with one hundred lines of commented out code and about twenty lines of actual code scattered throughout.
Helpdesk system references e.g. HEAT 9532. They means nothing and eventually the helpdesk system gets retired so you cannot see the details anyway.
Any sort of BEGIN OF CHANGE / END OF CHANGE especially if you keep the prior code above the change as a reference.
Saying “read customer data” in a comment above SELECT * FROM KNA1. If you think someone does not know what KNA1 is, wrap the SELECT in a method which says what it is.
Saying “read customer data” in a comment above a method called READ_CUSTOMER_DATA
Saying “read customer data” in a comment above a method called DATA_GET – instead lose the comment and give the method a proper name.
Saying what a variable means in a comment at the end. Instead rename the variable so it is obvious what it means.
I did not know tis but the code inspector can be set to look for (say) 4 or more lines of commented out code so you can go hunting for them and delete them. I am going to be making that setting just as fast as I can.
The talk ended with a discussion of ABAP Doc which is based on JavaDoc and enable automatic generation of HTML descriptions of signatures and the general purpose of a method or whatever when you hover your cursor over it in ABAP in Eclipse.
I may have got this wrong but I understand that as from 7.5 putting an ABAP Doc comment over the name of a method makes that name appear in SE24 next to the method, which would be really good as loads of people complain that when you generate methods in ABAP in Eclipse you cannot give them a description like you can in SE24. I tried that today. It works fine from SE24 into the ABAP in Eclipse code but realistically no-one is going to manually type what is in essence a 32 digit password to get the description flowing back the other way.
As a last point amazingly there is a code inspector check where you fail if you do not have enough comment lines and some companies insist on this passing so developers just add nonsense like nursery rhymes as comments just to get the code inspector to pass.
Then it was time to get interviewed! I must have looked nervous as one of the cameraman suddenly leaped at me and shouted “WE DO NOT BITE!” which did not actually calm me down as much as he might have hoped.
I still cannot get used to the modern world – as an example I find it amazing then we are doing our talks at SIT they ae getting live streamed over the internet so anybody who is bored enough anywhere in the world can have a listen if they want.
5 Graffiti#2 – Code Noise – Timo John
In some ways this was a continuation of the theme of the last talk in that “code noise” is that part of the code which does not add any value to you when you are trying to maintain it i.e. understand what it does so you can fix it which is the reason you are looking at it in the first place.
In this case the code noise was boiler plate code for exception handling and logging. The main point to note waste ever popular need to something like
IF 1=2 MESSAGE E099(ZSOMETHING) WITH A B C D. ENDIF.
This is followed by passing the message variables once again into some sort of log like what happens with BAPIs.
The IF 1=2 construct is just so the message gets picked up in the “where used” list when it gets output in production and you are trying to work out where it came from.
The speaker – just like me – had had this whole world view on macros turned upside down by the following blog:-
And had – like me – decided to use them to solve the problem of reams of repetitive code again and again.
If you have a method call inside a macro, the debugger will stop inside that method.
If you have a statement like the IF 1=2 one above with a message call, and that is in an INCLUDE and that INCLUDE is in a method, the where-used list will return the line in the method where that macro is called. That is because internally the ABAP system does not “see” the macro but rather the lines of code that make up the macro.
This is why the speaker had to use INCLUDES to store his macros rather than using methods – just to get the where-used” search on an error message to work.
The obvious benefit is that the code is a lot more compact as the “boring” things like error handling and logging (which are the same for every program with just some input values changing) get reduced to one line thus giving more prominence to the important bit i.e. the business logic which is specific to the application at hand.
6 Barn Clearing – S/4 HANA Code Adaptation – Ingo Brauninger
I gave a very similar talk to this at SAP TECHED in Las Vegas in 2017 about my experiences running analysis on my company’s code, but of course this was a generic SAP talk, and of course all the tools have changed!
On his system he was running ABAP 7.53 – that is supposed to be out in four weeks, but I imagine the official release will be delayed till TECHED 2018 as per usual.
Anyway in the latest version of ADT (ABAP in Eclipse) you are going to get little yellow warning blobs every time the code will not work so well in S/4 HANA e.g. a SELECT without ORDER BY or someone typing MATNR as CHAR18 which I have never seen anyone do ever but am assured is really common. The CTRL+1 will auto-fix the code for you. E.g. by adding ORDER BY PRIMARY KEY
The whole point of the talk (and I stressed this last year as well) is that you start right now even if you are not moving to S/4 HANA until you absolutely have to in seven years’ time when you are forced to (like my company).
Add the HANA checks to your default code inspector checks, and do what it says whilst changing programs. Rather do this slowly over seven years than a massive effort at the last minute.
Moreover run the SCMON usage check as well to discover the 75% of your custom code that never runs ever, so you can either delete it or at the very least flag it as irrelevant so you do not waste your time checking it for upwards compatibility – and do not copy it over to your S/4 HANA system when the day dawns..
7 War Story – History of EDI – Phillip Liegl
I love doing B2B projects, and EDI has not really yet taken off yet in Australia, so this are is an interest of mine.
It turns out like so much technology EDI was born out of the Second World War. More specifically when Germany was split into four zones and supplies had to be airlifted into the non-Russian half of Berlin. At this point was born the “advanced shipping notification” we know so well today as a DESADV IDOC.
As I know only too well the biggest problem is how to have a “lingu franca” between the two computer systems so they speak a common language when referring to a material, for example.
We were introduced to the GTIN which is the number you see on products next to the bar code on virtually anything you buy, and identifies the product in a globally unique way.
The main problem with having such standards so both sides of an EDI transaction can understand the other is that there are five hundred million different global standards organisations like ISO and ROSETTA and so on, all with different standards. So you pick which standard you want and hope your partner picks the same one, which they most likely will not. That is why companies that act as a middleman thrive out of the chaos the corporate and IT world has inflicted upon itself.
One interesting thing was that much was made of XML as a medium of exchange and how that would kill old flat formats like EDIFACT (and indeed IDOCS) however XML has ten times the memory footprint of EDIFACT and when you are talking about millions of records that becomes quite important. The messages in PI are certainly huge compared to an IDOC inside SAP.
8 You say Goodbye, I say Silo – Markus Theilen
This was a utility that potentially provided lots of different services to the same customer – power, internet and so on. They had a different application for each and loads of different applications, each with a separate copy of the customer’s data.
They stuck a HANA database underneath and had all the back end applications read and write customer to that, and all the front end (customer facing) applications do the same.
That involved data replication, but the advantage was all the groovy things the HANA platform could do with the data like predictive analysis and spatial recognition and presumably features that have not yet been added to this rapidly evolving product.
9 Come on Baby, Light up the Requirements – Rainer Winkler
You may have read some of Rainer’s blogs here on the SCN about trying to make sense of the incomplete or downright crazy requirements we programmers tend to get. He demonstrated his spreadsheet tool (which is open source and freely available) for keeping track of the requirements.
He notes there is no shortage of good books on the subject of writing requirements and there is even a chapter in CODE COMPLETE on the subject.
He pointed out that a requirement with any of the words “And / Or / But” inside it is not a requirement but two or more requirements and should be treated as such. In addition error handling is often forgotten in the requirements – you just get the “happy path”.
His requirement spreadsheet is organised like a textbook – with main chapters and subsections and individual requirements at the lowest level.
What does that remind me of? Why test classes and test methods of course! Based upon the requirements stored in this tool, which give you meaningful names so you do not need redundant comments and force you to write your programs in a SOLID way so it becomes easy to migrate them to ABAP in the Cloud! You see how it all comes together?
10 Alte Madchen
This is the pub where the Friday and Saturday night events were held. First off there is nothing at all wrong with the venue and the food and drink are clearly excellent. There is however something amiss with the business process and that is always something I am interested in.
It is self-service i.e. when you want a beer you go and queue up and get it, which is fine with me. All pubs in the UK and Australia are like that.
The problem is that there are two queues. The first is really fast moving as there are three people taking your beer order. So you get served (sort of) and pay quiet quickly. Then all those orders are given to one poor girl who has to pour all those beers whilst people wait in the second queue.
German beers are quite frothy and take a while to pour as you have to wat for the foam to subside. So in the time it takes her to pour one beer, orders for four more have come in. As a result she has about twenty half poured beers in front of her at any given time with extra orders coming in every 20 seconds, so she is in constant motion, moving at superhuman speed, whilst the order takers are idle half the time. Nonetheless it is physically impossible for her to keep up with the demand. You would need an octopus that could pour eight beers at once, and I have never seen one of those working in a pub.
As a result the second queue takes forever. After going through this process once I vowed never again. I even tried to cheat and instead of joining the real queue once I went into the room next door (restaurant) and saw five barmen behind the bar, doing nothing, talking to each other, waiting for a order from a waitress. I asked them if one of them could serve me from the beer pub right there in front of me and I pay and they put the money in the till right there and since they were obviously not doing anything what was the problem but no, this was Germany, that was against the rules.
How this relates to IT is the concept of agility – if someone in the organisation, say the manager, looked and saw an enormous queue every night and three idle people and one overworked person possibly they might want to look into what the (quite literal) bottleneck was?
I know building sites work like that (five people watching one person work) but there are no queues of people there waiting for beer (you would hope).
Moreover I bet someday someone will sell the manager an AI system and it will recommend something radical like having the same person take the order and pour the beer (that crazy process we have in the UK and USA) and they will adopt the recommendation and the huge queue will vanish and people will say “look how wonderful AI is, it solved a problem humans never could have”.
Whilst I am on silly processes the café in the airport in Brussels where you go up to the counter and get whatever it is you want but then you cannot pay the attendant, and they put the money in a till or something, no you have to put your money in this stupid machine which has difficulty recognising money, so keeps spitting it back out, and so it takes you ten minutes, whilst the attendant watches you because she is bored. That works really well also.
One of my colleagues went through that, my other colleague watched him and then went to the café opposite which had the old fashioned system of paying someone and they put the money in a till.
This was an excellent event. The quality of the speakers was very high indeed and by accident or design all the subjects seemed to complement each other.
It also cannot be overstated how important networking is at these events, meeting people who I only know from their blogs (like Eno Wuff and Rainer Winkler) as well as a whole bunch of SAP people from all over the place. Normally when I say networking I mean drinking, and while there was some of that in the evening the conversations in the breaks were fascinating as well.
I would say if you can possibly make it to SIT Hamburg next year then go for it, falling that get to the next SIT near you. In 2010 there was just one a year – now in Europe there is one a month! Naturally in other regions things are not that crazy, but this is one area where scope creep is a good thing!