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.
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.
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:
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 suiteCall TESTSUITE_START("MYCLASS", "MYCLASS test") From AXUNIT# Call the different test casesCall ADD_TESTCASE("MYCLASS_CREATION","Creation of MYCLASS with errors check",0) From AXUNITCall ADD_TESTCASE("MYCLASS_READ","Read MYCLASS",0) From AXUNITCall ADD_TESTCASE("MYCLASS_UPDATE","Update MYCLASS",0) From AXUNITCall ADD_TESTCASE("MYCLASS_DELETE","Deletion MYCLASS",0) From AXUNIT# Run the test and return the resultLocal Clbfile RESULT_SUITERESULT_SUITE=func AXUNIT.RUN_TESTSUITE("MYCLASS","MYCLASS test")End RESULT_SUITE
CODECODE CODEsh# Creation subprogramSubprog MYCLASS_CREATION()Local Integer ASTATUSLocal Instance MYINST01 Using C_MYCLASS# Instantiate the classMYINST01 = 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 creationsMYINST01.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 insertionCall CHECK_EQUAL(MYINST01.PROP1,"EXPECTED_VALUE") From AXUNIT# Repeat other creation cases if necessary...# End of testFreeGroup MYINSTA01End
A complete example of a test program for the classes created in the CRUD example is provided below.
The code for the main routine is shown below. This routine starts the job and calls the different test cases, which are:
CODECODE CODEsh#**#* The main entry point of the unit test suite#*#*!Call TESTSUITEEndFunprog TESTSUITE()# Start the test suiteCall TESTSUITE_START("YORDER", "YORDER test") From AXUNIT# Call the different test casesCall ADD_TESTCASE("YORDER_AINSERT","Creation of YORDER with errors check",54) From AXUNITCall ADD_TESTCASE("YORDER_AREAD","Check YORDER previously created",77) From AXUNITCall ADD_TESTCASE("YORDER_AUPDATE","Check YORDER update",11) From AXUNITCall ADD_TESTCASE("YORDER_YVALIDATE","Check YORDER validation operation",2) From AXUNITCall ADD_TESTCASE("YORDER_ADELETE","Check YORDER deletion",5) From AXUNIT# Run the test and return the resultLocal Clbfile RESULT_SUITERESULT_SUITE=func AXUNIT.RUN_TESTSUITE("YORDER","YORDER test")End RESULT_SUITE
This routine creates an order of several steps:
CODECODE CODEsh# Create an orderSubprog YORDER_AINSERTLocal Instance MYORDER Using C_YORDERLocal Integer I,J,K,L,OKLocal Decimal TOTAL_PRICEMYORDER=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 checkTOTAL_PRICE=0# 5 lines insertedFor I=1 To 5J=fmet MYORDER.ADDLINE("YOD",[V]CST_ALASTPOS)Call LOG_LINE("Result of ADDLIN I="+num$(I)) From AXUNITCall CHECK_TRUE(J>=0) From AXUNIT# We use existing items coded "BMSMN0020x" where x varies from 3 to 8MYORDER.YOD(J).YITM="BMSMN0020"+num$(2+I)# 4 sub-lines inserted for every lineFor L=1 To 4K=fmet MYORDER.YOD(J).ADDLINE("YOL",[V]CST_ALASTPOS)Call LOG_LINE("Result of ADDLIN L="+num$(L)) From AXUNITCall 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*LMYORDER.YOD(J).YOL(K).YUNITPRICE=5+LTOTAL_PRICE+=(I*L)*(5+L)Next LNext I# A lot of mandatory properties have no value : LOG_ERRORS will dump themOK=fmet MYORDER.AINSERTCall LOG_LINE("Result of AINSERT") From AXUNITCall CHECK_EQUAL(OK,[V]CST_AERROR) From AXUNITCall LOG_ERRORS(MYORDER)# Assigning the order number here will propagateMYORDER.YORDNUM="314159"# Check the propagationCall LOG_LINE("Propagate checks") From AXUNITFor I=1 To 5For J=1 To 4Call CHECK_EQUAL(MYORDER.YOD(I).YOL(J).YORDNUM,MYORDER.YORDNUM) From AXUNITNext JCall CHECK_EQUAL(MYORDER.YOD(I).YORDNUM,MYORDER.YORDNUM) From AXUNITNext I# Still a lot of mandatory properties have no valueOK=fmet MYORDER.AINSERTCall LOG_LINE("Result of AINSERT") From AXUNITCall CHECK_EQUAL(OK,[V]CST_AERROR) From AXUNITCall LOG_ERRORS(MYORDER)# Now let's assign the missing mandatory values# Customer code, sales rep code and currency code are supposed to existMYORDER.YBPC="BPC-000003"MYORDER.YREP="REPRE004"MYORDER.YORDDAT=[09/05/2002]MYORDER.YCUR='EUR'MYORDER.YSTATUS=1OK=fmet MYORDER.AINSERT# Check if the creation is OKCall LOG_LINE("Checks the insertion when everything is OK") From AXUNITCall CHECK_EQUAL(OK,[V]CST_AOK) From AXUNITCall LOG_LINE("Checks the total price computation") From AXUNITCall CHECK_EQUAL(MYORDER.YTOTAL,TOTAL_PRICE) From AXUNITFreeGroup MYORDEREnd
This routine reads the previous order and performs the following verifications:
CODECODE CODEshSubprog YORDER_AREADLocal Instance MYORDER Using C_YORDERLocal Integer I,J,K,L,M,N,OKLocal Decimal TOTAL_PRICEMYORDER=NewInstance C_YORDER AllocGroup NullOK=fmet MYORDER.AREAD("314159")Call LOG_LINE("Checks the AREAD method") From AXUNITCall CHECK_EQUAL(OK,[V]CST_AOK) From AXUNITCall LOG_LINE("Verify the values read") From AXUNITCall CHECK_EQUAL(MYORDER.YBPC,"BPC-000003") From AXUNITCall CHECK_EQUAL(MYORDER.YREP,"REPRE004") From AXUNITCall CHECK_EQUAL(num$(MYORDER.YORDDAT),"09/05/2002") From AXUNITCall CHECK_EQUAL(MYORDER.YCUR,'EUR') From AXUNITCall CHECK_EQUAL(MYORDER.YSTATUS,1) From AXUNITCall LOG_LINE("Verify the lines and sub-lines values read") From AXUNITK=0For I=1 To maxtab(MYORDER.YOD)If MYORDER.YOD(I)<>nullJ+=1K=MYORDER.YOD(I).AORDERCall CHECK_EQUAL(MYORDER.YOD(I).YITM,"BMSMN0020"+num$(2+K)) From AXUNITCall CHECK_EQUAL(MYORDER.YOD(I).YPRICE,sigma(1,4,K*indcum*(5+indcum))) From AXUNITFor L=1 To maxtab(MYORDER.YOD(I).YOL)M=0If MYORDER.YOD(I).YOL(L)<>nullM+=1N=MYORDER.YOD(I).YOL(L).AORDERCall CHECK_EQUAL(MYORDER.YOD(I).YOL(L).YUNIT,vireblc(mid$("UN TENCARPAC",3*N-2,3),2)) From AXUNITCall CHECK_EQUAL(MYORDER.YOD(I).YOL(L).YQTY,K*N) From AXUNITCall CHECK_EQUAL(MYORDER.YOD(I).YOL(L).YUNITPRICE,5+N) From AXUNITTOTAL_PRICE+=(5+N)*K*NEndifNext LEndifNext ICall LOG_LINE("Verify the total price read") From AXUNITCall CHECK_EQUAL(MYORDER.YTOTAL,TOTAL_PRICE) From AXUNITFreeGroup MYORDEREnd
This routine reads the previous order and performs the following updates:
CODECODE CODEsh# The update testSubprog YORDER_AUPDATELocal Instance MYORDER Using C_YORDERLocal Integer I,J,K,L,M,N,OKLocal Decimal TOTAL_PRICE, LINE_PRICEMYORDER=NewInstance C_YORDER AllocGroup NullOK=fmet MYORDER.AREAD("314159")Call LOG_LINE("Checks the AREAD method") From AXUNITCall 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 itCall LOG_LINE("Checks an insertion at level 2") From AXUNITI=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-linesCall LOG_LINE("Checks an insertion of a sub-line") From AXUNITI=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 AXUNITCall CHECK_NOTEQUAL(J,[V]CST_ANOTDEFINED) From AXUNITMYORDER.YOD(I).YOL(J).YUNIT="TEN"MYORDER.YOD(I).YOL(J).YQTY=3MYORDER.YOD(I).YOL(J).YUNITPRICE=16# Get the 5th line, then modify the 4th sub-lineCall LOG_LINE("Checks a modification of a sub-line") From AXUNITI=fmet MYORDER.AGETINDBYLINE("YOD",5)J=fmet MYORDER.YOD(I).AGETINDBYLINE("YOL",4)Call CHECK_NOTEQUAL(J,[V]CST_ANOTDEFINED) From AXUNITMYORDER.YOD(I).YOL(J).YUNIT="TEN"MYORDER.YOD(I).YOL(J).YQTY=10MYORDER.YOD(I).YOL(J).YUNITPRICE=43# Delete the 3rd lineCall LOG_LINE("Checks a deletion on a line") From AXUNITOK=fmet MYORDER.ADELLINE("YOD",3)Call CHECK_EQUAL(OK,[V]CST_AOK) From AXUNIT# Update the orderCall LOG_LINE("Checks the update") From AXUNITOK=fmet MYORDER.AUPDATECall CHECK_EQUAL(OK,[V]CST_AOK) From AXUNITCall 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=0For I=1 To maxtab(MYORDER.YOD)If MYORDER.YOD(I)<>nullIf find(MYORDER.YOD(I).ASTALIN,[V]CST_ADEL, [V]CST_ANEWDEL)=0LINE_PRICE=0For J=1 To maxtab(MYORDER.YOD(I).YOL)If MYORDER.YOD(I).YOL(J)<>nullIf find(MYORDER.YOD(I).YOL(J).ASTALIN,[V]CST_ADEL, [V]CST_ANEWDEL)=0LINE_PRICE+=MYORDER.YOD(I).YOL(J).YQTY*MYORDER.YOD(I).YOL(J).YUNITPRICEEndifEndifNext JTOTAL_PRICE+=LINE_PRICECall LOG_LINE("Verify the total price of line"-num$(I)) From AXUNITCall CHECK_EQUAL(MYORDER.YOD(I).YPRICE,LINE_PRICE) From AXUNITEndifEndifNext ICall LOG_LINE("Verify the total price read") From AXUNITCall CHECK_EQUAL(MYORDER.YTOTAL,TOTAL_PRICE) From AXUNITFreeGroup MYORDEREnd
This routine performs an operation (YVALIDATE) that can return a warning if it has already been performed.
CODECODE CODEsh# Validate an orderSubprog YORDER_YVALIDATELocal Instance MYORDER Using C_YORDERLocal Integer OK# Instantiate the orderMYORDER=NewInstance C_YORDER AllocGroup Null# First time, it will workCall LOG_LINE("Verify the order validation result") From AXUNITOK=fmet MYORDER.YVALIDATE("314159")Call CHECK_EQUAL(OK,[V]CST_AOK) From AXUNIT# Do it again : a warning is expectedCall LOG_LINE("Verify the order validation result with warning") From AXUNITOK=fmet MYORDER.YVALIDATE("314159")Call CHECK_EQUAL(OK,[V]CST_AWARNING) From AXUNITFreeGroup MYORDEREnd
This routine performs a deletion:
CODECODE CODEsh# Delete an orderSubprog YORDER_ADELETELocal Instance MYORDER Using C_YORDERLocal Integer OK# Instantiate the orderMYORDER=NewInstance C_YORDER AllocGroup Null# Read the orderOK=fmet MYORDER.AREAD("314159")Call LOG_LINE("Verify the order exists") From AXUNITCall CHECK_EQUAL(OK,[V]CST_AOK) From AXUNIT# As this order is validated, it cannot be deletedCall LOG_LINE("Verify the order cannot be deleted") From AXUNITOK=fmet MYORDER.ADELETECall CHECK_EQUAL(OK,[V]CST_AERROR) From AXUNIT# Clean up the classFreeGroup MYORDERMYORDER=NewInstance C_YORDER AllocGroup Null# Now let's invalidate the orderLocal File YORDERTrbegin [YOH]Update [YOH] Where YORDNUM="314159" With YSTATUS=1Commit# Read the order againCall LOG_LINE("Read the order again") From AXUNITOK=fmet MYORDER.AREAD("314159")Call CHECK_EQUAL(OK,[V]CST_AOK) From AXUNIT# Do it again : it should be OKCall LOG_LINE("Verify the order has been deleted") From AXUNITOK=fmet MYORDER.ADELETECall CHECK_EQUAL(OK,[V]CST_AOK) From AXUNIT# Verify that nothing remainsCall LOG_LINE("Verify that the lines in the database have been deleted") From AXUNITOK=func CLEANUP("314159")Call CHECK_EQUAL(OK,0) From AXUNITFreeGroup MYORDEREnd
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 linesFunprog CLEANUP(NUMYOH)Value Char NUMYOHLocal Integer ILocal File YORDER,YORDERLINE,YORDERSUBLINTrbegin [YOH],[YOD],[YOL]Delete [YOH] Where YORDNUM=NUMYOHI+=adxdlrecDelete [YOD] Where YORDNUM=NUMYOHI+=adxdlrecDelete [YOL] Where YORDNUM=NUMYOHI+=adxdlrecCommitEnd ISubprog SETUPLocal Integer II=func CLEANUP("314159")End
Some routines have been added at the end of the test. The following routines are available:
CODECODE CODEsh# Will be replaced laterFunprog ADELERRORS(MYCLASS)Value Instance MYCLASS Using C_YORDEREnd MYCLASS._ADELERRORS("+")Subprog LOG_ERRORS(MYORDER)Value Instance MYORDER Using C_YORDERLocal Integer IFERROR,I,J# Errors on the headerFor I=1 To maxtab(MYORDER.AERROR)If MYORDER.AERROR(I)<>nullCall LINE_LOG("Header",MYORDER.AERROR(I),IFERROR)EndifNext I# Errors on the linesFor I=1 To maxtab(MYORDER.YOD)If MYORDER.YOD(I)<>nullFor J=1 To maxtab(MYORDER.YOD(I).AERROR)If MYORDER.YOD(I).AERROR(J)<>nullCall LINE_LOG("Line"-num$(MYORDER.YOD(I).AORDER),MYORDER.YOD(I).AERROR(J),IFERROR)EndifNext JFor K=1 To maxtab(MYORDER.YOD(I).YOL)If MYORDER.YOD(I).YOL(K)<>nullFor J=1 To maxtab(MYORDER.YOD(I).YOL(K).AERROR)If MYORDER.YOD(I).YOL(K).AERROR(J)<>nullCall LINE_LOG("Sub-Line ("+num$(MYORDER.YOD(I).AORDER)+","+num$(MYORDER.YOD(I).YOL(K).AORDER)+")",& MYORDER.YOD(I).YOL(K).AERROR(J),IFERROR)EndifNext JEndifNext KEndifNext IEndSubprog LINE_LOG(MES1,ERRINS,IFERROR)Value Char MES1()Value Instance ERRINS Using C_AERRORVariable Integer IFERRORLocal Char MESSAGE(250)If IFERROR=0Call LOG_LINE("*** Errors dump ***") From AXUNITIFERROR=1EndifMESSAGE=MES1If ERRINS.PRO="" : MESSAGE-="(Global)"Else MESSAGE-="["+ERRINS.PRO+"]"EndifMESSAGE-=":"-ERRINS.MESCall LOG_LINE(MESSAGE) From AXUNITEnd
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
```