How to use axunit
This document describes the 'AX' unit test tool intended to automate all unit tests running with Sage X3 scripts.
Overview
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.
File name convention
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.
Unit test template
Writing a unit test follows the template below:CODECODE CODEsh
Funprog TESTSUITE()
Call TESTSUITE_START("US-99999-99", "My description of the test suite for User story 99999-99") From AXUNIT
Call ADD_TESTCASE("TEST_MYCASE1", "My description of the test case 1", NB_CHECKS_IN_TEST_CASE_1) From AXUNIT
Call ADD_TESTCASE("TEST_MYCASE2", "My description of the test case 2", NB_CHECKS_IN_TEST_CASE_2) From AXUNIT
End 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 suite
End
Subprog TEARDOWN
# Optional subprog called *after* running the test suite
End
Subprog 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_EQUAL
Call 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_TRUE
Call CHECK_TRUE(GOT) From AXUNIT
# ...
End
Subprog TEST_MYCASE2
# ...
End
Example: We want to write unit tests for a simple "addition" function:Funprog ADD(SUMMAND1, SUMMAND2)
Value Integer SUMMAND1
Value Integer SUMMAND2
End 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 RESULT
RESULT = func ADD(2, 5)
Call CHECK_EQUAL(RESULT, 7) From AXUNIT
Subprograms to verify the expected result
The framework supports the following:
CHECK_EQUAL(GOT, EXPECT)
:
Check ifGOT
equals toEXPECTED
CHECK_NOTEQUAL(GOT, EXPECT)
:
Check ifGOT
not equals toEXPECTED
CHECK_TRUE(GOT)
:
Check ifGOT
istrue
-CHECK_FALSE(GOT)
:
Check ifGOT
isfalse
Checking the contents of an instance
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 : ""
Running a unit test
Different options are available to run a unit test.
Run an individual test in the Eclipse console
In the Eclipse console, type a func
call with the full qualified name of the test suite. For example:
CODECODE CODEsh
=>func qlfar_encode.testsuite
QLFAR_ENCODE - REQ-70693 - 4 Succeed, 0 Failed, 80ms elapsed
Trace 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
A summary of the result is generated with the number of successful and failed test cases and the elapsed time spent by the test session.
Run all tests
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
.
Run some tests
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 CODEsh
func AXUNIT.RUN_ALL2(";QLFAS_ASYRMAIN;", 1)
Run a subset of unit tests
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).
Run in batch mode
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)
.