ABL Unit questions

Posted by DenDuze on 27-Oct-2016 06:23

Hi,

I'm playing with this ABL Unit and have some questions:

  • As far as I noticed you can put all tests (@test) into the existing .p (with the existing BL) or you can put all tests into a separate .p/.cls
    The advantage of putting it in the existing .p is that you see that there are tests defined for this .p but I guess it's not really the recommended way of implementing the tests.
  • When I loop some records and perform a test for all those records the Unittesting stops after the first failure
    Isn't it possible to loop all records so I can see how many failures i get?
  • Are there some simple real world examples of how to start with this ABLunit?
  • When I look at https://raw.githubusercontent.com/CameronWills/OEUnit/master/doc/images/oea_example1.png (example of OEunit instead of the ABLunit) I see a column "Result" in that browse.
    Is that also possible in Architect with OEunit??

Regards
Didier

Posted by Mark Abbott on 28-Oct-2016 08:55

Hi Didier,

OEUnit will also fail on the first failure in a Test case, the same as ABLUnit, correct. There is no way to change that behaviour that I am aware of.

A DataProvider allows you to parameterise a Test case, so that it is called multiple times with different parameter values. For each "record" in the DataProvider, the Test case is called, regardless of the results of previous tests. So, for example, if you have 5 sets of parameter values in the DataProvider, and the third set of the five fails an assertion in the Test case, the Test case will still be called with the fourth and the fifth sets of parameters. Each call to the Test case is split out into a different line in the results, so you should be able to pin-point the test failure to the data.

Hope that helps!

Mark

All Replies

Posted by cwright on 27-Oct-2016 07:14

Dider,

* You can put your tests into any Procedure file or Class file. However this is not the recommended practice. You should keep your tests separate from business logic. The best approach (and one that happens automatically when you add the ablunit facet) is to create a "tests" directory. In there you put your test cases. Test cases can be organized into logical units through the use of test suits.

* A test procedure / method should really only have a 1 to 1 ratio of test & assertion. This is why you have @before and @after annotations. If an assertion fails, then ABLUnit will go on to the next test. If your code errors out, the it will stop.

* One example, that I illustrate when I engaged on CI/D is to begin with a test case that verifies system integrity. Such as the values in a control table or perhaps specific files on disk.

* The window that displays the results in PDSOE is different for ABLunit as opposed to OEUnit. They are both xUnit formatted, so the display depends on the viewer. I know that when you import xUnit tests into Jenkins, they do not look like either.

Hope this helps

Cameron

Posted by DenDuze on 27-Oct-2016 08:11

Hey Cameron,

Thanks for the answers I will try the suggestions

Now i have another problem.

from inside a method I call another method where the tests (@test) is done.

When i call that @test method without parameters it works but when I add a parameter in the call and in the called method the test fails with "Could not locate method 'FirstTestMethod' with matching signature".

Why is that? Can't I provide a parameter to the @test method??

Posted by Sanjeva Manchala on 28-Oct-2016 02:01

Hi Den,

For your last question:

>> Why is that? Can't I provide a parameter to the @test method??

There is no parameter support for procedures or methods in ABLUnit. You can find the same information in the following KB article:

knowledgebase.progress.com/.../ABLUnit-Lack-of-Parameter-support-for-procedures-and-methods-not-documented

Hope this helps,

Sanjeev.

Posted by DenDuze on 28-Oct-2016 03:02

Hi Sanjeev,

OK, Thanks but still I find this very strange.

No problem I can solve this .

But I'm still having problems that I can't perform a test for a range of records!

if there occurs a failure on 1 of these records the whole ABLunit procedure stops. (see also thread: ABLunit - How to perform test for multiple records with failures)

Do you have a solution for that?

Is there also some way to return the detail message of the failure (let's say to some file).

regards

Didier

Posted by Phani Sajja on 28-Oct-2016 06:43

Hi Didier,

Are you looking for parameterized tests similar to JUnit (github.com/.../parameterized-tests). If yes, the features is not available in ABLUnit.

During the execution of a test, if an error (exception) is occured, the test is considered to be a failure test.

Currently, the full stack trace is generated where the failure happens and will be part of results.xml file.

--

Regards,

Phani S.

Posted by Mark Abbott on 28-Oct-2016 07:22

Hi Didier,

To expand on Phani's response, parameterised test functionality is available in OEUnit (if switching frameworks is possible for you) as a "DataProvider".

It is not currently in a formal release, but is in the master branch of the OEUnit repository on Github (https://github.com/CameronWills/OEUnit)

Details of the functionality are included in the OEUnit docs (preview here: https://htmlpreview.github.io/?https://github.com/CameronWills/OEUnit/blob/master/doc/dataprovider.html)

Thanks,

Mark

Posted by DenDuze on 28-Oct-2016 07:32

Hi Phani,

I can't answer that ;-) I'm not so familiar with UnitTesting but I find it interesting.

What I want to do is to always prepare a DB with all expected records in my tests.

Then run the tests with the needed for each-statements for the specific tests.

I expected then to see how many calls of a specific tests failed due to other result then expected.

But I see that ABLunit always stops a test when the first failure in that test occurs and I was wondering if I can prevent that.

example: I have a BL that adds 1 to the last number from an input value.

this input string can be <number>, <string>, <number><string>, <string><number>, <number><string><number>, ....

So I would create a record for every possible combination

Do a for each on these records and call for every record the test-method

Check on Assert:Equals

In that way I can check my BL on returning a expected value for all situations in 1 run.

Now I need to create for every situation a @test-method and in that @test-method I need to find the record (or hardcode the input value), call the BL and check the result.

I find that much overhead but OK if it must be done this way then it has to (I guess)

Isn't there some way to keep running the same test (with other input) when a failure has occured and see the sum of all failures of that test?

Thanks

Didier

Posted by DenDuze on 28-Oct-2016 07:51

Hi Mark,

Nice to know.

i've read about that OEunit but I thought that ABLunit was replacing this OEunit.

Is it the intention that OEunit keep existing in the future or will it be replaced by ALBunit?

regards

Didier

Posted by Mark Abbott on 28-Oct-2016 08:13

Hi Didier,

OEUnit is an open source project by the community, where as ABLUnit is provided by Progress.

OEUnit will keep going as long as people keep contributing to it.

Thanks,

Mark

Posted by DenDuze on 28-Oct-2016 08:29

Hi Mark,

Ok if it's keeps going then maybe I have to try this out.

I already looked @the documentation and there are some extra possibilities there.

But OEunit has the same behaviour when it comes to the first failure in a test (I think)

If I use a DataProvider to run a test multiple times then this will stop on the first failure.

Is there no way to prevent this in OEunit?

I would think that it is usefull that you get a list of all failures when running a specific test with different data.

regards

Didier

Posted by Mark Abbott on 28-Oct-2016 08:55

Hi Didier,

OEUnit will also fail on the first failure in a Test case, the same as ABLUnit, correct. There is no way to change that behaviour that I am aware of.

A DataProvider allows you to parameterise a Test case, so that it is called multiple times with different parameter values. For each "record" in the DataProvider, the Test case is called, regardless of the results of previous tests. So, for example, if you have 5 sets of parameter values in the DataProvider, and the third set of the five fails an assertion in the Test case, the Test case will still be called with the fourth and the fifth sets of parameters. Each call to the Test case is split out into a different line in the results, so you should be able to pin-point the test failure to the data.

Hope that helps!

Mark

Posted by DenDuze on 28-Oct-2016 09:45

Hi Mark,

Great that is just what I wanted!

When does this version comes available?

regards

Didier

Posted by Mark Abbott on 28-Oct-2016 10:09

Hi Didier,

To be honest, I don't think anyone is working to a schedule for the next release. It has been a while since the last version with several new features added, so we could do one soon (pending one outstanding Pull Request to review.)

That said, the releases are just snapshots of the master branch, so using the contents of that will give you the functionality you need. Reviewing your other comments, there is also Fixture functionality in the master branch which might also give you other functionality you may need.

Thanks,

Mark

Posted by Kai Siegele on 31-Oct-2016 10:55

Hallo Didier,

When you use Assert:IsTrue or Assert:IsFalse in addition to the check condition you can specify a detailed message about the testcase f.e. parameters and what you have expected. This message is written into the result xml-file as a failure message and it improves in my opinion the readability of the testprogram.

Regards

Kai

Posted by DenDuze on 03-Nov-2016 05:09

Hi Mark,

I tried the DataProvider in OEunit, it looks like the data gets loaded into the defined dataprovider.

The problem is that I can't find out how to get the data out of there and use it in some test

I found some methods like movefirst, movernext,..

I also found some things to get the parameterlist (progress.lang.parameterlist)

But I have no idea how I can get the values out of that DataProvider or ParameterList to check if the value of a field is allowed or not by my tests

I can get the values if I change the protected variable ttQuery (from the DataProvider.cls) to public but I guess that is not the way to go (it was just testing).

Can you give me a hint?

Remark: I don't know if I should create a new thread for this (because this thread is answered) of not

Regards

Didier

This thread is closed