How to test a class
The best development practices include the design of test cases. For every persistent class, the development partner must create a test case to check that everything is functioning correctly, while invoking standard or additional methods used in the class declaration.
The purpose of this test case is not only to verify that all methods work well with the correct data, but also to examine various error cases and make sure that errors are handled correctly. Before reading this document, it is recommended that you read the How to use AXUNIT document.
A test case consists of a normalized script. A specific chart for naming the test scripts is described in the How to Naming Rule document. For example, a test script on a given persistent class called 'MYCLASS' in the functional domain 'FDO' could be called 'QLF_FDO_MYCLASS'.
The different sections of the scripts and the main considerations about how they must be defined are explained in this document.
Establish the data used by the test
Main data required
Minimum data is necessary to execute the test. For example, customers, items, and currencies might be a prerequisite for the test of methods associated with the sales order.
Two alternatives are available to provide necessary:
- Data description is documented (as comments). In this case, the development partner must ensure the presence of the right data set in the different environments where the test must be conducted. There might be some data present in the SEED folder that will be copied in all the environments where non-regression tests must be executed.
- Data must be created during the test. This can be part of the automated test for the corresponding data as a sub-program in the test case. If a customer is required, a good practice is to call at the beginning of the test case the 'SETUP' sub-program of the test data script associated with the customer class.
Cleaning the data before starting the test
In the 'SETUP' sub-program, a procedure that cleans the data should be written. Because an automated test is likely to fail, this cleaning sub-program:
- Must delete the data created during the test.
- Must be called at the beginning and not at the end. A cleaning at the end of test could not be performed in case of test failure.
- Must not consider that a cleaning error (remaining data) is a failure of the cleaning procedure.
Write the test execution lines
Test execution lines are written using the 'TESTSUITE' function. It is called by the 'AXUNIT' tool from every 'QLF*' script to execute the test.
In the 'TESTSUITE' function, the following sub-programs are called:
- 'TESTSUITE_START' From 'AXUNIT' to describe the test suite.
- 'ADD_TESTCASE' Fom 'AXUNIT' to add the list of test cases to be initiated.
- 'RUN_TESTSUITE' From 'AXUNIT' to run the test.
Every test sub-program added by 'ADD_TESTCASE' has a name. For a persistent class, the name of the test sub-program can be:
Test Case sub-program name | Use |
---|---|
MYCLASS_CREATE | Creation of a class instance |
MYCLASS_READ | Read operation on a class instance |
MYCLASS_UPDATE | Update of a class instance |
MYCLASS_MYMETHOD | Test of the Method 'MYMETHOD' |
MYCLASS_MYPROP_PROPAGATE | Test of the propagation rule on 'MYPROP' property |
When complex documents with headers and lines are created, it is important to test all the operations on the child classes, including the insertion and deletion of lines.
The beginning of the test script looks like the example below:
CODECODE CODEsh
#**
#* The main entry point of the unit test suite
#*
#*!
Funprog TESTSUITE()
# Start the test suite
Call TESTSUITE_START("MYCLASS", "MYCLASS test") From AXUNIT
# Call the different test cases
Call ADD_TESTCASE("MYCLASS_CREATION","Creation of MYCLASS with errors check",0) From AXUNIT
Call ADD_TESTCASE("MYCLASS_READ","Read MYCLASS",0) From AXUNIT
Call ADD_TESTCASE("MYCLASS_UPDATE","Update MYCLASS",0) From AXUNIT
Call ADD_TESTCASE("MYCLASS_DELETE","Deletion MYCLASS",0) From AXUNIT
# Run the test and return the result
Local Clbfile RESULT_SUITE
RESULT_SUITE=func AXUNIT.RUN_TESTSUITE("MYCLASS","MYCLASS test")
End RESULT_SUITE
In the different test cases, to check if the result expected is the right one, the 'CHECK_EQUAL', 'CHECK_NOTEQUAL', 'CHECK_TRUE', 'CHECK_FALSE'... sub-programs from "AXUNIT" must be used. The 'MYCLASS_CREATE' sub-program should look like the example below:
CODECODE CODEsh
# Creation subprogram
Subprog MYCLASS_CREATION()
Local Integer ASTATUS
Local Instance MYINST01 Using C_MYCLASS
# Instantiate the class
MYINST01 = NewInstance C_MYCLASS AllocGroup Null
# Assign all the properties but with some errors (repeat it several times with various error cases)
MYINST01.PROP1 = ...
MYINST01.PROP2 = ...
...
MYINST01.PROPN = ...
[L]ASTATUS = fmet MYINST01.AINSERT()
Call CHECK_EQUAL([L]ASTATUS,[V]CST_AERROR) From AXUNIT
...
# Assign correctly the elements to have successful creations
MYINST01.PROP1 = ...
MYINST01.PROP2 = ...
...
MYINST01.PROPN = ...
[L]ASTATUS = fmet MYINST01.AINSERT()
Call CHECK_EQUAL([L]ASTATUS,[V]CST_AOK) From AXUNIT
# Check also if necessary the values of some properties if they are computed at insertion
Call CHECK_EQUAL(MYINST01.PROP1,"EXPECTED_VALUE") From AXUNIT
# Repeat other creation cases if necessary
...
# End of test
FreeGroup MYINSTA01
End
Complete example
A complete example of a test program for the classes created in the CRUD example is provided below.
The Main routine
The code for the main routine is shown below. This routine starts the job and calls the different test cases, which are:
- An Insertion of an entity (54 unit tests)
- A Read operation on the entity (77 unit tests)
- An Update operation on the entity (11 unit tests)
- An execution of an operation (2 unit tests)
- An execution of a Delete operation (5 unit tests).
CODECODE CODEsh
#**
#* The main entry point of the unit test suite
#*
#*!
Call TESTSUITE
End
Funprog TESTSUITE()
# Start the test suite
Call TESTSUITE_START("YORDER", "YORDER test") From AXUNIT
# Call the different test cases
Call ADD_TESTCASE("YORDER_AINSERT","Creation of YORDER with errors check",54) From AXUNIT
Call ADD_TESTCASE("YORDER_AREAD","Check YORDER previously created",77) From AXUNIT
Call ADD_TESTCASE("YORDER_AUPDATE","Check YORDER update",11) From AXUNIT
Call ADD_TESTCASE("YORDER_YVALIDATE","Check YORDER validation operation",2) From AXUNIT
Call ADD_TESTCASE("YORDER_ADELETE","Check YORDER deletion",5) From AXUNIT
# Run the test and return the result
Local Clbfile RESULT_SUITE
RESULT_SUITE=func AXUNIT.RUN_TESTSUITE("YORDER","YORDER test")
End RESULT_SUITE
The Insertion test
This routine creates an order of several steps:
- The instance is created. At this point, a temporary hack has been added because the mandatory constraints are not updated by the class constructor, but this will evolve in the near future.
- Lines and sub-lines are added by using the 'ADDLINE' method at different levels.
- A first insertion is tried but it fails due to an unfilled mandatory information. A detailed log provides a list of all the detected errors.
- A call to an internal method is done to cancel all the errors (this will also change in the future). Otherwise, it would be necessary to re-instantiate a class and fill all the properties again.
- The order number is updated at the header level, a test is done to verify that the lines and sub-lines values have been propagated.
- A second unsuccessful insertion attempt is performed (still some mandatory values missing).
- Errors are written in the log again, and then cancelled. The missing values are filled and a final successful insertion is performed.
- The computation price is verified.
CODECODE CODEsh
# Create an order
Subprog YORDER_AINSERT
Local Instance MYORDER Using C_YORDER
Local Integer I,J,K,L,OK
Local Decimal TOTAL_PRICE
MYORDER=NewInstance C_YORDER AllocGroup Null
# Double loop on lines and sub-lines
# The total price is computed on the fly to be able to perform a consistency check
TOTAL_PRICE=0
# 5 lines inserted
For I=1 To 5
J=fmet MYORDER.ADDLINE("YOD",[V]CST_ALASTPOS)
Call LOG_LINE("Result of ADDLIN I="+num$(I)) From AXUNIT
Call CHECK_TRUE(J>=0) From AXUNIT
# We use existing items coded "BMSMN0020x" where x varies from 3 to 8
MYORDER.YOD(J).YITM="BMSMN0020"+num$(2+I)
# 4 sub-lines inserted for every line
For L=1 To 4
K=fmet MYORDER.YOD(J).ADDLINE("YOL",[V]CST_ALASTPOS)
Call LOG_LINE("Result of ADDLIN L="+num$(L)) From AXUNIT
Call CHECK_TRUE(K>=0) From AXUNIT
# We use successively the units "UN","TEN","CAR","PAC"
MYORDER.YOD(J).YOL(K).YUNIT=vireblc(mid$("UN TENCARPAC",3*L-2,3),2)
MYORDER.YOD(J).YOL(K).YQTY=I*L
MYORDER.YOD(J).YOL(K).YUNITPRICE=5+L
TOTAL_PRICE+=(I*L)*(5+L)
Next L
Next I
# A lot of mandatory properties have no value : LOG_ERRORS will dump them
OK=fmet MYORDER.AINSERT
Call LOG_LINE("Result of AINSERT") From AXUNIT
Call CHECK_EQUAL(OK,[V]CST_AERROR) From AXUNIT
Call LOG_ERRORS(MYORDER)
# Assigning the order number here will propagate
MYORDER.YORDNUM="314159"
# Check the propagation
Call LOG_LINE("Propagate checks") From AXUNIT
For I=1 To 5
For J=1 To 4
Call CHECK_EQUAL(MYORDER.YOD(I).YOL(J).YORDNUM,MYORDER.YORDNUM) From AXUNIT
Next J
Call CHECK_EQUAL(MYORDER.YOD(I).YORDNUM,MYORDER.YORDNUM) From AXUNIT
Next I
# Still a lot of mandatory properties have no value
OK=fmet MYORDER.AINSERT
Call LOG_LINE("Result of AINSERT") From AXUNIT
Call CHECK_EQUAL(OK,[V]CST_AERROR) From AXUNIT
Call LOG_ERRORS(MYORDER)
# Now let's assign the missing mandatory values
# Customer code, sales rep code and currency code are supposed to exist
MYORDER.YBPC="BPC-000003"
MYORDER.YREP="REPRE004"
MYORDER.YORDDAT=[09/05/2002]
MYORDER.YCUR='EUR'
MYORDER.YSTATUS=1
OK=fmet MYORDER.AINSERT
# Check if the creation is OK
Call LOG_LINE("Checks the insertion when everything is OK") From AXUNIT
Call CHECK_EQUAL(OK,[V]CST_AOK) From AXUNIT
Call LOG_LINE("Checks the total price computation") From AXUNIT
Call CHECK_EQUAL(MYORDER.YTOTAL,TOTAL_PRICE) From AXUNIT
FreeGroup MYORDER
End
The Read test
This routine reads the previous order and performs the following verifications:
- The return value of 'AREAD' is OK.
- The header properties have the expected values.
- The lines and sub-lines properties have the right values.
- The total price is verified.
CODECODE CODEsh
Subprog YORDER_AREAD
Local Instance MYORDER Using C_YORDER
Local Integer I,J,K,L,M,N,OK
Local Decimal TOTAL_PRICE
MYORDER=NewInstance C_YORDER AllocGroup Null
OK=fmet MYORDER.AREAD("314159")
Call LOG_LINE("Checks the AREAD method") From AXUNIT
Call CHECK_EQUAL(OK,[V]CST_AOK) From AXUNIT
Call LOG_LINE("Verify the values read") From AXUNIT
Call CHECK_EQUAL(MYORDER.YBPC,"BPC-000003") From AXUNIT
Call CHECK_EQUAL(MYORDER.YREP,"REPRE004") From AXUNIT
Call CHECK_EQUAL(num$(MYORDER.YORDDAT),"09/05/2002") From AXUNIT
Call CHECK_EQUAL(MYORDER.YCUR,'EUR') From AXUNIT
Call CHECK_EQUAL(MYORDER.YSTATUS,1) From AXUNIT
Call LOG_LINE("Verify the lines and sub-lines values read") From AXUNIT
K=0
For I=1 To maxtab(MYORDER.YOD)
If MYORDER.YOD(I)<>null
J+=1
K=MYORDER.YOD(I).AORDER
Call CHECK_EQUAL(MYORDER.YOD(I).YITM,"BMSMN0020"+num$(2+K)) From AXUNIT
Call CHECK_EQUAL(MYORDER.YOD(I).YPRICE,sigma(1,4,K*indcum*(5+indcum))) From AXUNIT
For L=1 To maxtab(MYORDER.YOD(I).YOL)
M=0
If MYORDER.YOD(I).YOL(L)<>null
M+=1
N=MYORDER.YOD(I).YOL(L).AORDER
Call CHECK_EQUAL(MYORDER.YOD(I).YOL(L).YUNIT,vireblc(mid$("UN TENCARPAC",3*N-2,3),2)) From AXUNIT
Call CHECK_EQUAL(MYORDER.YOD(I).YOL(L).YQTY,K*N) From AXUNIT
Call CHECK_EQUAL(MYORDER.YOD(I).YOL(L).YUNITPRICE,5+N) From AXUNIT
TOTAL_PRICE+=(5+N)*K*N
Endif
Next L
Endif
Next I
Call LOG_LINE("Verify the total price read") From AXUNIT
Call CHECK_EQUAL(MYORDER.YTOTAL,TOTAL_PRICE) From AXUNIT
FreeGroup MYORDER
End
The Update test
This routine reads the previous order and performs the following updates:
- Deletion of a sub-line
- Insertion of a sub-line
- Modification of a line
- Deletion of a line
- Update of the document
- Verification of the total (lines and header)
CODECODE CODEsh
# The update test
Subprog YORDER_AUPDATE
Local Instance MYORDER Using C_YORDER
Local Integer I,J,K,L,M,N,OK
Local Decimal TOTAL_PRICE, LINE_PRICE
MYORDER=NewInstance C_YORDER AllocGroup Null
OK=fmet MYORDER.AREAD("314159")
Call LOG_LINE("Checks the AREAD method") From AXUNIT
Call CHECK_EQUAL(OK,[V]CST_AOK) From AXUNIT
# Different modifications will be done here:
# Get the 2nd line, then the 2nd sub-line of this line, and delete it
Call LOG_LINE("Checks an insertion at level 2") From AXUNIT
I=fmet MYORDER.AGETINDBYLINE("YOD",2)
OK=fmet MYORDER.YOD(I).ADELLINE("YOL",2)
Call CHECK_EQUAL(OK,[V]CST_AOK) From AXUNIT
# Get the 4th line, then insert a line at the third position of the sub-lines
Call LOG_LINE("Checks an insertion of a sub-line") From AXUNIT
I=fmet MYORDER.AGETINDBYLINE("YOD",4)
J=fmet MYORDER.YOD(I).ADDLINE("YOL",3)
Call LOG_LINE("Checks an insertion of a sub-line"-num$(J)) From AXUNIT
Call CHECK_NOTEQUAL(J,[V]CST_ANOTDEFINED) From AXUNIT
MYORDER.YOD(I).YOL(J).YUNIT="TEN"
MYORDER.YOD(I).YOL(J).YQTY=3
MYORDER.YOD(I).YOL(J).YUNITPRICE=16
# Get the 5th line, then modify the 4th sub-line
Call LOG_LINE("Checks a modification of a sub-line") From AXUNIT
I=fmet MYORDER.AGETINDBYLINE("YOD",5)
J=fmet MYORDER.YOD(I).AGETINDBYLINE("YOL",4)
Call CHECK_NOTEQUAL(J,[V]CST_ANOTDEFINED) From AXUNIT
MYORDER.YOD(I).YOL(J).YUNIT="TEN"
MYORDER.YOD(I).YOL(J).YQTY=10
MYORDER.YOD(I).YOL(J).YUNITPRICE=43
# Delete the 3rd line
Call LOG_LINE("Checks a deletion on a line") From AXUNIT
OK=fmet MYORDER.ADELLINE("YOD",3)
Call CHECK_EQUAL(OK,[V]CST_AOK) From AXUNIT
# Update the order
Call LOG_LINE("Checks the update") From AXUNIT
OK=fmet MYORDER.AUPDATE
Call CHECK_EQUAL(OK,[V]CST_AOK) From AXUNIT
Call LOG_LINE("Verify the lines and sub-lines values after update") From AXUNIT
# K is the grand total, and L the total of every line (cumulated sub-lines)
TOTAL_PRICE=0
For I=1 To maxtab(MYORDER.YOD)
If MYORDER.YOD(I)<>null
If find(MYORDER.YOD(I).ASTALIN,[V]CST_ADEL, [V]CST_ANEWDEL)=0
LINE_PRICE=0
For J=1 To maxtab(MYORDER.YOD(I).YOL)
If MYORDER.YOD(I).YOL(J)<>null
If find(MYORDER.YOD(I).YOL(J).ASTALIN,[V]CST_ADEL, [V]CST_ANEWDEL)=0
LINE_PRICE+=MYORDER.YOD(I).YOL(J).YQTY*MYORDER.YOD(I).YOL(J).YUNITPRICE
Endif
Endif
Next J
TOTAL_PRICE+=LINE_PRICE
Call LOG_LINE("Verify the total price of line"-num$(I)) From AXUNIT
Call CHECK_EQUAL(MYORDER.YOD(I).YPRICE,LINE_PRICE) From AXUNIT
Endif
Endif
Next I
Call LOG_LINE("Verify the total price read") From AXUNIT
Call CHECK_EQUAL(MYORDER.YTOTAL,TOTAL_PRICE) From AXUNIT
FreeGroup MYORDER
End
The Operation test
This routine performs an operation (YVALIDATE) that can return a warning if it has already been performed.
- A first call is performed and the return status is checked.
- A second call is performed and the return must be a warning.
CODECODE CODEsh
# Validate an order
Subprog YORDER_YVALIDATE
Local Instance MYORDER Using C_YORDER
Local Integer OK
# Instantiate the order
MYORDER=NewInstance C_YORDER AllocGroup Null
# First time, it will work
Call LOG_LINE("Verify the order validation result") From AXUNIT
OK=fmet MYORDER.YVALIDATE("314159")
Call CHECK_EQUAL(OK,[V]CST_AOK) From AXUNIT
# Do it again : a warning is expected
Call LOG_LINE("Verify the order validation result with warning") From AXUNIT
OK=fmet MYORDER.YVALIDATE("314159")
Call CHECK_EQUAL(OK,[V]CST_AWARNING) From AXUNIT
FreeGroup MYORDER
End
The Deletion test
This routine performs a deletion:
- First, the instance is read.
- Then a first attempt is done: it fails because the order has been validated by the previous test.
- The validation flag is updated by a direct database update.
- A second call is done that must succeed.
- A call is done to the cleaning function that returns the number of deleted databases (must be 0).
CODECODE CODEsh
# Delete an order
Subprog YORDER_ADELETE
Local Instance MYORDER Using C_YORDER
Local Integer OK
# Instantiate the order
MYORDER=NewInstance C_YORDER AllocGroup Null
# Read the order
OK=fmet MYORDER.AREAD("314159")
Call LOG_LINE("Verify the order exists") From AXUNIT
Call CHECK_EQUAL(OK,[V]CST_AOK) From AXUNIT
# As this order is validated, it cannot be deleted
Call LOG_LINE("Verify the order cannot be deleted") From AXUNIT
OK=fmet MYORDER.ADELETE
Call CHECK_EQUAL(OK,[V]CST_AERROR) From AXUNIT
# Clean up the class
FreeGroup MYORDER
MYORDER=NewInstance C_YORDER AllocGroup Null
# Now let's invalidate the order
Local File YORDER
Trbegin [YOH]
Update [YOH] Where YORDNUM="314159" With YSTATUS=1
Commit
# Read the order again
Call LOG_LINE("Read the order again") From AXUNIT
OK=fmet MYORDER.AREAD("314159")
Call CHECK_EQUAL(OK,[V]CST_AOK) From AXUNIT
# Do it again : it should be OK
Call LOG_LINE("Verify the order has been deleted") From AXUNIT
OK=fmet MYORDER.ADELETE
Call CHECK_EQUAL(OK,[V]CST_AOK) From AXUNIT
# Verify that nothing remains
Call LOG_LINE("Verify that the lines in the database have been deleted") From AXUNIT
OK=func CLEANUP("314159")
Call CHECK_EQUAL(OK,0) From AXUNIT
FreeGroup MYORDER
End
The clean-up function
This function deletes the header, lines, and sub-lines associated with a key value and returns the number of lines deleted. It is called in the previous test and in the 'SETUP' sub-program. This 'SETUP' sub-program is automatically called by the unit test framework at the beginning of a test to ensure that no remaining data is likely to hinder the normal test operation.
The code for the Operation routine is as follows:CODECODE CODEsh
# Delete the order and count the number of deleted lines
Funprog CLEANUP(NUMYOH)
Value Char NUMYOH
Local Integer I
Local File YORDER,YORDERLINE,YORDERSUBLIN
Trbegin [YOH],[YOD],[YOL]
Delete [YOH] Where YORDNUM=NUMYOH
I+=adxdlrec
Delete [YOD] Where YORDNUM=NUMYOH
I+=adxdlrec
Delete [YOL] Where YORDNUM=NUMYOH
I+=adxdlrec
Commit
End I
Subprog SETUP
Local Integer I
I=func CLEANUP("314159")
End
Additional sub-programs
Some routines have been added at the end of the test. The following routines are available:
- A function "ADELERRORS" deletes the errors by using an internal routine. This is temporary, a permanent method will be supplied later.
- A "LOG_ERROR" sub-program goes through the error hierarchy to get the errors. A standard method exists for this task, but the generated standard log is not detailed enough.
- A "LINE_LOG" sub-program handles an error line in the log.
CODECODE CODEsh
# Will be replaced later
Funprog ADELERRORS(MYCLASS)
Value Instance MYCLASS Using C_YORDER
End MYCLASS._ADELERRORS("+")
Subprog LOG_ERRORS(MYORDER)
Value Instance MYORDER Using C_YORDER
Local Integer IFERROR,I,J
# Errors on the header
For I=1 To maxtab(MYORDER.AERROR)
If MYORDER.AERROR(I)<>null
Call LINE_LOG("Header",MYORDER.AERROR(I),IFERROR)
Endif
Next I
# Errors on the lines
For I=1 To maxtab(MYORDER.YOD)
If MYORDER.YOD(I)<>null
For J=1 To maxtab(MYORDER.YOD(I).AERROR)
If MYORDER.YOD(I).AERROR(J)<>null
Call LINE_LOG("Line"-num$(MYORDER.YOD(I).AORDER),MYORDER.YOD(I).AERROR(J),IFERROR)
Endif
Next J
For K=1 To maxtab(MYORDER.YOD(I).YOL)
If MYORDER.YOD(I).YOL(K)<>null
For J=1 To maxtab(MYORDER.YOD(I).YOL(K).AERROR)
If MYORDER.YOD(I).YOL(K).AERROR(J)<>null
Call LINE_LOG("Sub-Line ("+num$(MYORDER.YOD(I).AORDER)+","+num$(MYORDER.YOD(I).YOL(K).AORDER)+")",
& MYORDER.YOD(I).YOL(K).AERROR(J),IFERROR)
Endif
Next J
Endif
Next K
Endif
Next I
End
Subprog LINE_LOG(MES1,ERRINS,IFERROR)
Value Char MES1()
Value Instance ERRINS Using C_AERROR
Variable Integer IFERROR
Local Char MESSAGE(250)
If IFERROR=0
Call LOG_LINE("*** Errors dump ***") From AXUNIT
IFERROR=1
Endif
MESSAGE=MES1
If ERRINS.PRO="" : MESSAGE-="(Global)"
Else MESSAGE-="["+ERRINS.PRO+"]"
Endif
MESSAGE-=":"-ERRINS.MES
Call LOG_LINE(MESSAGE) From AXUNIT
End
The generated log file
Part of the 285 lines produced by the test are provided below as an example:
```
CODECODE CODE
2013-03-07T16:18:36.983: Start suite - QLFYDOM_Y1 - YORDER - YORDER test
2013-03-07T16:18:36.987: Start test case - Creation of YORDER with errors check
2013-03-07T16:18:36.999: Result of ADDLIN I=1
2013-03-07T16:18:37.027: Result of ADDLIN L=1
2013-03-07T16:18:37.077: Result of ADDLIN L=2
2013-03-07T16:18:37.090: Result of ADDLIN L=3
2013-03-07T16:18:37.103: Result of ADDLIN L=4
2013-03-07T16:18:37.117: Result of ADDLIN I=2
2013-03-07T16:18:37.127: Result of ADDLIN L=1
2013-03-07T16:18:37.138: Result of ADDLIN L=2
.....
2013-03-07T16:18:37.392: Result of ADDLIN L=4
2013-03-07T16:18:37.465: Result of AINSERT
2013-03-07T16:18:37.466: * Errors dump
2013-03-07T16:18:37.466: Header [YORDNUM] : Mandatory field
2013-03-07T16:18:37.467: Header [YBPC] : Mandatory field
2013-03-07T16:18:37.467: Header [YREP] : Mandatory field
2013-03-07T16:18:37.467: Header [YORDDAT] : Mandatory field
2013-03-07T16:18:37.468: Header [YCUR] : Mandatory field
2013-03-07T16:18:37.468: Line 1 [YORDNUM] : Mandatory field
2013-03-07T16:18:37.468: Sub-Line (1,1) [YORDNUM] : Mandatory field
2013-03-07T16:18:37.469: Sub-Line (1,2) [YORDNUM] : Mandatory field
2013-03-07T16:18:37.469: Sub-Line (1,3) [YORDNUM] : Mandatory field
2013-03-07T16:18:37.470: Sub-Line (1,4) [YORDNUM] : Mandatory field
2013-03-07T16:18:37.470: Line 2 [YORDNUM] : Mandatory field
2013-03-07T16:18:37.470: Sub-Line (2,1) [YORDNUM] : Mandatory field
.....
2013-03-07T16:18:37.477: Sub-Line (5,4) [YORDNUM] : Mandatory field
2013-03-07T16:18:37.501: Propagate checks
2013-03-07T16:18:37.512: Result of AINSERT
2013-03-07T16:18:37.512: Errors dump *
2013-03-07T16:18:37.512: Header [YORDNUM] : Mandatory field
2013-03-07T16:18:37.513: Header [YBPC] : Mandatory field
2013-03-07T16:18:37.513: Header [YREP] : Mandatory field
2013-03-07T16:18:37.513: Header [YORDDAT] : Mandatory field
2013-03-07T16:18:37.513: Header [YCUR] : Mandatory field
2013-03-07T16:18:37.514: Line 1 [YORDNUM] : Mandatory field
2013-03-07T16:18:37.514: Sub-Line (1,1) [YORDNUM] : Mandatory field
2013-03-07T16:18:37.514: Sub-Line (1,2) [YORDNUM] : Mandatory field
.....
2013-03-07T16:18:38.029: Checks the total price computation
1.1 - check isTrue - OK
1.2 - check isTrue - OK
1.3 - check isTrue - OK
1.4 - check isTrue - OK
1.5 - check isTrue - OK
1.6 - check isTrue - OK
1.7 - check isTrue - OK
1.8 - check isTrue - OK
1.9 - check isTrue - OK
......
1.24 - check isTrue - OK
1.25 - check isTrue - OK
1.26 - check equal - OK: 4
1.27 - check equal - OK: '314159'
1.28 - check equal - OK: '314159'
1.29 - check equal - OK: '314159'
1.30 - check equal - OK: '314159'
1.31 - check equal - OK: '314159'
1.32 - check equal - OK: '314159'
1.33 - check equal - OK: '314159'
......
1.51 - check equal - OK: '314159'
1.52 - check equal - OK: 4
1.53 - check equal - OK: 0
1.54 - check equal - OK: 1200
0001 success=54, failure=0, elapsed=1044ms
2013-03-07T16:18:38.030: Start test case - Check YORDER previously created
2013-03-07T16:18:38.251: Checks the AREAD method
2013-03-07T16:18:38.251: Verify the values read
2013-03-07T16:18:38.254: Verify the lines and sub-lines values read
2013-03-07T16:18:38.276: Verify the total price read
2.1 - check equal - OK: 0
2.2 - check equal - OK: 'BPC-000003'
2.3 - check equal - OK: 'REPRE004'
2.4 - check equal - OK: '09/05/2002'
2.5 - check equal - OK: 'EUR'
2.6 - check equal - OK: 1
2.7 - check equal - OK: 'BMSMN00203'
2.8 - check equal - OK: 80
......
2.76 - check equal - OK: 9
2.77 - check equal - OK: 1200
0001 success=77, failure=0, elapsed=246ms
2013-03-07T16:18:38.277: Start test case - Check YORDER update
2013-03-07T16:18:38.467: Checks the AREAD method
2013-03-07T16:18:38.468: Checks an insertion at level 2
2013-03-07T16:18:38.470: Checks an insertion of a sub-line
2013-03-07T16:18:38.484: Checks an insertion of a sub-line 5
2013-03-07T16:18:38.487: Checks a modification of a sub-line
2013-03-07T16:18:38.491: Checks a deletion on a line
2013-03-07T16:18:38.493: Checks the update
2013-03-07T16:18:38.758: Verify the lines and sub-lines values after update
2013-03-07T16:18:38.759: Verify the total price of line 1
2013-03-07T16:18:38.759: Verify the total price of line 2
2013-03-07T16:18:38.760: Verify the total price of line 4
2013-03-07T16:18:38.761: Verify the total price of line 5
2013-03-07T16:18:38.761: Verify the total price read
3.1 - check equal - OK: 0
3.2 - check equal - OK: 0
3.3 - check notEqual - OK: 5
3.4 - check notEqual - OK: 4
3.5 - check equal - OK: 0
.......
3.11 - check equal - OK: 1230
0001 success=11, failure=0, elapsed=485ms
2013-03-07T16:18:38.763: Start test case - Check YORDER validation operation
2013-03-07T16:18:38.764: Verify the order validation result
2013-03-07T16:18:38.809: Verify the order validation result with warning
4.1 - check equal - OK: 0
4.2 - check equal - OK: 3
0001 success=2, failure=0, elapsed=50ms
2013-03-07T16:18:38.812: Start test case - Check YORDER deletion
2013-03-07T16:18:38.952: Verify the order exists
2013-03-07T16:18:38.952: Verify the order cannot be deleted
2013-03-07T16:18:38.964: Read the order again
2013-03-07T16:18:39.099: Verify the order has been deleted
2013-03-07T16:18:39.324: Verify that the lines in the database have been deleted
5.1 - check equal - OK: 0
5.2 - check equal - OK: 4
5.3 - check equal - OK: 0
5.4 - check equal - OK: 0
5.5 - check equal - OK: 0
0001 success=5, failure=0, elapsed=516ms
2013-03-07T16:18:39.329: QLFYDOM_Y1 - YORDER - 5 Succeed, 0 Failed, 2354ms elapsed
Trace has been written to '....../TRA/QLFYDOM_Y1_DOM.tra'
JSON result is available at: http://.../TMP/QLFYDOM_Y1_DOM.json
```