How to use axunit
This document describes the 'AX' unit test tool intended to automate all unit tests running with Sage X3 scripts.
The AXUNIT
unit test framework is based on the same fundamentals as 'QUnit' or 'JUnit'.
The main purpose is to have a source file which is a test suite of several test cases that verify some predefined assertions.
Every unit test file must match the file name pattern QLF*_*.src
. The complete naming rule is described in the How to Naming Rule document.
CODECODE CODEshFunprog TESTSUITE()Call TESTSUITE_START("US-99999-99", "My description of the test suite for User story 99999-99") From AXUNITCall ADD_TESTCASE("TEST_MYCASE1", "My description of the test case 1", NB_CHECKS_IN_TEST_CASE_1) From AXUNITCall ADD_TESTCASE("TEST_MYCASE2", "My description of the test case 2", NB_CHECKS_IN_TEST_CASE_2) From AXUNITEnd func AXUNIT.RUN_TESTSUITE("US-99999-99", "My description of the test suite for User story 99999-99")Subprog SETUP# Optional subprog called *before* running the test suiteEndSubprog TEARDOWN# Optional subprog called *after* running the test suiteEndSubprog TEST_MYCASE1# ... some code to get the result we want to verify# the result of the code will be put to the first parameter of CHECK_EQUAL,# the expected value will be put to the second parameter of CHECK_EQUALCall CHECK_EQUAL(GOT, EXPECT) From AXUNIT# ... some code to get the result we want to verify# the code returns a logical value which we want to check. It will be put into the # first parameter of CHECK_TRUECall CHECK_TRUE(GOT) From AXUNIT# ... EndSubprog TEST_MYCASE2# ... End
Example: We want to write unit tests for a simple "addition" function:Funprog ADD(SUMMAND1, SUMMAND2)Value Integer SUMMAND1Value Integer SUMMAND2End SUMMAND1 + SUMMAND2
In order to verify that the sum of 2 and 5 is indeed 7, we write:Call CHECK_EQUAL(func ADD(2, 5), 7) From AXUNIT
orLocal Integer RESULTRESULT = func ADD(2, 5)Call CHECK_EQUAL(RESULT, 7) From AXUNIT
The framework supports the following:
CHECK_EQUAL(GOT, EXPECT)
:
Check if GOT
equals to EXPECTED
CHECK_NOTEQUAL(GOT, EXPECT)
:
Check if GOT
not equals to EXPECTED
CHECK_TRUE(GOT)
:
Check if GOT
is true
-
CHECK_FALSE(GOT)
:
Check if GOT
is false
An additional function is available (from patch 6) to allow to dump the content of an instance. The function is the following:
Call LOG_CLASS(MYINSTANCE,INSTANCE_NAME,ERRORS) From AXUNIT
Where:
MY_INSTANCE
is the instance pointer we want to dumpINSTANCE_NAME
is the name of the instance pointer (it will appear in the log)ERRORS
is a flag that will trigger the display of all the errors associated to the classes or to their properties. When this happens, the error is displayed on a line following the element where the error is triggered, with two asterisks before it, and the corresponding level of gravity (INFO
, WARNING
, ERROR
, FATAL
).When arrays of children instances are present, all the indexes are written in the log, preceded by a line that is written in this format:
NNN: [xxx,MMM]
Where NNN
is the current index, xxx
is the status of the line as given by ASTALIN
(NEW
, DEL
, NEWDEL
, UPD
, NOTMOD
), and MMM
the value of AORDER
.
Instance MYORDER of C_YORDER| ** AWARNING This order is really big| String(80) COMMENT : ""| Datetime CREDATTIM : "2014-07-03T15:22:18Z"| String(5) CREUSR : "MARTIN"| String(3) CURRENCY : "EUR"| String(15) CUSTOMER : "ZAO007"| ** AERROR ZAO007 : Record does not exist| String(5) FCY : "AO011"| Collection LINES of C_YLINE (1..3)| 001: [NEW,001] | | Decimal DISCOUNT : 0| | Integer DLVQTY : 0| | String(3) FLAG : ""| | String(20) ITEM : "BMS005"| | ShortInt NUMLIN : 1| | String(16) ORDNUM : "994159249"| | Decimal PRICE : 3.14| | Integer QTY : 1| | ShortInt SORTLIN : 1| | Decimal UNITPRICE : 3.14| 002: [DEL,002] | | Decimal DISCOUNT : 25| | Integer DLVQTY : 0| | String(3) FLAG : ""| | String(20) ITEM : "BMS007"| | ShortInt NUMLIN : 2| | String(16) ORDNUM : "994159249"| | Decimal PRICE : 1500| | Integer QTY : 20| | ShortInt SORTLIN : 2| | Decimal UNITPRICE : 100| 003: [UPD,003] | | Decimal DISCOUNT : 95| | ** AERROR Discount too high| | Integer DLVQTY : 0| | String(3) FLAG : ""| | String(20) ITEM : "BMS007"| | ShortInt NUMLIN : 3| | String(16) ORDNUM : "994159249"| | Decimal PRICE : -100| | Integer QTY : 20| | ShortInt SORTLIN : 3| | Decimal UNITPRICE : -100| | ** AERROR Price must be positive| String(20) OPERATION : ""| TinyInt ORDCLO : 1| Date ORDDAT : "2014-07-14"| String(16) ORDNUM : "994159249"| TinyInt ORDSTA : 1| Decimal TOTAL : 1403.14| Datetime UPDDATTIM : "0000-00-00T00:00:00Z"| String(5) UPDUSR : ""
Different options are available to run a unit test.
In the Eclipse console, type a func
call with the full qualified name of the test suite. For example:
CODECODE CODEsh=>func qlfar_encode.testsuiteQLFAR_ENCODE - REQ-70693 - 4 Succeed, 0 Failed, 80ms elapsedTrace has been written to '/produits/v160/SOLSUPV6/dossiers/SUPERV/TRA/QLFAR_ENCODE_ERBOU.tra'JSON result is available at: http://sodaix02/Adonix_SOLSUPV6/SUPERV/TMP/QLFAR_ENCODE_ERBOU.json
Running all tests could last a while. For this reason, it is recommended to not run them in the Eclipse console. To run all tests, call func AXUNIT.RUN_ALL
.
It is possible to run all tests or exclude some of them by calling the func AXUNIT.RUN_ALL2(EXCLUDES, NODEBUG)
function.
This function requires two arguments:
EXCLUDES
A string of program names separated by ;
NODEBUG
A value indicating if the debug mode must be disabled.CODECODE CODEshfunc AXUNIT.RUN_ALL2(";QLFAS_ASYRMAIN;", 1)
By using an appropriate name convention, it is simple to run a subset of unit tests by calling the func AXUNIT.RUN_SET("AS")
function. This function will call all QLFAS_*.src
unit tests (all supervisor tests).
This is the recommended way to run all tests. Create a batch task that calls func AXUNIT.RUN_ALL
or func AXUNIT.RUN_ALL2("", 1)
.