Claiming ABAPUnit – Again. Part 2: More tests, some thoughts and Adt is awsome!
Part one of this series is here: https://blogs.sap.com/2021/12/05/claiming-abapunit-again.-a-walktrough-part-1/
(Maybe you note the change of users – yeah, I currently have 4 to my name… that’s a different story, and I would like to tell it, but not now)
It’s new week, and I’m back into coding.
I also keep working on unit tests.
I have a new filter method, so I’ll just do with it what I did with the others:
METHOD test3_consignment_stock_filter. "given: build the test data table: APPEND line_3_with_stock_usage_c TO mt_stock_mon. *Filter should delete it: "when cut->filter_data_consignment_stock( CHANGING ct_stock_mon = mt_stock_mon ). "then Table should be empty: cl_abap_unit_assert=>assert_initial( act = mt_stock_mon ). ENDMETHOD.
I also remembered that wenn I add stuff to mt_stock_mon in a test, that line might still be there in another test.
So I could clear it 1st thing in every test.
Or I do that in the setup(): (I need do check: setup is executed once before every single test, right?)
METHOD setup. "given cut = NEW zclewm_stasam_interface( iv_lgnum = '1020' ). line_1_with_qdocid_filled = VALUE #( matnr = '0815' qdocid = '478326423648' ). line_2_with_emtyp_qdocid = VALUE #( matnr = '0815' qdocid = space ). line_3_with_stock_usage_c = VALUE #( matnr = '0815' qdocid = space stock_usage = me->MC_consignment_Stock ). clear me->mt_stock_mon. "always start fresh and new - we want no side effects! ENDMETHOD.
Theres also a question on test philosophy here, where I would be happy to get your thoughts:
I’m creating my (small) test data table mt_stock_mon with every test method.
Another approach would be:
Create a (big) test date table in setup, one the covers every aspect. And is expanded when needed, whenever another test is added. -> run all tests on this big table.
What are ABAPUnit practitioners thoughts on those approaches?
Side note: I try to give meaningful (and also sortable / grouping names). For that, I think I need some words, lots of characters.
The 30 I have available for methods is not that much. So I’m thinking about where to save:
Maybe, instead of naming methods test1_ test2_ etc. I could go for just t1_, t2_ ?
Maybe even dropping the _ ?
(I would like to also drop the T [big kudos to whoever recognizes a South Park reference in that?!], but methods can’t start with a number. )
Next thing: this might be obvious, but maybe not:
Pleas note, how little typing I have to do, when creating a similar, but different test:
My test4 on consignment stock is very similar to test2 on QDOCID, so what I do is this:
– Highlight them complete method test2_
– ctrl+alt+down to copy it
– alt+down(+down+down+down…) to move it, well, down, to after test_3
– change the methods name to test4_
– ctrl+1 (QuickFix) to have the definition for testing generated.
– change what line I want to append ( type: line_4 press: ctrl+space and hit enter to complete.
– change the methods I’m testing (delete the part after filter_ then again press: ctrl+space and hit enter to complete.)
– Last step: Ctrl + Shift + F10 to make it run / watch it fail(*)!
*Yes, I do remember the TDD cycle:
1. Write a test
2. watch it fail
3. write code, so it passes.
4. watch it pass
5. Choose any one of those: write next test / refactor code / refactor tests.
And with that I’ll leave it for today!
For GUI-oriented users or people new to quick assists who don't necessarily know what is on offer at any given time, there is an option to dock the quick assist view somewhere and sync it with whatever you are pointing at.
Ah, yes, good point, thanks! (ctrl+shift+1 will open that view! )
Setup is run once per test. What happens somewhere is
Rather than one big lump of test data, I prefer to have it divided up. Much easier to create, check for errors in your test data, and to understand in 3 months time.
Thanks for confirmation and explanation, Matthew Billingham , appreciate it!
Just like the setup() method is executed before each test, there is also a teardown() method that is executed after each test. That is where I like to clear attributes of the test class, so that when a test finishes everything is back to an initial state before the next test runs. There's probably some personal preference on that, though. I could also see why someone might clear class attributes in the setup() method, to be sure that everything is freshly cleared right before the test executes.
I agree with Matthew Billingham that it's better to keep the test data separate for each test. You can create helper methods/classes to help build the data if there's a lot of duplicated code involved in building that test data.
As far as naming your test methods, I would remove the "test" prefixes altogether, since those prefixes don't communicate anything meaningful about what the test is actually testing.
Thanks for continuing the conversation about unit testing!
The fact that the class begins with ltc tells me it's a test!
I don't think I've ever used teardown.