0% found this document useful (0 votes)
16 views

TAFJ UnitTestFramework

d
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views

TAFJ UnitTestFramework

d
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 26

TAFJ U nit Test F r a m e wo rk

Doc u m e n t Hist o r y

Revi si o
Dat e Ame n d e d Na m e De s c r i p t i o n
n
1 Sep 11 2015 T. Aube r t Initial version
2 Nov 5 2015 T. Aube r t New function ali ti e s adde d

3 Dec 15 2015 T. Aube r t Remove d the recor di n g facilities

4 15 th Marc h 2016 M. Kuma r R16 AMR review

5 April 21 st 2016 T. Aube r t Add ignore Mi s si n g S t u b s () desc ri ptio n

6 May 2 nd 2016 T. Aube r t Add rese t () desc ri pti on

7 May 6 th 2016 T.Aube r t Stub Conditions and new modifiers

Add saveCo n t e x t () and resto r e C o n t e x t () and


8 May 9 th 2016 T.Aube r t
rem ov e S t u b ( ...)

9 May 17 th 2016 T.Aube r t Code Cover a g e and new Result view

10 June 6 th 2016 T.Aube r t setDa t e() setTi m e() rese t D a t eTi m e ()

11 June 6 th 2016 T.Aube r t lockRec o r d() unlockR ec o r d ()

12 June 29 th 2016 T.Aube r t Assert N o t E q u a l s()

13 July 1 st 2016 T.Aube r t UTF.se t S t o p pi n g()

14 July 6 th 2016 T.Aube r t Default Date / Time setting s

15 Dec 12 th 2016 T. Aube r t setFileP oi n t e r ()

16 Aug 10 th 2017 T.Aube r t mockSYSTEM()

17 21 st Marc h 2019 M. Kuma r R19 AMR review

18 24 th Marc h 2020 Imm a n u e l KJ R20 AMR review

M.
19 12 th April 2021 R21 AMR review
Siranje evi

20 25 th Marc h 2022 Ekat a Malik R22 AMR review

21 6 th April 2023 M.Kum a r R23 AMR Review

2
TAFJ U nit Test F r a m e wo rk

Copyri g h t

Copyrig h t © Teme n o s Hea d q u a r t e r s SA 2009- 2023.


All right s rese rv e d.
This docu m e n t cont ain s prop rie t a r y inform a tio n that is prote c t e d by copyrig h t. No part of this docu m e n t may
be repro d u c e d , tra ns m i t t e d , or mad e availa ble direc tly or indirec tly to a third party without the expr e s s
writt e n agre e m e n t of TEMENOS UK Limite d. Receipt of this mate ri al direc tly TEMENO S UK Limite d
constit u t e s its expr e s s per mis sion to copy. Per mis sion to use or copy this docu m e n t expr e s sly exclud e s
modifying it for any purpo s e , or using it to cre a t e a derivative the r ef ro m .

Errat a and Com m e n t s


If you have any com m e n t s reg a r di n g this man u al or wish to repor t any error s in the docu m e n t a t i o n ,
plea s e docu m e n t the m and send the m to the add r e s s below:
Technology Depa r t m e n t
Teme no s Hea d q u a r t e r s SA
2 Rue de l’Ecole- de- Chimie,
CH - 1205 Geneva,
Switze rl a n d

Tel SB: +4 1 (0) 22 708 1150


Fax: +4 1 (0) 22 708 1160

Pleas e includ e your na m e , comp a n y, addr e s s, and telep h o n e and fax num b e r s , and email add r e s s if
applica bl e. TAFJdev@t e m e n o s . c o m

3 Teme no s Application Fra m e w o r k Java – (TAFJ)


TAFJ U nit Test F r a m e wo rk
Ta b l e o f C o n t e n t s

Intro d u c t i o n

The Unit Test Fra m e w o r k (UTF) helps develop e r s and test e r s to validat e that the code is doing what it is
inten d e d to do. The version 1.0 was storing bina ry inform a ti o n s, and was requiri n g a specific editor to
modify a test s. Despit e that the “binary” way of storing in form a ti on s was a good appr o a c h for huge sets
of infor m a t i o n s, the downsi d e s wer e too big, and a full re- engin e e r i n g has been done to get to the
Version 2.
The Version 2 still have the recor di n g facility, and this is much easi er to maint ai n the test as this ends up
being “just” jBC code. Howeve r , unlike EasyQA, the r e is only one file per test and the full Eclipse

4
TAFJ U nit Test F r a m e wo rk
launc hi n g facilities are still availa bl e. This docu m e n t aims to desc ri b e in det ails how this all work. You
will notice that the r e is no “deploym e n t ” section as everyt hi n g is emb e d d e d in the existin g runti m e /
com pile r / eclips e plugi ns.

TUT Overvi e w
A .tut file is a jBC file. Howev e r , the exten sio n .tut is nec e s s a r y to help the differ e n t tools to discove r the
tests.
A tut is not a SUBROUTINE, neith e r a PROGRAM nor a FUNCTIO N. This is a
“TESTCASE”.
So every tuts are star tin g with TESTCASE < n a m e of test > as show n here :

We could wond e r why this could not be a simple SUBROUTINE or PROGRAM, and late r in the docu m e n t ,
everyt hi n g will make sens e. For now, we simply nee d to know that a UnitTe st is decla r e d in the code with
TESTCASE.
Then, this is just jBC, anyt hi n g jBC can do can be done in a tut. Howeve r, this would not be really useful
to stop at that point, and this is her e that the TESTCASE decla r a t i o n sta rt s to make sens e. In fact, by
using TESTCASE, this will auto m a t i c a lly add a low- level refer e n c e in the code. This refer e n c e is “UTF”.
IN the next cha pt e r , we will desc ri b e all the met ho d s the UTF refer e n c e (object) is offerin g. We will call
it a “com po n e n t ” to make the readi n g more jBC orient e d , but in fact this is a real Object.

The UTF “Co m p o n e n t ”

So we know now that a Teme no s Unit Test is a file with the “tut” exten sio n that this is writt e n in jBC and
that the decla r a t i o n is “TESTCASE” bec a u s e we need the “UTF Compo n e n t ” which will help us doing a
test. So let's look in det ails at this Compo n e n t .

First, this is a low- level compo n e n t , sitting into the runti m e , so don't try to find som et hi n g like
UTF.com p o n e n t on your disk, it doesn' t exists. Then, this com po n e n t is auto m a t i c ally “her e”. No need to
do a $USING or what s o ev e r , it sits behind your code. You can consid e r it as a lang u a g e exten sio n. Let's
explor e all thes e exte n si on s. The full list :

Global methods :
UTF.runTest()
UTF.setTarget(<subroutine>)
UTF.setDescription(<a_description>)
UTF.addParam(<variable_or_value>)
UTF.setRecord(<table>, <id>, <record>)
UTF.ignoreMissingStubs()

5 Teme no s Application Fra m e w o r k Java – (TAFJ)


TAFJ U nit Test F r a m e wo rk
UTF.mockSYSTEM(<index>, <value>)
UTF.runTest()

Stubs methods :
UTF.addStub(<subroutine>)
UTF.setRepeatable(<a_stub_ref>)
UTF.addStubParam(<a_stub_ref>, <in_value>, <out_value>)
UTF.addStubCommonChange(<a_stub_ref>, <common>, <out_value>)
UTF.addStubCacheChange(<a_stub_ref>, <bucket_name>, <key>, <out_value>)
UTF.addStubWriteDone(<a_stub_ref>, <table>, <id>, <out_record>)
UTF.addStubPropertyChange(<a_stub_ref>, <component>, <property>, <value>)
UTF.setStubReturnValue(<a_stub_ref>, <value>)

Assertions methods :
UTF.assertEquals(<value1>, <value2>)
UTF.assertContains(<value1>, <value2>)
UTF.assertTrue(<value>)
UTF.assertFalse(<value>)
UTF.assertGreaterThan(<value1>, <value2>)
UTF.assertLessThan(<value1>, <value2>)
UTF.assertStartsWith(<value1>, <value2>)
UTF.assertEndsWith(<value1>, <value2>)
UTF.assertMatches(<value1>, <mask>)
UTF.getRecord(<table>, <id>)

Modifiers methods :
UTF.any()
UTF.matches(<mask>)
UTF.same()

Glob a l UTF Met h o d s


UTF.se tT a r g e t ( < s u b r o u t i n e > )
Usually the very first met ho d (but not mand a t o r y), this is defining wha t subro u ti n e we want to test. This
subr o u t i n e will be called with the UTF.r u nT e s t () met ho d desc ri b e d later.
You can pass a varia bl e as well as a const a n t value.
XYZ = "TEST.SIMPLE"
UTF.setTarget(XYZ)
or
UTF.setTarget("TEST.SIMPLE")
Note that this will be always the sam e for all par a m e t e r , so we won't repe a t it.
6
TAFJ U nit Test F r a m e wo rk
UTF.se t D e s c ri p tio n( < a _ d e s c r i p ti o n > )
This is setti ng a desc ri p tio n for the test (for repo r ti n g purpo s e s)

UTF.ad d P a r a m ( < v a r i a b l e_or_valu e > )


This one nee d s to be called as many time s as you have par a m e t e r s in your tar g e t . Her e, you should (but
not man d a t o r y) put a variabl e, beca u s e this is what you will refer e n c e in the asse r ti o n s. (see later)
Here are two exam pl e s :
P1 = "7"
UTF.addParam(P1)
DIM P2(10)
P2(2) = "6"
UTF.addParam(P2)

UTF.se t P a r a m (i dx, <va ri a bl e_or_valu e > )


This is possibl e to modify (in oposition to add) a par a m e t e r . In that case, you will use the setP a r a m ( )
inst e a d of the addP a r a m .
Eg :
P1 = "10"
UTF.setParam(1, P1)

UTF.se t R e c o r d ( < t a b l e > , <id > , < r e c o r d > )


Since runni n g the test is not touc hi n g at the dat a b a s e , if your test is dep e n d e n t of a pre- existing recor d,
you must add this reco r d with this met ho d. This is a little bit as if you whe r e writing a recor d in a
dat a b a s e , but this is kept in me mo r y.
UTF.setRecord("F.MY.TEST", "MY.KEY.1", 'Field1' : @FM : "Field2")
This function ret u r n a recor d point e r which can be used in lock / unlock Recor d (see lockReco r d(),
unlockR e c o r d()). So you can write :
myRecord = UTF.setRecord("F.MY.TEST", "MY.KEY.1", 'value')

UTF.se t File P oi n t e r ( < file P oi n t e r > , <file N a m e > )


There are som e case s whe r e the filepoint e r (eg used in a READ) is a COMMON varia bl e and the r e is no
OPEN (OPF) done durin g the proc e s s. So in that case, we can direc tly set the filepoint e r to the
corr e s p o n di n g variabl e like this :
UTF.setFilePointer(F$AA.ARRANGEMENT, "F.AA.ARRANGEMENT")

UTF.moc k SYSTE M( < i n d e x > , <val u e > )


Mock any SYSTEM() variabl e s. Eg, to make believe the targ e t routin e that a tra ns a c t i o n is star t e d , you
can write som et hi n g like this
UTF.mockSYSTEM(47, @TRUE)
Later, if the target routine does something like this

IF SYSTEM(47) THEN …

This will be true

Note : Mocked system variables are cleared on a reset().

7 Teme no s Application Fra m e w o r k Java – (TAFJ)


TAFJ U nit Test F r a m e wo rk
UTF.igno r e M i s si n g S t u b s ()
This met ho d infor m s the UTF that is a stub is missing, it will be simply ignor e d and no error will be
raise d. This is to use with caution as this beco m e s difficult to debu g the targ e t . Useful for huge routin e s
for which we only want to test a small portion.

UTF.ru nT e s t()
This met ho d simply launc h the test (call the routi n e define d by the setTa r g e t (...). This met ho d must be
called afte r the stub s definition (see next section)
If the routin e define d by the setTa r g e t is a FUNCTION, then UTF.ru nT e s t () will ret u r n the value of the
function.
Eg :
ret.value = UTF.runTest()

UTF.re s e t ()
Clea r compl e t elly the cont ext (COMMO N, prope r t i e s, recor d s, static cach e, mocke d SYSTEM and
par a m e t e r s ) .

UTF.s av eC o n t e x t()
Save (in- mem o r y) a snap s h o t of the curr e n t COMMO N, prope r ti e s, recor d s, static cach e and par a m e t e r s .

UTF.re s t o r e C o n t e x t()
Restor e the previously saved cont ext (see saveCo n t e x t()). This is also settin g all the stub s invoca tion
count e r back to 0.

UTF.se t D a t e ( d d , mm, yyyy)


Allow the test to set the date. This affect s function s like DATE(), TIMEDATE(), TIMESTAMP(),
SYSTEM(12). The time is not modified. Note that the timezon e is irrel eva n t . Not e : look also at the
“Default Date / Time” chapt e r.

UTF.se tTi m e( h h , mm, ss)


Allow the test to set the time. This affect s functions like TIME(), TIMEDATE(), TIMESTAMP(),
SYSTEM(12). The date is not modified. Note that the timezo n e is irreleva n t . Not e : look also at the
“Default Date / Time” chapt e r.
Typically, this type of test will give the sam e result wher ev e r you run it on the plane t :
SUBROUTINE TEST.DATE.TIME(date, time, timedate, timestamp, sys12)
date = DATE()
time = TIME()
timedate = TIMEDATE()
timestamp = TIMESTAMP()
sys12 = SYSTEM(12)
END

TESTCASE TestDATE.TIME
UTF.setTarget("TEST.DATE.TIME")
date = ''
UTF.addParam(date)
time = ''
UTF.addParam(time)

8
TAFJ U nit Test F r a m e wo rk
timedate = ''
UTF.addParam(timedate)
timestamp = ''
UTF.addParam(timestamp)
sys12 = ''
UTF.addParam(sys12)

UTF.setDate(26, 04, 1968)


UTF.setTime(03, 14, 15)

UTF.runTest()

UTF.assertEquals(date, 117)
UTF.assertEquals(time, 11655)
UTF.assertEquals(timedate, "03:14:15 26 APR 1968")
UTF.assertEquals(timestamp, -53127945)
UTF.assertEquals(sys12, 11655000)
END

UTF.re s e t D a t e Ti m e ()
Reset (canc el any setD a t e() or setTim e()) the dat e / time to the curr e n t / defa ul t one.

UTF.lockRe c o r d ( < r e c o r d > )


In som e specific circu m s t a n c e s , you may want to test a situa tion whe r e a recor d is locke d. You can do that by
puttin g the lock flag on a recor d using the lockRe co r d () function. The par a m e t e r pass e d is the ret u r n value of
the setR ec o r d() met ho d.
Exam pl e :
myRecord = UTF.setRecord("FBNK.CURRENCY", "USD", "This is a CCY Record")
UTF.lockRecord(myRecord)

This will affect READU, CALL F.READU(), MATREADU, CALL F.MATREADU() and READVU
Here is a full code showi ng a routin e and its test :
SUBROUTINE GET.LOCK(REC)
OPEN "FBNK.CURRENCY" TO F.FILE ELSE NULL
DIM AR(100)
MATREADU AR FROM F.FILE, "USD" LOCKED
REC = "MATREADU RECORD LOCKED / "
END
READU R FROM F.FILE, "USD" LOCKED
REC := "READU RECORD LOCKED / "
END
READVU R FROM F.FILE, "USD", 2 LOCKED
REC := "READVU RECORD LOCKED / "

9 Teme no s Application Fra m e w o r k Java – (TAFJ)


TAFJ U nit Test F r a m e wo rk
END
ER = ""
CALL F.MATREADU ("FBNK.CURRENCY","USD",MAT AR,100,F.FILEID,ER,RETRY)
REC = REC : ER : " / "
ER = ""
CALL F.READU ("FBNK.CURRENCY","USD",REC2,F.FILEID,ER,RETRY)
REC = REC : ER
END

TESTCASE TestGET.LOCK
UTF.setTarget("GET.LOCK")
REC = ''
UTF.addParam(REC)
myRecord = UTF.setRecord("FBNK.CURRENCY", "USD", "Currency Record")
UTF.lockRecord(myRecord)
UTF.runTest()
UTF.assertEquals(REC, "MATREADU RECORD LOCKED / READU RECORD LOCKED / READVU RECORD LOCKED /
RECORD LOCKED / RECORD LOCKED")
END

UTF.unlockR e c o r d ( < r e c o r d > )


Unlock a recor d. See UTF.lockR e c o r d()

Default Date / Time


In addition to the setDa t e () / setTim e() met ho d which are done for individu al testc a s e , you can chan g e
your environ m e n t dat e and time by settin g the prope r ti e s (in your <p r oj e c t > . p r o p e r t i e s file) like this :
tem n. t afj.utf.d ef a ul t. d a t e = “dd/m m /yyyy”
tem n. t afj.utf.d ef a ul t.ti m e = “hh: m m : s s”
Note that the form a t is impor t a n t and must matc h exactly the patt e r n desc ri b e d. As an exa m pl e ,
“26/04/ 6 8” is invali d !

Stubs met ho d s

refer e n c e = UTF.ad d S t u b ( < s u b r o u t i n e > )


This is the decla ri n g met h o d for a stub (the repl ac e m e n t of a routin e). Imagin e your tar g e t is calling the
subr o u t i n e DO.SOMET HI NG, then you will decla r e it like this :
STUB = UTF.addStub("DO.SOMETHING")
Note that the ret u r n value is a function. You canno t do a lot with it app a r t passin g it back to the next
stub relat e d function s.

UTF.re m ov e S t u b ( < a _ s t u b_ r ef > )


Remove (delet e) an existin g stub

10
TAFJ U nit Test F r a m e wo rk
UTF.se t R e p e a t a b l e ( < a _ s t u b_ r ef > )
Nor m a lly, when the invocatio n of a sub is done, this one will not be re- use d. As an exam pl e, if the tar g e t
is calling 2 time s DO.SOMETHIN G, the n you should have 2 stubs (you should put 2
UTF.ad d S t u b (“DO.SO M ET HI NG”). Howev e r, by specifying that the stub is rep e a t a bl e , this save you to
decl a r e it twice. A typical routin e in T24 which can be “repe a t a b l e” is “CDT”.
The section desc ri bin g how the stub s are found (late r in this docu m e n t ) will cert ai nly bring som e lights.

UTF.se t S t o p p i n g( < a _ s u b_ r ef > )


In som e circu m s t a n c e s , a subro u ti n e is issuing a STOP stat e m e n t (like FATAL.ERROR in T24). In that
case, you can specify it for your stub like this :
STUB = UTF.addStub("FATAL.ERROR")
UTF.addStubParam(STUB, UTF.any(), UTF.same())
UTF.setStopping(STUB)

UTF.ad d S t u b P a r a m ( < a _ s t u b_ r ef > , <in_valu e > , <o u t_valu e > )


This met ho d has to be invoke d as many time s as the num b e r of par a m e t e r s in your stub. In
DO.SOMETHI NG, we have 3 para m e t e r s , so we nee d to invoke 3 times UTF.ad d S t u b P a r a m ( ...). The first
par a m e t e r is the stub refer e n c e s (obtai n e d when doing UTF.ad d S t u b ), the secon d one is the in-
par a m e t e r , the third one is the value of this para m e t e r afte r the call. We could arg u e about the in-
par a m e t e r nee d. This one is use d to det e c t which stub nee d s to be called. If we take the sam e CDT
function, we will have
STUB = UTF.addStub("CDT")
UTF.addStubParam(STUB, '', '')
UTF.addStubParam(STUB, "20130623", "20130624")
UTF.addStubParam(STUB, "+1C", "+1C")

STUB = UTF.addStub("CDT")
UTF.addStubParam(STUB, '', '')
UTF.addStubParam(STUB, "20130523", "20130524")
UTF.addStubParam(STUB, "+1C", "+1C")

When the tar g e t calls CDT('', 2013 0 6 2 3 , “+1C”), the n the 2 nd par a m e t e r cha n g e s to 2013 0 6 2 4 . The test s
nee d s to know which one to take. This explain the in- par a m e t e r .
Note that STUB is just a varia bl e nam e, you can put anyt hin g you want.
MY.FIRST.STUB = UTF.addStub("CDT")
UTF.addStubParam(MY.FIRST.STUB, '', '')
. . .

UTF.ad d S t u b C o m m o n C h a n g e ( < a _ s t u b_ r e f > , < c o m m o n > , < o u t _v al u e > )


Here, this is how we say that the subro u ti n e is suppo s e d to chan g e the value of a com m o n varia bl e.
Reme m b e r , since the routin e is neve r really called, we need to tell everyt hi n g. Of cours e , only com m o n
variabl e having an impa c t on the tar g e t routin e are nec es s a r y.

UTF.addStubCommonChange(STUB, COMI, "A NEW VALUE FOR COMI")

If your com m o n is an DIMm e d arr ay (eg R.NEW), you will pass an arr ay as new value :
DIM stubCommon(500)

11 Teme n o s Application Fra m e w o r k Java – (TAFJ)


TAFJ U nit Test F r a m e wo rk
stubCommon(10) = "A New Value for R.NEW"
UTF.addStubCommonChange(STUB, R.NEW, stubCommon)

UTF.ad d S t u b C a c h e C h a n g e ( < a _ s t u b_ r ef > , < b u c k e t_ n a m e > , <k ey > , <o u t_valu e > )
Sam e app ro a c h as for the com m o n, app a r t from the fact that you are not passi n g the com m o n itself, but
the Bucke t nam e and the key.
Doing som e t hi n g like that :

UTF.addStubCacheChange(STUB, "USED.BUCKET", "KEY1", "A New Value")

Is the equivale n t as the real routin e doing

CachePut("USED.BUCKET", "KEY1", "A New Value")

UTF.ad d S t u b W ri t e D o n e ( < a _ s t u b_ r ef > , < t a b l e > , < i d > , <ou t_r e c o r d > )
Exactly the sam e as the previous one, but for dat a b a s e .
So doing

UTF.addStubWriteDone(STUB, "F.MY.TEST", "MY.KEY.1", "A new Record")

is the sam e as if the routin e wer e doing a F.WRITE. Of cour s e, the data b a s e is not touch e d , but this is “as
if ...”

So afte r the stub invoca tion, the targ e t routi n e can do a


CALL F.READ("F.MY.TEST", "MY.KEY.1", REC, F.MY.TEST, ERR)
In REC, we would find : "A new Record"

UTF.ad d S t u b P r o p e r t y C h a n g e ( < a _ s t u b_ r ef > , < c o m p o n e n t > , < p r o p e r t y > , <valu e > )


When using compo n e n t s , COMMO N variabl e s are not acces si bl e direc tly. Inst e a d , thes e are gett e r s /
set t e r s on a prope r t y define d n the compo n e n t . Use the addS t u b P r o p e r t y C h a n g e met ho d, giving the
com po n e n t nam e and it's prope r t y for chan gi n g it whe n the stub is invoked.
As an exam pl e, if a routin e was doing
MOD.MyComponent.setMyProperty('a new value')
you will tell the stub the following :
UTF.ad d S t u b P r o p e r t y C h a n g e ( S T UB, 'MOD.MyCo m p o n e n t ' , 'MyProp e r t y', 'a new value')

UTF.se t S t u b R e t u r nV al u e( < a _ s t u b_ r ef > , <valu e > )


If a stub b is a function, you will specify the ret u r n value of the function with this met h o d

UTF.ge t N b I nv o c a ti o n( < a _ s t u b_ r ef > )

Retu r n the num b e r of time a stub got invoke d durin g the test
12
TAFJ U nit Test F r a m e wo rk
exa m pl e (check that our stub got invoke d 2 time s) :
NB.STUB = UTF.getNbInvocation(STUB)
UTF.assertEquals(2, NB.STUB)

Stub Condition s
The way stub s are select e d is, by nat u r e , base d on par a m e t e r s . These para m e t e r s can have modifie rs
(see specific cha pt e r) or can be set as UTF.any(). Howev e r, this is some ti m e s nec e s s a r y to specify whe n a
STUB is eligible base d on COMMON varia bl e s or Prope r ti e s.
There are 2 met h o d s to crea t e such condition s :
UTF.ad d S t u b C o m m o n C o n d i tio n( < a _ s t u b_ r e f > , A.COMMO N, value)
eg :
UTF.a d d S t u b C o m m o n C o n di ti o n( STUB, COMI, “1234”)
or
UTF.ad d S t u b P r o p e r t y C o n di tio n( < a _ s t u b_ r ef > , “Compo n e n t . n a m e ” , “Prope r t y”, value)
eg :
UTF.ad d S t u b P r o p e r t y C o n di ti on( STUB, “EB.Syst e m T a bl e s”, “Comi”, “1234”)
The value can be wra p p e d by all the modifier s.
Eg :
UTF.a d d S t u b C o m m o n C o n di ti o n( STUB, COMI, UTF.lessT h a n( 1 2 3 4 ))
Which mea n s :
This STUB is valid if the COMMON variabl e COMI is less than 1234 at the mom e n t of the call.

IO Met h o d
IO Keywor d s (OPEN, READ, WRITE, DELETE, MATREAD, MATWRITE, OPENS EQ, READSEQ,
WRITESEQ) but also their corr e s p o n di n g met ho d s (F.READ, CACHE.READ, F.WRITE, F.MATWRITE,
F.MATREAD, F.DELETE) are all base d on a “in- mem o ry stor a g e).
There is no need to STUB a F.READ, neith e r a F.WRITE, .... They will auto m a ti c ally use/u p d a t e this in-
me m stor a g e .
Now, before runni n g a test (runTe s t()), you will use the UTF.se t R e c o r d() met ho d, and after the test, if
you want to verify a reco r d, you will used the UTF.ge t R e c o r d () met ho d.
In the case of the SEQu e n ci al files, you will use the exact sam e mech a n i s m , but the ID will have to stay
empty (“”).
Here is an exam pl e of SEQUE NC IAL acce s s :
The Targe t :
SUBROUTINE DO.SEQ(FIRSTLINE)
OPENSEQ "/home/user/TOTEST", "MY.FILE" TO F.SEQ.FILE THEN
READSEQ FIRSTLINE FROM F.SEQ.FILE ELSE NULL
WRITESEQ "One Value" ON F.SEQ.FILE THEN NULL
WRITESEQ "Another Value" ON F.SEQ.FILE THEN NULL
END
END
END

13 Teme n o s Application Fra m e w o r k Java – (TAFJ)


TAFJ U nit Test F r a m e wo rk
The tes t :
TESTCASE TestDO.SEQ
UTF.setTarget("DO.SEQ")
PARAM = ""
UTF.addParam(PARAM)
NL = CHAR(10)
* Add a line in this in-mem file
MY.REC="Line 1" : NL
UTF.setRecord("MY.FILE", "", MY.REC)
UTF.runTest("Test SEQ")
UTF.assertEquals(PARAM, "Line 1")
* Get the record and verify that the writeseq occurred.
REC = UTF.getRecord("MY.FILE", "")
UTF.assertEquals(REC, "Line 1":NL:"One Value":NL:"Another Value":NL)
END

Ass e r t i o n s me t h o d s

These met h o d s are obvious and talking by the m s elv e s. If one of thes e met ho d is evalua t e d as “false”, the
test will be in “failur e”. Pleas e refer to the “repo r ti n g ” and “eclipse” chap t e r s for more det ails.
One small not e on the para m e t e r s .
At the begin ni n g of the docu m e n t , we mentio n e d that the par a m e t e r s shoul d be put as variabl e s and not
const a n t . Imagi n e that you wrot e
UTF.addParam("7")

Inst e a d of

P1 = "7"
UTF.addParam(P1)

This would make no sens e to make an asse r ti o n on “7” : UTF.assertEquals("7", "7")

But verifying that the first par a m e t e r is not cha n gi n g :

UTF.assertEquals(P1, "7")

Makes suddenly more sense.

UTF.as s e r t E q u a l s ( < v a l u e 1 > , <val u e 2 > )


TRUE if <val u e 1 > is equals to <val u e 2 > , FALSE othe r wi s e

14
TAFJ U nit Test F r a m e wo rk
UTF.as s e r t N o t E q u a l s ( < v a l u e 1 > , <valu e 2 > )
TRUE if <val u e 1 > is differe n t tha n < v a l u e 2 > , FALSE othe r wi s e

UTF.as s e r t C o n t a i n s ( < v a l u e 1 > , <val u e 2 > )


TRUE if <val u e 1 > cont ai n s <val u e 2 > , FALSE othe r wi s e

UTF.as s e r tT r u e ( < v a l u e > )


TRUE if <val u e 1 > is evalua t e d (jBC) to TRUE (sam e as IF <val u e 1 > ...)

UTF.as s e r t F a l s e ( < v a l u e > )


TRUE if <val u e 1 > is evalua t e d (jBC) to FALSE (sam e as IF NOT( <v al u e 1 > ) ...)

UTF.as s e r t G r e a t e r T h a n ( < v a l u e 1 > , <valu e 2 > )


TRUE if <val u e 1 > GT <val u e 2 > , FALSE othe r wi s e

UTF.as s e r tL e s s T h a n ( < v a l u e 1 > , <valu e 2 > )


TRUE if <val u e 1 > LT <valu e 2 > , FALSE othe r wi s e

UTF.as s e r t S t a r t s W it h( < v a l u e 1 > , <valu e 2 > )


TRUE if <val u e 1 > Star t s With <val u e 2 > , FALSE othe r wi s e

UTF.as s e r t E n d s Wi t h( < v a l u e 1 > , <valu e 2 > )


TRUE if <val u e 1 > Ends With <val u e 2 > , FALSE othe r wi s e

UTF.as s e r t M a t c h e s ( < v a l u e 1 > , < m a s k > )


TRUE if <val u e 1 > MATCHES <val u e 2 > , FALSE othe r wi s e
This is the MATCH equival e n t of jBC
eg

UTF.assertMatches(P1, "3N4X")
P1 = "123ABCD" : TRUE
P1 = "123ABC" : FALSE

UTF.ge tR e c o r d ( < t a b l e > , <id > )


This is fetchin g a recor d from the (in- mem o ry dat a b a s e ) useful for makin g asse r t io n s on the recor d.
REC = UTF.getRecord("F.MY.TEST", "MY.KEY.2")
UTF.assertEquals(REC, 'A new Record from stub' : @FM : "Modified")

Modifi e r s
This section should in fact be linked to the Stub s, but for clarity of the docu m e n t s let's keep it at the end.
Modifier s are infor m a t i o n s you can pass as argu m e n t s to the stub definition s or the stub s conditions.

When a test is runnin g, and the targ e t is makin g a CALL, the UTF is looking for the best mat c hi n g stub.
The first absolut e test is the stub nam e (the SUBROUTINE nam e must matc h EXACTELY the call
-obvious- ). Then, we will check the par a m e t e r s .

15 Teme n o s Application Fra m e w o r k Java – (TAFJ)


TAFJ U nit Test F r a m e wo rk
If all the par a m e t e r s are “norm ally” define d, then they must matc h exactly as well, howev e r, we can put
modifie rs so the stub could not fully matc h.

Exam pl e :

UTF.addStubParam(STUB, UTF.any(), "Anything")


Mea n s that what ev e r the in para m e t e r is, this stub will be eligible for the CALL and the par a m e t e r will
be cha n g e d to "Anything"

UTF.addStubParam(STUB, UTF.matches("2N"), "less than hundred")


Means that if the in parameter Matches "2N", this stub will be eligible for the CALL and the parameter will be changed to
"less than hundred"

So what if we have multiple stubs being eligible ?


The rules is the following.
The stubs are sort e d by <n u m b e r of strict value > , < n u m b e r of mat c h value > and <n u m b e r of “any”
value > . The top most stub will be take n.

In the prec e d e n t exam pl e, UTF.matches("2N") is better than UTF.any(). However, if we had


UTF.addStubParam(STUB, "12", "twelve"), and the parameter was "12", this is the one which would have been
taken.

UTF.any()
Do not conside r the par a m e t e r to elect the stub as a good stub for a given CALL.

UTF.m a t c h e s ( < m a s k > )


Elect the stub as a good stub for a given CALL if the par a m e t e r is matc hi n g (jBC MATCH) the given
mask.

UTF.s a m e ()
UTF.sa m e () is not a modifier as such. It is define d for the out- par a m e t e r . This is basically saying that the
out par a m e t e r ends up having the sam e value as the in. As an exa m pl e, this par a m e t e r :
UTF.addStubParam(STUB, UTF.matches("2N"), UTF.same())
Would not cha n g e the par a m e t e r if this is a 2 digit num b e r , and of cour s e, if ther e is no bett e r matc h (eg
UTF.addStubParam(STUB, "12", "twelve"))
The following modifiers do obviously not nee d any explan a t io n s :

16
TAFJ U nit Test F r a m e wo rk
UTF.isTru e( < v a l u e > )

UTF.isF als e( < v a l u e > )

UTF.con t a i n s ( < v a l u e > )

UTF.en d s Wi t h( < v a l u e > )

UTF.st a r t s Wit h( < v a l u e > )

UTF.gr e a t e r T h a n ( < v a l u e > )

UTF.les sT h a n ( < v a l u e > )

Reme m b e r that they can be used with


- UTF.a d d S t u b P a r a m
- UTF.a d d S t u b C o m m o n C o n d i t io n
- UTF. addS t u b P r o p e r t y C o n d i tio n

Creat i n g a ne w UnitT e s t

From scra t c h
Crea ti n g a test is not any differ e n t tha n cre a ti n g a new SUBROUTINE : In Eclipse, Right- click on the
direct o ry whe r e you want to cre a t e your test, selec t
New - > T24 routine / component / testcase

17 Teme n o s Application Fra m e w o r k Java – (TAFJ)


TAFJ U nit Test F r a m e wo rk

Select “Cre a t e UnitTest”, give a nam e to your file …

And auto m a t i c a lly a new TestC a s e , with a tem pl a t e will be crea t e d as follows :

18
TAFJ U nit Test F r a m e wo rk
Then this is just
a matt e r to edit /
save / run.

Editor
Helpe r s
When editing a
TESTCASE, you
have som e
options in the
cont ext u al men u
of your editor.
Righ- click on the
editor (whe r e
you want to add
som e t hi n g). You
will have the “Unit Test Fra m e w o r k ….” menu availabl e with 2 options : “Setti n g the targ e t ...” and
“Adding a stub...”

Settin g the targ e t


This option will open the JBC Subro u t i n e selectio n dialog (see specific cha pt e r ).
Select a routin e or com po n e n t met ho d, and the code for setti ng the targ e t with all para m e t e r s will be
adde d. You only will nee d to specify the value s of the par a m e t e r s .
Exam pl e by choosin g AA.Fees.CalculateTierAmount(...) :

You just nee d to specify values to your variable s.

Adding a stub
Adding a stub is done the sam e way as settin g the targ e t . The code will be gene r a t e d like this ( for
AC.API.EbUpdateAcctEntFwd )

The default values are UTF.a ny() for the IN par a m and UTF.sa m e () for the OUT para m . You will nee d to
chan g e thes e values accor di n g to your test case.

JBC Subro u ti n e selection dialog

The prec e d e n t chap t e r is mentio ni n g this dialog box, and her e is a desc ri ptio n of how it works.

19 Teme n o s Application Fra m e w o r k Java – (TAFJ)


TAFJ U nit Test F r a m e wo rk

IMPORTA NT : The con t e n t s of thi s dial o g box IS NOT THE SOURCE file s , but th e co m p i l e d on e .
This me a n s you don't ne e d to hav e all so u r c e s to be abl e to sel e c t a routi n e . Just have th e jars
in your pre c o m p i l e dire c t o r y .

Conv e r t i n g old tut s

There is a tool to conve r t tut version 1.0 to the new 2.0 version.
In the TAFJ/bin direct o ry, you will find the tConve r t T e s t (.bat file).
The synt ax is :

tConvertTest <file_to_convert> [<new_file>]

If the new file is omitt e d, the <file_to_conve r t > will be overri d d e n by the new one.

20
TAFJ U nit Test F r a m e wo rk
Compiling, and distrib u ti n g tests

A test acts as a jBC PROGRAM or SUBROUTIN E. There compile the sam e way, a Class is gene r a t e d , this
class can be put in a jar.

Run n i n g te s t s
In console mode

Runni n g a test is not very differ e n t as runni n g a prog r a m . Ther e is only one flag to specify : “-test”. This
flag is nece s s a r y as the class gene r a t e d is prefixed with “test c a s e .” to not conflict with the tar g e t
subr o u t i n e .

To resu m e :

MY.SUBROUTIN E. b gen e r a t e a class called MY_SUBROUTINE_cl.cl ass

MY.SUBROUTIN E.t u t gene r a t e a class called test c a s e_ MY_SUBROUTIN E_cl.clas s

exa m pl e : tRun MY.SUBROUTINE will try to run the class MY_SUBROUTINE_cl.cla s s which is wrong.
You have to run :

tRu n -tes t MY.S U B R O U T I N E in orde r to run test c a s e_MY_SUBROUTIN E_cl.cla s s.

So this is

tRun -test myTest

Where “myTest” is the name you gave here :

You can also run your test by specifying the full file na m e .

Exam pl e :

tRun -test /path/to/my/top/dev/directory/unitTests/myTest.tut

Runnin g multiple test s at once

You can also specify a direc t o ry. In that case, all test s in this direct o ry will be run

Exam pl e :

tRun -test /path/to/my/top/dev/directory/unittests

21 Teme n o s Application Fra m e w o r k Java – (TAFJ)


TAFJ U nit Test F r a m e wo rk
And last but not least, you can use the -rec u r s flag if you want to find test s resu r siv ely in a direc to ry and
run the m :

Exam pl e :

tRun -test -recurs /path/to/my/top/dev/directory

Retu r n value
In console mode, the exit value of tRun will be 1 if one or mor e test are failing. A succe s s value is 0.
Note that a failure can be som e t hi n g else than a wron g asse r t io n. It can be a call to a non existin g
routin e, a test without asse r ti o n, or any kind of techni c al failur e.

22
TAFJ U nit Test F r a m e wo rk
In Eclipse
Running a test in eclipse consist of selecting

1) One *.tut file

2) Multiple *.tut files

3) One or multiple directories (containing “at least” one tut file)


Right-Click - > Run (or Debug) As … - > Unit Tests

Autom a t ic ally, a new window will open showing the tests and their result s :

23 Teme n o s Application Fra m e w o r k Java – (TAFJ)


TAFJ U nit Test F r a m e wo rk
The “res ult” view

This view will show all possible infor m a t io n s reg a r di n g the differ e n t tests.

One *.tut file can cont ai n s multipl e test s (UTF.ru nT e s t (..). In that case, this singl e tut file will be
pres e n t e d as multiple test, with a count e r (2 nd colum n). You can drill- down (open) the line to see the
differ e n t asse r t io n s.
Also, the last colum n is showin g the code cover a g e of the tar g e t . You can right- click on a line and you
will have the choice to
1) open the tut file
2) open the targ e t with the code cover a g e highlight s (or doubl e click)
3) open the targ e t .

Also, by doubl e- clicking on an asse r ti o n, the tut file will be open and the focus will be given to the
asse r ti o n line.

24
TAFJ U nit Test F r a m e wo rk
Colors mea ni n g

Everyt hi n g which is Gree n conce r n s the test itself. If this is a “light” gree n, this me a n s that thes e are
lines cover e d by this test only. The num b e r of line is folowing the perc e n t a g e . (eg : 53% +2 mea n s : Code
cover a g e of this test is 53 %, and 2 lines are cover e d just by this test). This allow the develop e r to quickly
see what is the ben efit of this test in ter m of code cover a g e .

The gray lines are lines cover e d by the othe r test s for the sam e targ e t .
The color
sche m e in the
Result view is
the sam e as the
one in the
editor.
Here is an
exa m pl e of
what you will
see when
doubl e- clicking
on a test (not an
asse r ti o n) or by
choosin g “Open
Targe t with
Code Cover a g e ”
Line 32 - > 40
are not touc h e d
by this test, but
are touc h e d by
som e othe r
tests
Line 17 → 26 are cover e d by this test and som e othe r test s.
Line 27 /28 are touch e d by this test and this is the only test touchi n g them .
You will see that som e lines (29, 36, 38) are not highligh t e d . This is beca u s e the r e is no equivale n t of
thes e lines in java, and the runti m e is neve r touc hi n g the m. The count of total line knows that and the
cover a g e ratio of this tar g e t is 100%. This will be resolve d in futur e versions.

Rep o r t i n g
You can generate junit types of reports by specifying it in the properties file with the following keys :
temn.tafj.utf.generate.results = true
By default, the repor t s (xml files) are gene r a t e d in
<tafj_home>/data/<projectName>/testResults/
25 Teme n o s Application Fra m e w o r k Java – (TAFJ)
TAFJ U nit Test F r a m e wo rk
You can chan g e this defa ul t location with the key

temn.tafj.utf.results.directory = …

Com p o n e n t and UnitT e s t s

Scopin g excep tio n


You can use $USING / $PACKAGE as any othe r jBC file. A small disting ui s hi n g : The scopi ng do not apply
whe n writing a TESTCASE. This mea n s you can acces s privat e met ho d s of any compo n e n t .

Stub bin g a met h o d


A met ho d can be stub b e d by giving it fully qualified na m e
UTF.ad d S t u b (“ M OD.Co m p o n e n t . m y M e t h o d ” )
You do not nee d to explicitly add a $USING for this stub case.

26

You might also like