Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Is it possible to test ASSERT in ABAP Unit? ​

pokrakam
Active Contributor

I would like to catch assert failures in ABAP Unit tests.

Technically it should be possible, because the ABAP Unit framework does intercept them. We get a message "[The ASSERT condition was violated.]" instead of a dump. Instead, I would like to unit test that the ASSERT fails. Unfortunately I can't find anything in the AU framework to handle it.

I could raise an exception instead of ASSERT, but I think ASSERTS have their place and it would be useful to be able to test these. Ironically, the ASSERT I was trying to test this with had an error in it and wasn't being raised at first, so my testing had real value here.

1 ACCEPTED SOLUTION

former_member183804
Active Contributor

Hello Mike,

if I understand the requirement properly the intend is to validate the use of ASSERT methods in concrete tests for correctness. Well that is tough. ABAP Unit internally uses EVENTS both in the session of the test sandbox executing the test methods as well as in the session of the test driver. As such you can theoretically register to the event but not intercept it. Thus it is virtually impossible to test the use of ASSERT methods within test methods. Besides these EVENTS are an ABAP Unit internal detail and as such referring to them is strongly discouraged.

The use of the ASSERT statement as mentioned before is no alternative either. It terminates the ABAP runtime and prevents this way any programmatic validation of the behaviour of your tests in the same ABAP session.

To try tests of test code I would introduce custom asserts. That is you provide a class with your own custom assert logic. For instance in standard test mode delegating to methods of CL_ABAP_UNIT_ASSERT and to execute some extra behaviour for the meta test mode.

Looking on my personal best practices I use custom asserts to improve readability of tests and failure log. I doubt that using them for the meta tests would yield such qualities for the meta tests. And as readability and thus maintainability is very important to me I won´t go this way for my own tests.

Do you have only positive tests that ensure the functionality is working properly? If so, yes I know that is not only slightly different, adding negatíve test logic that ensure the functionality fails properly for faulty input might soften up the original problem.

Hope this helps

Klaus

10 REPLIES 10

Sandra_Rossi
Active Contributor

I use ASSERT only as a kind of documentation, i.e. hint for readability, to say "here it's definitely impossible to have this value different from this one, and I prove it as it never dumped".

But usually ASSERT is only for easy assertions, not complex ones.

So, either I use ASSERT in the code for easy assertions and there's no corresponding ABAP UNIT, or I use ABAP Unit for complex assertions and there's no corresponding ASSERT in the code.

Agree. They don't have to be overly complex to warrant testing. To use my current use case: a method can be called in two ways, each supplying one of two optional parameters, but we would never receive values in both.

METHOD blah.
ASSERT p1 is initial or p2 is initial.

ASSERT is used here, because it should not happen, and if it does it is not an exception but a programming fault and the calling code should never go to production.

But it would be nice to unit test it, if only to get rid of the red bits in the coverage results 🙂

0 Kudos

I understand. Is it worth testing it, I don't know. Maybe SAP will propose something in the future.

SuhaSaha
Advisor
Advisor
0 Kudos

Hi Mike,

METHOD blah.
ASSERT p1 is initial or p2 is initial.

i would rather define a dynamic exception & propagate it!

if it does it is not an exception but a programming fault and the calling code should never go to production.

This means that this situation can be actually prevented by the caller & therefore the choice of using a dynamic exception.

Cf. https://help.sap.com/doc/abapdocu_751_index_htm/7.51/en-US/index.htm?file=abenexception_category_gui...

pokrakam
Active Contributor
0 Kudos

No, this would not make sense. I'm asserting that the developer didn't do something stupid. If the developer catches exceptions then they would understand the reason and not be passing the parameters incorrectly in first place.

The other part to consider is simplicity. It should never happen, so adding exceptions just adds unnecessary complexity. If it does happen something is desperately wrong - I also see ASSERT as something stronger than an exception.

The example is just an example, and has no real relevance to the question. There many many other ASSERT scenarios, and it would be nice to test at least some of them.

But as we are discussing it, the background to this example is: his particular case is a private method which can be called from own-developed methods with a Z-datatype or from SAP standard via an SAP interface. Same data passed in different ways depending on who is calling it.

0 Kudos

this particular case is a private method which can be called from own-developed methods with a Z-datatype or from SAP standard via an SAP interface.

If it's a private method, then declaring an exception would make less sense! I was assuming that the method is a public one & you wanna check that atleast one of the "optional" param provided by the caller is not initial.

I also see ASSERT as something stronger than an exception.

+1 ... IMO assertions should be raised when you reach a totally inconsistent state & further processing is no longer an option. For me assertions are the desperate measures in, "Desparate times call for desperate measures".

former_member183804
Active Contributor

Hello Mike,

if I understand the requirement properly the intend is to validate the use of ASSERT methods in concrete tests for correctness. Well that is tough. ABAP Unit internally uses EVENTS both in the session of the test sandbox executing the test methods as well as in the session of the test driver. As such you can theoretically register to the event but not intercept it. Thus it is virtually impossible to test the use of ASSERT methods within test methods. Besides these EVENTS are an ABAP Unit internal detail and as such referring to them is strongly discouraged.

The use of the ASSERT statement as mentioned before is no alternative either. It terminates the ABAP runtime and prevents this way any programmatic validation of the behaviour of your tests in the same ABAP session.

To try tests of test code I would introduce custom asserts. That is you provide a class with your own custom assert logic. For instance in standard test mode delegating to methods of CL_ABAP_UNIT_ASSERT and to execute some extra behaviour for the meta test mode.

Looking on my personal best practices I use custom asserts to improve readability of tests and failure log. I doubt that using them for the meta tests would yield such qualities for the meta tests. And as readability and thus maintainability is very important to me I won´t go this way for my own tests.

Do you have only positive tests that ensure the functionality is working properly? If so, yes I know that is not only slightly different, adding negatíve test logic that ensure the functionality fails properly for faulty input might soften up the original problem.

Hope this helps

Klaus

0 Kudos

Hello Klaus,

Thanks for your comprehensive answer, it does explain it.

I like the idea of a custom assert, kindof like a production version of the CL_ABAP_UNIT_ASSERT, will give that some thought. On the flip side it does add a little overhead, so would probably use standard ASSERTs for the pure sanity check/unrealistic scenarios.

Re. your question "Do you have only positive tests that ensure the functionality is working properly?". No I am also doing negative tests to ensure it will break when it's supposed to, and this is exactly my reason for wishing to test ASSERT statements. If it takes 30 seconds to write two lines of code to test a validation condition then it's a quick win.

Thanks,
Mike

rainer_winkler
Contributor
0 Kudos

Hello Mike,

I just tested an assert with the help of a test-seam. In the test-injection I did set a static attribute of a local class for testing. This static attribute will be set when the assert statement would be executed. In my case I tested only for "ASSERT 1=2". The local class for testing is therefore defined as:

CLASS test_container DEFINITION FOR TESTING.
PUBLIC SECTION.
CLASS-DATA:
assert_raised TYPE abap_bool.
ENDCLASS.

In the test coding I tested for test_container=>assert_raised equal to X.

Kind regards,
Rainer

PS: The proposal by klaus.ziegler should also work. It is probably a matter of taste how to solve this problem.

0 Kudos

Hi Rainer,

Thanks for the input. I must admit I'm not a big fan of test seams, but I suppose your approach would be a useful interim solution before refactoring.

FWIW, I simply work around the problem. I liked the idea of an assert framework, but haven't had the opportunity to implement it. Following clean code principles, either an ASSERT is so simple that it doesn't need testing, or if it's complex enough to warrant testing then it's worth coding an alternative.

For example, this use case was to ASSERT that only one of two alternative parameters was supplied. Simple enough check not to have to do elaborate coding, and ASSERT is perfectly sensible as it's a programming error that should never make it to production. So one could e.g. refactor

methods find importing i_val type clike optional
                       i_ref type ref to data optional.
...
method find.
  assert i_val is initial or i_ref is initial.

as:

public section. 
  methods find_by_value importing i_val type clike optional.
  methods find_by_ref   importing i_ref type ref to data.
private section. 
  methods find importing i_val type clike optional
                         i_ref type ref to data optional.

Since we only test public methods and the developer of the class is in full control, testing the ASSERT is not as important since it's not guarding against outside calls anymore. And the outside interface is clearer too.