Beruflich Dokumente
Kultur Dokumente
Table Of Contents
Abstract..............................................................................................................................................................5
Document Revision History...............................................................................................................................6
1.WCC Testing...................................................................................................................................................7
1.1 XML Testing.............................................................................................................................................7
1.2 Limitations.................................................................................................................................................7
2.FitNesse Basics...............................................................................................................................................8
2.1 Testing With FitNesse...............................................................................................................................8
2.2 Testing WCC with FitNesse......................................................................................................................9
2.3 Basic Setup to test WCC with FitNesse..................................................................................................10
2.4 Creating, Editing and maintenance of Test and Suite Pages...................................................................12
2.5 Test scripts and WCC Tests....................................................................................................................13
2.6 Table Processing......................................................................................................................................14
2.7 Running Tests..........................................................................................................................................16
3.Basic Fixture.................................................................................................................................................19
3.1 What is Basic Fixture?............................................................................................................................19
3.2 Syntax for Base Fixture...........................................................................................................................19
3.3 PassThrough............................................................................................................................................21
3.4 Value.......................................................................................................................................................22
3.5 Not Value................................................................................................................................................24
3.6 Count.......................................................................................................................................................24
3.7 Exists.......................................................................................................................................................25
3.8 Not Exists................................................................................................................................................26
3.9 Variable Placeholder(!!)..........................................................................................................................26
3.10 Limitations.............................................................................................................................................27
3.10.1) Strict Adherence to data – Scripts have to be data specific...........................................................27
3.10.2) Limited ways of asserting..............................................................................................................27
3.10.3) Request and Response xml files not getting saved........................................................................28
3.10.4) Only responses can be asserted and validated................................................................................28
3.10.5) Improper Handling of Exceptions..................................................................................................28
3.11 Example Test.........................................................................................................................................29
4.Customized Fixture.......................................................................................................................................31
4.1 New Syntax.............................................................................................................................................31
Prasad Buddha 2
WCC Testing With FitNesse User Guide IBM
4.2 Behavioral Modifications........................................................................................................................32
4.2.1) Storing request and response xml files.............................................................................................32
4.2.2) XPath validations on Request xml ..................................................................................................33
4.2.3) Output Captured...............................................................................................................................33
4.2.4) Properties File..................................................................................................................................35
4.2.5) Testing the performance...................................................................................................................36
4.2.6) Action Keyword behavioral changes...............................................................................................37
4.3 File Handlers...........................................................................................................................................38
4.3.1) ByPass..............................................................................................................................................38
4.3.2) Pass...................................................................................................................................................39
4.3.3) Force.................................................................................................................................................39
4.3.4) Optional............................................................................................................................................40
4.3.5) No File..............................................................................................................................................41
4.4 Predefined Variables...............................................................................................................................42
4.4.1) ?UniqueKey?....................................................................................................................................42
4.4.2) ?UniqueNumber?.............................................................................................................................42
4.4.3) ?YYYY?, ?MM?, ?DD?...................................................................................................................43
4.4.4) ?CreateBackup?................................................................................................................................43
4.5 New Variable Placeholder.......................................................................................................................44
4.5.1) ##......................................................................................................................................................44
4.6 New Passthroughs...................................................................................................................................45
4.6.1) Count PassThrough..........................................................................................................................45
4.6.2) Part PassThrough.............................................................................................................................45
4.6.3) CPassThrough..................................................................................................................................47
4.6.4) CPart PassThrough...........................................................................................................................48
4.6.5) CPassThrough Or Copy...................................................................................................................49
4.7 New Assertions........................................................................................................................................50
4.7.1) Value IgnoreCase.............................................................................................................................50
4.7.2) Contains............................................................................................................................................51
4.7.3) Is Empty...........................................................................................................................................51
4.7.4) Not Empty........................................................................................................................................51
4.7.5) Length..............................................................................................................................................52
4.7.6) Is PastDate........................................................................................................................................52
4.7.7) Is FutureDate....................................................................................................................................52
Prasad Buddha 3
WCC Testing With FitNesse User Guide IBM
4.7.8) Is Today............................................................................................................................................53
4.7.9) Is Before...........................................................................................................................................54
4.7.10) Is After...........................................................................................................................................55
4.7.11) Is SameDate...................................................................................................................................55
4.7.12) CValue............................................................................................................................................56
4.7.13) CValue IgnoreCase........................................................................................................................60
4.7.14) CContains.......................................................................................................................................60
4.7.15) All CValue IgnoreCase..................................................................................................................61
4.7.16) All CContains.................................................................................................................................62
4.8 Miscellaneous Key words.......................................................................................................................63
4.8.1) Copy.................................................................................................................................................63
4.8.2) CCopy..............................................................................................................................................64
4.8.3) Add...................................................................................................................................................65
4.8.4) If Variable Exists … EndIf..............................................................................................................65
4.8.5) Display Value...................................................................................................................................66
4.8.6) Display Count...................................................................................................................................67
4.8.7) Exception..........................................................................................................................................67
4.8.8) Remind.............................................................................................................................................67
4.8.9) #........................................................................................................................................................67
4.8.10) Reset...............................................................................................................................................67
4.8.11) Reset All.........................................................................................................................................68
4.9 Advantages of Customized fixture..........................................................................................................68
4.9.1) Separating scripts from data.............................................................................................................68
4.9.2) More Actions....................................................................................................................................69
4.9.3) Request as well as response xml files can be validated...................................................................70
4.9.4) Requests and Responses getting saved for future reference............................................................70
4.9.5) Unique Key generators and Unique Number generators and several other predefined variables....70
4.9.6) Customized log makes it easy to open xml files for debugging.......................................................70
5.Re-usability...................................................................................................................................................71
5.1 Designing the Reusable Components......................................................................................................72
5.2 Including the Reusable Components.......................................................................................................74
Appendix – I: Syntax of All the Actions..........................................................................................................77
Appendix – II: Actions & Number of Tags......................................................................................................78
Prasad Buddha 4
WCC Testing With FitNesse User Guide IBM
Abstract
This document discusses about an open source tool called FitNesse and how it is used to test WCC.
This document starts by giving a brief idea about FitNesse and its features. Then it discusses about a plug-
in that is developed to enable simple and basic unit testing of WCC xml transactions. It then explores the
features, I have added to the fixture by redesigning it to make many things possible, which are impossible
with the fixture before those customizations. This document explains how all these new features to the
plug-in (fixture) make WCC testing with FitNesse easier and provide more testability.
Why do we need a different tool for xml testing? The answer is simple. The comparison we have to
do in this case is different. We are not comparing two similar xml files with different data but two different
xml files with different structure. We may even have to compare two different tags in the same file. Doing
these things in the regular xml comparison tools is extremely complex. Therefore, we need a different set
of tools to do just that. This document tells how to do that.
As market conditions drive companies to become more customer-centric, many organizations are
turning to packaged Customer Data Integration (CDI) solutions to help enable their transformation. With
WebSphere Customer Center, IBM® markets the industry’s most robust and mature Customer Data Integ
ration solution. WCC’s unique set of 500+ pre-built ‘business services’ enables organizations of all sizes
to build a solid foundation of ‘actionable’ customer data for consumption by front and back-office systems
in real-time or in batch.
The Customers that are using WebSphere Customer Center or simply WCC are growing in quick
succession. So many clients like SunTrust are opting for WCC for their customer data management and
customizing the product to suit their needs. As the number OOTB transactions (Out Of The Box or simply
readymade transactions) are growing and customized transactions are increasing at a high pace, the testing
of WCC projects is getting more and more complex. The back end testing of WCC involves execution of
xml transactions and comparing request and response xml files of various transactions. We need to analyze
many xml files in a very short span of time.
‘Whether the xml files are being generated properly or not?’, ‘whether the xml files contain correct
data in correct tags or not?’ are the main questions to be answered by the test team while testing xml trans
actions. In such a scenario, where, xml files are getting bigger and transactions becoming complex the test
ing is a nightmare in this agile world. Whenever a new requirement comes, it is not enough if you just test
the new requirement, we have to rerun all the regression test cases and analyze all the xml files repeatedly.
Analyzing all the xml files manually is a gigantic task and requires large-scale human effort, time, and
cost.
This document does not speak about how to customize WccXMLFixture or how to create new fix
tures. They are out of scope for this document. This document does not even give many details about
WCC.
Prasad Buddha 5
WCC Testing With FitNesse User Guide IBM
Prasad Buddha 6
WCC Testing With FitNesse User Guide IBM
1.WCC Testing
WCC uses a request/response framework to maintain data. The request can be through an xml re
quest or through UI provided by WCC. Hence, WCC Testing can be either xml testing or DSUI testing.
DSUI testing is out of scope for this document. The xml request/response framework consists of the follow
ing simple steps.
xml request is created and submitted to WCC. This request contains information about what ex
actly has to be done.
WCC then reads the xml request and goes through each of the three layers detailed above. Using
its unified view of information WCC attempts to perform action specified within xml request,
while ensuring that customer data remain consistent.
WCC creates an xml response that contains a success message with data related to the request or
a failure message if the transaction is unsuccessful.
1.1 XML Testing
xml Testing beginning with a mere preparation of request xml files, execute the transaction by hit
ting the WCC and get the response xml file, compare the input and output xml files, check for missing and
misplaced data to identify defects and save the xml files for future reference.
1.2 Limitations
There are quite a few challenges for any xml testing. There is no easy way to automate xml testing
so far and manual testing has its own set of setbacks. Here are they.
The biggest issue is time. xml files may contain less than two to more than thousands of tags.
Executing the transaction and comparing all the tags of all the xml files repeatedly for every re
gression cycle, is a very tedious task.
Doing everything manually can cause errors to creep in and bugs to escape from the early stages
of testing.
Automating the testing is a solution to overcome the limitations set by manual testing, but as we
discussed, so far there is no best way to automate xml testing. After 8 months of experimentation and suc
cessful implementation, we came to a near perfect solution to validate and compare xml files.
The solution for this problem is extending a tool named FitNesse and creating a plug-in like com
ponent (let us call it Fixture from here on wards) that does what we needed and the solution surprisingly
comes at free of cost. FitNesse is a web server, a WIKI, and an open source software-testing tool. It is
based on Ward Cunningham’s Framework for Integrated Test. FitNesse is designed to support acceptance
testing. With the new features, we use it for a lot more than simple acceptance testing in our project; we
use it in all levels of testing WCC xml services in our project.
Prasad Buddha 7
WCC Testing With FitNesse User Guide IBM
2.FitNesse Basics
FitNesse enables customers, testers, and programmers to learn what their software should do, and
to compare automatically that to what it actually does. It compares customers’ expectations to actual res
ults. From another perspective, FitNesse is a lightweight, open-source framework that makes it easy for
software teams to organize and run test scripts etc.
FitNesse is a software-testing tool -
You can collaboratively define Acceptance Tests -- web pages containing simple tables of inputs
and expected outputs.
Run those tests and see the results.
FitNesse is a wiki -
You can easily create and edit pages.
It uses wiki syntax to create test tables.
FitNesse is a web server -
It requires no configuration or setup.
Just run it and then direct your browser to the machine where it is running.
2.1 Testing With FitNesse
To write a test case in FitNesse, tester needs to create a new test Wiki Page. In that page, tester cre
ates test tables, which contain information required for the test case. The test page should also contain a
construct called a Fixture. It can be program to be tested, or it can even be an adapter between FitNesse
and application to be tested. In some test cases, a single fixture is all that is needed. However, many times
a test case may require more than just one fixture to ensure the proper functionality.
One key concept of the FitNesse is that Wiki Pages are put together in a hierarchy. By leveraging
this capability, testers can group functional tests together and run them in what is called a Suite. A Suite
Prasad Buddha 8
WCC Testing With FitNesse User Guide IBM
will execute all tests that are below it within the hierarchy. FitNesse also allows you to create Suites of
Suites.
Wait a moment, if the fixture communicates to WCC by sending the request and receiving the re
sponse xml files and if fixture validates the xml against the automation script, why do we need FitNesse?
Why does the fixture have to tell FitNesse, whether the test case has passed or failed?
As explained earlier, FitNesse is a wiki server; it helps us to organize all our test scripts in the form
or Wiki pages. It is a web server, it enables multiple people to work on automation scripts by keeping at
central location and serve the test scripts like web pages to testers. Even when fixture is doing all the work,
at some point of time the fixture has to be called, FitNesse is the calling application. It supplies the fixture
right automation script at right time, when the tester wants to test. FitNesse receives the statistics, whether
the tests have passed or failed and creates a report that is easy to debug.
Therefore, neither just FitNesse, nor just fixture is enough to test our application; we need both.
However, you do not have to worry; a fixture is already developed to test WCC xml services. You just
have to use it. All you need is you need to have is JRE installed in your system, running copy of FitNesse
and a little knowledge on how to use the fixture. The name of the fixture is WccXMLFixture.
Looking at the picture above we can conclude that user can interact with FitNesse for two pur
poses, either for creating test automation scripts or for testing the WCC services. While creating automa
tion scripts, the tester uses FitNesse UI and saves the script through it. In that phase, neither Fixture, nor
WCC comes into action. While testing, the user asks FitNesse to execute test cases; FitNesse takes the
Prasad Buddha 9
WCC Testing With FitNesse User Guide IBM
scripts that are created earlier and sends them to WccXMLFixture. Fixture collects the xml files as per the
path mentioned in the script. The fixture then converts the xml file into a string and then passes it to WCC.
WCC then sends back a response xml in the form of a string. The Fixture then saves the response xml
string as xml file. Then the validates the request and response xml files depending on the automation script
to find out if there are any issues, and if it finds any discrepancies, it sends the test status and relevant error
message to FitNesse. FitNesse prepares a report for easy debug and presents it to the tester.
Prasad Buddha 10
WCC Testing With FitNesse User Guide IBM
To be able to run the WCC
tests, there are a couple of vari
ables that must be defined in each
test page, or instead they can be
defined in a home page for which
all other test script pages are chil
dren. The variables are…
classpath
COMMAND_PATTERN
Classpath tells FitNesse
where to search for required class
files. COMMAND_PATTERN
tells FitNesse where to find WAS
environment files and JRE envir
onment. Classpath variable is
defined using the syntax ‘!path Figure 3: Home Page Of FitNesse in our project
<path>’.
Here is the example for classpath variable definition…
!path lib/fitnesse.jar
!path lib/fitlibrary.jar
!path ./WCCFixture/wccFitnesse.zip
!path ./WCCFixture/DWLCommonServices.jar
!path ./WCCFixture/xmlunit1.0.jar
!path ./WCCFixture/ace.jar
!path ./WCCFixture/j2ee_ce_client.jar
!path ./WCCFixture/log4j-1.2.9.jar
!path ./WCCFixture/commons-logging.jar
!path ./WCCFixture/commons-io.jar
!path ./WCCFixture/commons-lang-2.1.jar
To understand the way these definitions work, refer to the FitNesse user guide. You do not have to
worry about the setting up these variables; Setup provided along with this document defines all the vari
ables required and provides the required jar files.
Prasad Buddha 11
WCC Testing With FitNesse User Guide IBM
Figure 5: FitNesse page with Test script Figure 4: Suite page referring other pages
Click Edit button in the left menu bar to edit a page. This will bring you to a new page with a text
box containing the editable text of the original page. The Text box has all the page content in WIKI
markup language (raw script); you do not see the tables or links anymore. Look at Figure 6 for reference.
Once the Page is saved, it will be displayed in form of a table as in the Figure 5, as per the wiki markup
rules.
Prasad Buddha 12
WCC Testing With FitNesse User Guide IBM
A new page can be created while in edit mode of another page. All we need to do is typing a new
name following page-naming rules. FitNesse automatically recognizes any word in the page as qualified
name for page creation, if the word satisfies the following rules…
1. The word must be in Camel Case (each word starting with a capital letter)
2. There must be at least two capital letters (ex: NewPage, QualitY)
3. It must start with an alphabet(A-Z) or a ‘^’
4. There must not be two consecutive capital letters
5. There must not be any spaces or special characters
For example, if you type QualitY or TestAddPerson123 in the edit mode of SandBox, and save the
page, a hyperlinked question mark will appear beside the above word. Click on the question mark, and a
new page will be displayed with an empty text box be opened with the page
name QualitY or TestAddPerson123 type something in the page and hit save.
You have just created a sibling page for SandBox, if you want to create the
page as a child, you should type ^QualitY or ^TestAddPerson123 while in
edit mode of SandBox.
Whenever such a word (which is qualified to be the name for a page)
is typed in edit mode of a page and saved, a hyperlinked question mark ap
pears after that word as in Figure 7. Clicking on that link takes us to edit Figure 7: Question marks
mode of the new page. The word we typed in edit mode of parent page will beside words that are eli
be the name of the new page. We can enter anything we want, it can be our gible to be a page name
test script, or it can be something else depending on the requirement. Observe
that there is no question mark beside ‘Sample Tests’ in the figure as it is not a
qualified page name (the two words are separated with a space).
For more information on WIKI markup language and creating tests and suites, refer to the user
guide that comes with FitNesse.
We do not have to understand how the above test table works except for two things. The first thing
you have to know is about the first line. The first line in the table tells that the fixture that is going to be
used is eg.Division (if you are aware of Java, you can guess that ‘eg’ is a package and Division is a class in
that package). The other thing you have to know is that the syntax you find from second line is the syntax
expected by the fixture. The number of columns may vary according to the number of inputs required for
Prasad Buddha 13
WCC Testing With FitNesse User Guide IBM
the fixture and the number of outputs that are to be verified. Let us not go into any more details of the
above table.
Similarly, if we have to test WCC, our first line should tell FitNesse that we are going to use Wc
cXMLFixture. From second line onwards, it will be the syntax expected by WccXMLFixture. The syntax
can mean that the URL for WCC server, xml file name, the action keywords, representing tags, and defin
ing variables to compare xml files etc.
In edit mode (normal text or raw wiki script view) of a typical page, there can be different parts in
the script. The Portions marked in Yellow in Figure 8 are the real testing portions of the scripts. They are
test tables. They start with ‘!|com.ibm.wcc.fitnesse.WccXMLFixture|’, and end with an empty line. The
com.ibm.wcc.fitnesse.WccXMLFixture is applicable only for our WCC testing of xml transactions.
The next area marked in brown is a multi-line comment. A multi-line comment start with a triple
opening braces ‘{{{’ and ends with a triple closing braces ‘}}}’. Whatever you keep between those two
triple braces, will be considered as a block comment. Even if you place test tables, they will be ignored
while running the script.
However, if you look at the second yellow portion, you can see that the table does not end with an
empty line. It ends with a commented line. A single line comment starts with ‘#’. Whatever you write after
# is just a comment and will be ignored. There are two lines in the area after second test table.
The first portion in green is some text. This is not a comment but it is not a part of the test script. It
is just used to provide more clarity. You may also use such text to give the various steps in a test case, ex
pected result, test case description and what not. However, there is no rule that these portions have to be in
the places as shown below. Any portion can be at any place you need it. A test script can start with a
Prasad Buddha 14
WCC Testing With FitNesse User Guide IBM
straight test table. However, once test-table starts, the subsequent lines must start with a ‘|’ or else the test
table ends. Once you save the script, it looks as in Figure 9…
Figure 9: Once the script is saved, it will be rendered as per wiki syntax by FitNesse
If you have observed, you do not see certain characters in Figure 9. The first portion does not
change much. However, the test table portion looks like a real table now. Then the block comment portion
does not look like a test table, even if there is a test table between {{{ and }}}. FitNesse does not consider
the text between those two characters as test script, so it displays the text same as we entered in edit mode.
The next test table also appears like a test table. However, you do not see the next lines as in edit page, as
those two are single line comments. FitNesse does not show you whatever you commented with a ‘#’.
If exclamation is missing from the beginning of the first line of a test-table, FitNesse does not con
sider it as a test table. However, it looks like a table. You may find ‘----’ in the script, it is just to add a ho
rizontal line. There are many more. However, I want to confine this discussion to just test-tables. Not all
the other things are so important, and you can find out in internet if you search for Wiki Syntax.
By following all these rules, you can make scripts with any level of complexity. It does not matter
how long the script is. It all boils down to one point, what is the number of test tables that are not commen
ted?
Prasad Buddha 15
WCC Testing With FitNesse User Guide IBM
Figure 11: Running the script will change the color of cells depending on the Pass or Fail status
Figure 12: Test case execution with failures turning into red
Observe the top-left corner of Figure 11, you will find a hyperlink that says Output Captured, and
clicking on that link will take us to the logs. Any exception while running the scripts, the request and re
sponse xml files. Here is the screen-shot when we click Output Captured. The output logs has various de
tails like when it is executed, the time taken to execute the test case and request and response xml files, if
there are any exceptions, they will be printed to this log.
Prasad Buddha 16
WCC Testing With FitNesse User Guide IBM
Prasad Buddha 17
WCC Testing With FitNesse User Guide IBM
Figure 14: Report band turns green and displays number Figure 15: When some exception occurs, Report band
of assertion passed turns into Yellow and observe number of exceptions
Figure 17: Any failed action lines will turn the report Figure 16: If nothing else passed and some rows are ig
band red nored the report band turns into Grey, here some passed
Observe the Report band that tells how many action lines passed and how many failed. If we run an
entire suite the report band also displays, how many test cases failed and how many passed along with the
number of assertions passed and failed. Along with the report band, it also displays status of each test
when we run a suite, and results of each test are appended to the same suite results page as show below.
Prasad Buddha 18
WCC Testing With FitNesse User Guide IBM
3.Basic Fixture
As explained so far… FitNesse does not have any in-built capabilities to test WCC, to be precise it
does not even have in-built capabilities to read and validate xml files. We need an additional component or
plug-in that reads xml, modifies them, sends a request to WCC server, receives response and compares the
xml tags. An additional component or plug-in or fixture is required to do all these tasks. Luckily, it is
already created back in 2006. In this document, we call it a Basic Fixture, because it lacks certain features
that are required to be able to use it as an effective alternate for manual testing and a full-scale tool for
automating WCC testing. I have added many features that are required for this fixture to be a full-scale al
ternative to manual testing. I call it Customized Fixture.
com.ibm.wcc.fitnesse.WccXMLFixture
WCC Instance Name WCC Provider URL
XML file name
Variable
Action Keyword XPath of the tag to be used from response XML
or constant
:
:
Variable
Action Keyword Xpath of the tag to be used from response XML
or constant
Illustration 1: Syntax for Basic WccXMLFixture
The above table tells many things about the syntax required for WCC testing. The first line is the
fixture line com.ibm.wcc.fitnesse.WccXMLFixture; WccXMLFixture is a Java class file that is in the
package com.ibm.wcc.fitnessse. The second line consists of two cells, first cell is for telling fixture, the in
Prasad Buddha 19
WCC Testing With FitNesse User Guide IBM
stance name and the second cell is to tell fixture the URL of the WCC server. The third cell is for mention
ing the name of the xml file.
From the fourth line to end of the table, the first cell is for action keyword (either passthrough or
assertions) to work on the tags. The second cell is for XPath of the tag to work on. The first two cells are
mandatory and the third cell is conditional. It becomes either mandatory or optional depending on the first
cell. Here is an example of a small test table.
!|com.ibm.wcc.fitnesse.WccXMLFixture|
|${WCCInstanceName}|${WCCProviderUrl}|
|${WCCInputDirBase}Samples\addPerson.xml|
|Not Exists|/TCRMService/TxResponse/TxResult/ResultCode|
|Value|/TCRMService/TxResponse/TxResult/ResultCode|SUCCESS|
|PassThrough|/TCRMService/TxResponse/ResponseObject/TCRMPersonBObj/PartyId|partyID?|
The small portions of wiki script that starts with ‘${’ and ends with ‘}’ are the fitnesse-page-vari
ables. These variables are used to simplify changing portions of fitnesse script. The fitnesse-page-variables
can be defined using the keyword define. Those variables can be used anywhere in the fitnesse pages. Here
is the syntax to create page-variables…
!define <Variable Name> {<value>}
To define a page-variable the first character of the line must be an exclamation, which is immedi
ately followed by the keyword define. Therefore, in the above example, WCCProviderUrl is the variable
and iiop://10.19.6.241 is the value in the variable. To use the variable anywhere inside fitnesse scripts, you
have to use the syntax ${<variable name>}. Thus, let us call ${ and } as the variable placeholders for
page-variables.
Is it confusing? Let us rephrase it. We define page-variables and store a value inside using the !
define keyword, we use those variables in subsequent children pages to provide flexibility, to get the value
inside the variables, we enclose the variable name with page-variable placeholders. If you ask me the dif
ference between page-variables and script variables, page-variables are static, they do not change once the
test is started to run, they are like constants, you know what their values are, before running a test. The
script variables are dynamic, they will be created at run-time. They exist as long as the test runs. You may
not be able to find what their values will be until running the script.
The number of cells from fourth row can vary depending on the kind of validation or work, we
want to do on the tag. We use fixture-defined keywords in the first cell of the table from fourth row on
wards. Sometimes you want to fetch value in a tag and compare it to another value. In such a case, you
need to tell fixture that you want to compare, then which tag to compare and finally which value to com
pare. To do this we need to tell the fixture two things(the tag and the value). Sometimes, we just want to
check whether a tag is empty. To do that, we have to tell the fixture that we want to find out if a tag is
empty. Therefore, here we need only one cell(tag). We tell fixture about what we want to do using fixture
keywords. We tell fixture about the path of the tag using XPath notation. We give words of our own
choice to name variables or values.
Prasad Buddha 20
WCC Testing With FitNesse User Guide IBM
With this basic version of fixture, two types of key words can be used in the first cell of test-table
from the fourth row. One is PassThrough and the other type is assertion. PassThrough is used for storing
value from a tag and assertions are a way to ensure that a tag is according to our need. For example, to
check that it has a value what we expected, or to check if it is empty etc., Let us go through all the fixture
keywords in the following sections of this document. PassThrough is the only keyword that comes under
PassThrough type. Exists, Not Exists, Value, Not Value, and Count are assertion type of keywords because
they assert.
3.3 PassThrough
PassThrough is a keyword that can be
used to get the value from an xml tag and store it
in a variable. It expects two parameters, a valid
XPath that resolves to a unique tag and a variable.
The flow of pass-through begins with
checking if Cell 2 and Cell 3 available. Once both
the validations succeeded, it checks if the XPath
provided is valid or not. If required cells are not
available, it throws an exception.
If the XPath is valid, the fixture checks if a
unique tag can be resolved for the XPath in the
xml file. Pass-through requires the XPath to
match a single tag in xml file. If an XPath
matches no tag, it is an error. If an XPath matches
more than one tag, the fixture cannot decide
which tag to get the value from, so it throws an er
ror. Even If the XPath matches a single tag but if
the tag is empty, it is still an error.
Once a unique tag matches the XPath and
a string is found in the tag, the fixture fetches the
value inside the tag and stores it in a variable with
the name provided in the cell 3. There are no
naming rules for script variables. As a standard
and convention we are having a question mark at
the end of every variable like partyID?, address
lineone?.
The flow of operations in PassThrough is
presented in the flowchart in Figure 20. The flow
takes the green path when everything goes as ex
pected and the red path is taken whenever some
exception occurs.
PassThrough is the only way in which you
can take the value from a tag and store it in a vari
able. You can use this variable for comparisons or
as input data for the subsequent xml files. Below
is a screen-shot for example usage of
PassThrough. Figure 20: Flow of PassThrough
Prasad Buddha 21
WCC Testing With FitNesse User Guide IBM
As explained previously, the first cell must always be the action keyword, in this case it is
PassThrough and the second cell is for XPath of the tag for the PassThrough to work on (whatever you see
something similar to /TCRMService/TxResponse/Response..) and the third cell is for variable partyID?
The raw wiki script (in edit window) for the line highlighted in Figure 21 will be as below…
|PassThrough|/TCRMService/TxResponse/ResponseObject/TCRMPersonBObj/PartyId|partyID?|
When the test is executed, the flow of execution will be same as shown in flowchart. It Passes or
fails accordingly. Here are few examples when we run PassThrough in different scenarios.
3.4 Value
Value is an Assertion type of action keyword. This asserts that the value in the tag is equal to the
value provided in the third cell of the test-table. Here are two different usages of Value action.
Prasad Buddha 22
WCC Testing With FitNesse User Guide IBM
The flow of Value action is similar to flow of PassThrough except for small changes at the end.
Once the existence of Cells 2 and 3 is confirmed, and unique tag resolution is successful, there starts the
difference between PassThrough and value actions. Value action verifies, if any variable is provided in the
third cell of the same row in the test-table. If a variable is used, the fixture checks if the variable used is
already defined using a PassThrough. If the variable is not yet defined, it throws an error. If the variable is
found, it replaces the variable with the value of the variable.
Prasad Buddha 23
WCC Testing With FitNesse User Guide IBM
Once the value in the third cell becomes a constant, the fixture compares that constant string with
the value inside the tag, if they are equal the assertion passes, or else it displays the actual value and the
expected values. If we provide both variable and string in the third cell, it concatenates both after replacing
the value of the variable and then treats the cell as a constant.
As long as there are no exceptions, the flow takes the green path as in Figure 24. Any exception
will lead to failure of assertion. XPath matching to no tag, or multiple tags also produces a similar kind of
error as in PassThrough.
The wiki script syntax for the above two scenarios (one using a constant in the third cell, and other
with a variable) will be as shown below…
|Value|/TCRMService/TxResponse/TxResult/ResultCode|SUCCESS|
|Value|/TCRMService/TxResponse/TxResult/ResultCode|!!resultCode?!!|
3.6 Count
Count is an assertion type of
action that asserts that the number of
tags matching with the XPath is
equal to an integer value we provide.
For example, we can verify if a party
has only one Address or three contact
methods etc.,
Once Availability of cells 2
and 3 is confirmed, and the XPath in
cell 2 is valid, fixture checks if an in
teger is provided in cell 3, if it finds
anything other than integer, even if it
is a real number like 1.0 or 2.5, basic
fixture crashes. Count then counts the
number of tags matching the given Figure 26: Flow Of Count Assertion
Prasad Buddha 24
WCC Testing With FitNesse User Guide IBM
XPath and checks if the count is equal to the integer provided in cell 3. If they are not equal, count throws
an error and the assertion fails.
You should not even use a variable in cell 3 as long as you use Basic Fixture. The customized fix
ture can get a value from a variable and can compare if the value inside the variable is an integer. Example
usage is given below…
|count|/TCRMService/TxResponse//TCRMPersonBObj/TCRMPersonNameBObj|2|
The above fitnesse script line checks if the response xml file has only two TCRMPersonNameBObj
tags. That tag can be a parent tag or a child tag, count treats both the tags similar. Here is the screen-shot
of the example run of a script with count assertion.
Careful not to use any non-integer because if you do, an exception will be thrown and the test run
will crash. This problem is fixed in the customized fixture.
3.7 Exists
‘Exists’ is an assertion that makes sure that a tag
matching to the XPath exists at least once in the xml. It only
checks for the existence of the tag, but does not have anything
to do with the value inside it. Therefore, we do not have to
provide any other constant or variable. We can easily conclude
that we just need two cells to use this action. ‘Exists’ in the
first cell and the XPath of the tag in the second cell. Here is the
sample use of it.
Exception will be thrown if the XPath is invalid ac
cording to rules of XPath.
|Exists|/TCRMService/TCRMPersonBObj/TCRMPerson
NameBObj|
The assertion passes if at least one TCRMPersonName Figure 28: Flow of Exists Keyword
BObj at the path mentioned in the XPath is found, and it fails
Figure 29: Test runs of Exists assertion along with some exceptional cases
if the tag is not found. Here is an example screen-shot of running fitnesse script with exists keyword.
Prasad Buddha 25
WCC Testing With FitNesse User Guide IBM
Before going on to the next section, let us quickly look at some interesting things, all the action
keywords are case insensitive. So far, I mentioned as if the fixture is going to throw an exception if the re
quired cell is not provided, there is a little twist to that point, if any cell required is not provided, the last
cell in that row will be considered as the required cell. The execution screen-shots for Exists in Figure 29
are an example to this it.
The above example is very straightforward, check if the GivenNameOne tag is equal to ‘Mat’ or
not? It looks simple. However, how do we deal with a scenario that requires us to check if two tags are
equal. One alternative is PassThrough one tag into a variable and compare the variable with the other tag.
Well, but how do we tell FitNesse, that we are using a variable? You may arrive at the following answer…
|PassThrough|/TCRMResponse/TCRMPersonNameBObj[1]/GivenNameOne|firstName?|
|Value|/TCRMResponse/TCRMPersonNameBObj[2]/GivenNameOne|firstName?|
This problem is solved, but what if we have to check some scenario, where second GivenNameOne
tag must be equal to the Mr followed by first GivenNameOne tag? You may simply say to use something
like MrfirstName?. I guess you might have identified a problem with this kind of usage. In such a case Fit
Nesse may think that ‘MrfirstName?’ as another variable. Therefore, we need to tell the fixture where the
variable starts and where the variable ends. That is why we need to use variable placeholders. The solution
is to tell fixture where a variable starts and where a variable ends. We use ‘!!’ for that purpose, precede
and succeed the variable with !!. Therefore, this is what we have to do to use a variable…
|Value|/TCRMResponse/TCRMPersonNameBObj/GivenNameOne|!!firstName?!!|
Now let us look at another example where this variable placeholder will be useful. Say we have a
scenario, where in, we have to add a person in the database, and in the next step, we have to retrieve that
person from the database. To retrieve a person, we have to use the party id (a unique identifier party in
WCC database) that is generated by WCC while adding the party. We have to store the pass the value from
response of addPerson to the request of getPerson, without stopping the execution of test script. So how do
we change the party id in the request xml. Our variable placeholder will be useful here also. We create the
Prasad Buddha 26
WCC Testing With FitNesse User Guide IBM
variable from party id tag in the response of addPerson and use the variable placeholder for this purpose
passing it to next request xml file. Look at an example xml file below…
<TCRMService>
<RequestControl/>
<TCRMInquiry>
<InquiryType>getPerson</InquiryType>
<InquiryParam>
<tcrmParam name="partyID">!!partyID?!!</tcrmParam>
<tcrmParam name=“inquiryLevel”>3</tcrmParam>
</InquiryParam>
</TCRMInquiry>
</TCRMService>
See the line with bold characters, the variable ‘partyID?’ is enclosed in double exclamations in
side xml file, the fixture will replace ‘!!partyID?!!’ with the value in the variable ‘partyID?’, if it is de
clared before calling this xml file. The replacement will take place whenever we call the xml file in a fit
nesse script. An exception will be thrown if the variable inside the xml file is not defined by the time the
file is called in a test table.
3.10 Limitations
We hate to have limitations. When there are too many, it becomes unusable. This is exactly what
happened with this basic WccXMLFixture, you might have observed that I mentioned about saving files in
Figure 2. The image does not show the flow with basic WccXMLFixture, it is for the customized fixture.
To know what we cannot do with the basic fixture, just go through the following details.
Prasad Buddha 27
WCC Testing With FitNesse User Guide IBM
rent date. We should be able to compare dates in two tags. We should be able to check if a tag is empty or
not, we should be able to create variables conditionally.
If you have observed, PassThrough will only provide one way to create a variable from value of a
tag. However, if we have to create a variable without any tag, we cannot do that. If we want to copy value
of a variable to another variable, we cannot do that. If we want to conditionally pass-through and condi
tionally compare, we cannot do that. Adding two integers or concatenate two strings is next to impossible.
We cannot store count of tags matching to an XPath. Sometimes we may want to check if all the tags
matching to a particular XPath has same value or not, we cannot do that because that number need not be a
constant or may be large. We have to use value action 100 times, if we have 100 tags of same XPath that
we have to compare.
We cannot check if the expected string is a part of value of tag. We cannot check for the length of
characters in a string, if required. We cannot pass-through partial value of a tag. The value action is case
sensitive, so in case we have to compare the values where the case changes from input to output, we are
ahead of a wall. We cannot write comments in the middle of a test script table.
Prasad Buddha 28
WCC Testing With FitNesse User Guide IBM
Prasad Buddha 29
WCC Testing With FitNesse User Guide IBM
!|com.ibm.wcc.fitnesse.WccXMLFixture|
||iiop://127.0.0.1:2810|
|C:\FitNesse\InputXMLs\AddPerson.xml|
|Value|/TCRMService/TxResponse/TxResult/ResultCode|SUCCESS|
|PassThrough|/TCRMService//TCRMPersonNameBObj/GivenNameOne|GivenNameOne?|
|PassThrough|//TCRMPersonBObj/TCRMPersonNameBObj/LastName|LastName?|
|PassThrough|/TCRMService/TxResponse/ResponseObject/TCRMPersonBObj/PartyId|PartyId?|
!|com.ibm.wcc.fitnesse.WccXMLFixture|
||iiop://127.0.0.1:2810|
|C:\FitNesse\InputXMLs\GetPerson1.xml|
|Value|/TCRMService/TxResponse/TxResult/ResultCode|SUCCESS|
|Value|//TCRMPersonBObj/TCRMPersonNameBObj/GivenNameOne|!!GivenNameOne?!!|
|Value|//TCRMPersonBObj/TCRMPersonNameBObj/LastName|!!LastName?!!|
!|com.ibm.wcc.fitnesse.WccXMLFixture|
||iiop://127.0.0.1:2810|
|C:\FitNesse\InputXMLs\UpdatePersonName.xml|
|Value|/TCRMService/TxResponse/TxResult/ResultCode|SUCCESS|
!|com.ibm.wcc.fitnesse.WccXMLFixture|
||iiop://127.0.0.1:2810|
|C:\FitNesse\InputXMLs\GetPerson2.xml|
|Value|/TCRMService/TxResponse/TxResult/ResultCode|SUCCESS|
|Not Exists|/TCRMService/TxResponse/ResponseObject/TCRMPersonBObj/DeceasedDate|
|Exists|/TCRMService/TxResponse/ResponseObject/TCRMPersonBObj/BirthDate|
|Count|/TCRMService/TxResponse/ResponseObject/TCRMPersonBObj/TCRMPersonNameBObj|2|
If you have observed, the first three lines are same in all the four test tables, except for the file
names. The fourth line in all the test-tables has a value action that verifies if the value in the ResultCode is
‘SUCCESS’. The first table has three PassThrough actions, one each for GivenNameOne, LastName and
PartyId. Please note that the ‘?’ at the end of each variable is just a convention, it is not mandatory. If you
have observed, the PartyId PassThrough row is after the GivenNameOne and LastName variable defini
tions. If you are aware of the xml structure of response of addPerson transaction, you know that the
PartyId tag comes before the other two tags. You do not have to follow the order in which the tags appear
in the xml file.
Second table checks the value of GivenNameOne and LastName tags if they are equal to the vari
ables defined. Third table just sends the request to WCC and checks if the result code is SUCCESS. Fourth
table verifies that the response xml file does not have DeceasedDate and has BirthDate with the help of
Not Exists and Exists assertions. The last line with count assertion checks if the response has two TCRM
PersonNameBObjs.
Before we close the discussion about basic fixture, make a note of several points. You can define
same variable any number of times. However, the variable will retain the latest value passed into it. It is
not mandatory to use any variable after it is defined. You cannot use a variable in any action or request
xml until it is defined. For example, as the ‘PartyId?’ is defined in the first table, you cannot use !!
PartyId?!! in the request AddPerson.xml, because by the time fixture deals with the request, it still does not
have the response xml to define the ‘PartyId?’ variable. You can also use a variable in XPath if required
after the variable is defined (e.g. //TCRMPersonNameBObj[LastName = '!!LastName?!!']/GivenNameOne
). You can use any complex XPath as long as it is valid as per the rules defined in XPath 2.0.
Prasad Buddha 30
WCC Testing With FitNesse User Guide IBM
4.Customized Fixture
The previous chapter introduced you to the features of the fundamental fixture. The same chapter
also explained what could not be done with it. We came a long way from a point where we decided that
the fixture cannot be used for real testing to this point, where we automated nearly 4000 test cases. As I
explained you before that WccXMLFixture is a small program written in java. The fixture code used to be
mere 200 lines. It has grown to vast 4000 lines of code with all my customizations. The basic structure of
the fixture is modified in a lot many ways. As the time progresses, new challenges came up, I had to keep
on adding new functionality to solve those automation problems. At this point of time, the fixture has a lot
more functionality. We designed a very efficient way of testing xml transactions using all the new
functionality. Let us go one-step at a time from defining the types of customizations to very detailed ex
planation of all the customizations. However, this document does not tell you how to create fixtures or
how to customize WccXMLFixture. It only helps you learn all the new functionality and how to use them.
Here is a list of the modifications to the fixture…
Syntax changes
Behavioral modifications
New passthroughs
New assertions
File handlers
Miscellaneous action keywords
Variable placeholders
Predefined variables
4.1 New Syntax
To provide more functionality, not everything can be done in with the same syntax of the test
tables. So the test table is redesigned to accommodate new functionality. This new syntax is carefully de
signed in such a way that none of the existing scripts break, along with giving provision to the new func
tionality. Therefore, it is compatible with the existing scripts. Here is the new syntax for the advanced or
customized WccXMLFixture.
com.ibm.wcc.fitnesse.WccXMLFixture
WCC Instance Name WCC Provider URL
File Handler XML file name
Action Keyword XPath of the tag to be used from response XML Cell 3 Cell 4 Cell 5 Cell 6
:
:
Action Keyword XPath of the tag to be used from response XML Cell 3 Cell 4 Cell 5 Cell 6
Illustration 2: Syntax for customized fixture
Instead of just Cell 3 in the test table from fourth row as shown in Illustration 1: Syntax for Basic
WccXMLFixture, we can now use cells 3, 4, 5, 6. However, they are conditional. Number of cells required
changes from action to action. Only one action keyword requires up to cell 6. We will take a detailed look
at new action keywords later. To allow various file handling mechanisms, a new optional cell is introduced
in the third row. If you ignore the file handler cell, the xml file name cell will be the first cell. If you
provide file handler keyword and provide the xml file name in the second cell in the same row, given file
handling method will be opted. We discuss about file handlers and new action keywords in the subsequent
sections. All the cells given in Grey are optional according to the new syntax rules of test-table.
Prasad Buddha 31
WCC Testing With FitNesse User Guide IBM
Prasad Buddha 32
WCC Testing With FitNesse User Guide IBM
4.2.2) XPath validations on Request xml
As mentioned earlier the basic fixture can only do validations on response xml file, any action on
request xml file tag produces the error: Tag not found, unless that XPath accidentally matches with a tag in
response xml file. With the new fixture, you do not have to do anything new except for using the XPath
from request xml directly. Let me tell you how this functionality is implemented. The fixture does not
know anything about xml structures, it takes XPath and tries it on one of the files (either request or re
sponse). If the XPath does not match to any tag in the request file, instead of throwing an error, fixture
goes to response file for XPath validation. Therefore, we got double work to do, though it is not significant
for a single XPath validation, the number of assertions in a test case can grow to a very large number de
pending on the complexity of the test case. We have several test cases where we have more than 1000 as
sertions in many test cases. We have to follow a better approach than this trial and error approach.
For our project, in fact, for any xml project, generally the xml structures will be constant at lower
depth (root tag has a depth of zero and its children has a depth of one and so the depth increases). There
fore, all the XPath for request xml file will have a common start point. The same is the case with XPath for
response xml files. For WCC, the XPath for request will start with either /TCRMService/RequestControl,
or /TCRMService/TCRMTx, or /TCRMService/TCRMInquiry. We call these request markers, because if
the provided XPath starts with any of these, it means that the XPath belongs to request. The same logic is
used to decide whether the XPath belongs to request or response. However, hard coding the request mark
ers in code will reduce the flexibility, if we have to have some other request markers, we may not be able
to do that unless we modify the code.
Therefore, I decided to go with a properties file in which these request markers are defined. Proper
ties file is created after you run a test using the advanced WccXMLFixture for the first time. The name of
the properties file is ‘properties.xml’. The tag <RequestMarker/> will hold the request XPath portions. If
you want to add additional request markers, you just add another RequestMarker tag with the request
marking XPath portion. If your project has request xml structure that always starts with /A/B/C then you
add another RequestMarker tag as below…
<RequestMarker>/A/B/C</RequestMarker>
RequestMarker XPath is case insensitive. So, it will not be a problem, even if you provide /a/b/c.
Our project has two different applications with which FitNesse interacts, WCC and WQS. The request
markers for both WQS and WCC can be found in the properties.xml snippet in section Properties File.
Prasad Buddha 33
WCC Testing With FitNesse User Guide IBM
Figure 36: Once an xml file hyperlink is clicked, it will be opened in browser window
Prasad Buddha 34
WCC Testing With FitNesse User Guide IBM
<!-- Request Markers let FitNesse fixture recognize if the XPath is from Request xml file or
Response xml file. All the Request XPath should have one of the Request Marker. -->
<RequestMarker>/TCRMService/RequestControl</RequestMarker>
<RequestMarker>/TCRMService/TCRMTx</RequestMarker>
<RequestMarker>/TCRMService/TCRMInquiry</RequestMarker>
<RequestMarker>/soap:addressStandardization</RequestMarker>
<RequestMarker>/soap:addressValidation</RequestMarker>
<RequestMarker>/soap:nameStandardization</RequestMarker>
<!-- The following parameters are being used for Service Time Logging while executing.
They can be used for performance testing. To Enable SeriveTime logging and Throwing error
if service time is crossed than the threshold-->
<ResponseTimeTagXPath>/TCRMService/ResponseControl/ServiceTime</ResponseTimeTagX
Path>
<ResponseTimeThreshold>5000</ResponseTimeThreshold>
<PerformanceTestEnabled>N</PerformanceTestEnabled>
</WccFitNesseProperties>
There are several RequestMarker tags some of them are for WQS testing where we will be sending
the SOAP requests to WQS. The ResponseMarker tags are initially used for differentiating between re
quest XPath and response XPath, but later I found that using RequestMarker would be more useful than
ResponseMarker. There can be some scenarios where the XPath does not contain both the markers
(e.g. //GivenNameOne) that can be from request as well as response. In such an ambiguous situation, the
fixture assumes that this XPath belongs to response. To make this assumption easy in code the decision is
taken to use RequestMarker instead of ResponseMarker.
Prasad Buddha 35
WCC Testing With FitNesse User Guide IBM
The other tag in the properties file is DateFormat. This can be changed if you want any other date
format for some action keywords like Is Before, Is After etc., The date format may change from imple
mentation to implementation in WCC as WCC provides flexibility to change the date format. The default
format given in the properties file is yyyy-MM-dd because this is the date format, we use in our project.
You can give any format like yyyy MMM dd hh:mm:ss. Later we will discuss about the action keywords,
which make use of this DateFormat.
The Version tag is to keep track of the version of the properties file. If there is an updated version
of WccXMLFixture, the properties file is updated according to the new code. When you run a test on new
WccXMLFixture, it finds out if the properties file is of the old version. If the version is less than the cur
rent version it replaces the properties file with the new file as defined in the WccXMLFixture code.
UniqueNumber is the tag that contains an integer. It increments every time a test is run, or whenever
we reset the predefined variables in the script. Resetting the predefined variables is something that we are
going to deal a bit later in this document. This integer can grow to any large number starting from one if you
keep on running the tests. You can change the value inside UniqueNumber tag and the value will be
incremented from that number. Using this UniqueNumber variable will be explained in section ?
UniqueNumber?.
Figure 38: Whenever service time of a service time Figure 37: Service Time will be displayed when Per
crosses the threshold limit, it will be highlighted formance Testing is enabled
This is the current version of properties file. I am going to add new features to the fixture, for
which, I may need to add some more tags to the properties file. One final and funny thing about proper
ties.xml is, it is designed in such a way that the order of xml tags does not matter. You can modify order of
the tags inside properties file, but do not change the content in the tags unless you know what you are do
ing.
Prasad Buddha 36
WCC Testing With FitNesse User Guide IBM
4.2.6) Action Keyword behavioral changes
Several action keywords are updated with new code such that they behave in a slightly different
way. PassThrough, Value, Exists and Not Exists are not modified much except to also consider XPath
from a request. The major change is with Count. Observe the following Script and its output and see if you
can find out the reason for failure.
This instantly shows you where the problem is without crashing. Another advancement in count ac
tion is, you can also use variables if required. You can use the variable as you have used with value asser
tion. Just make sure that there is an integer in that variable or else an exception is thrown. Of course, that
exception will be caught by the new fixture before the test can crash.
Prasad Buddha 37
WCC Testing With FitNesse User Guide IBM
4.3.1) ByPass
Using any file handler is very simple. It must be used as shown below…
|ByPass|C:\Xmls\addPerson.xml|
The concept of ByPass is also very easy, whenever you mention ByPass file handler before a file
name, fixture avoids sending that request to WCC. It uses that file just for doing actions mentioned from
the fourth line onwards. The same file is considered as a request and response as well.
Prasad Buddha 38
WCC Testing With FitNesse User Guide IBM
once to WCC, and we can call response xml multiple times using this ByPass file handler. This saves us
from repeatedly sending the same request to WCC to get the response.
4.3.2) Pass
Pass works just as default file handler, it sends request file to WCC normally look at the Figure 2
Interactions between User, FitNesse, Fixture and WCC to look at the way default file handler works. It
normally sends the request to WCC and receives the response. Well, why do we need one more thing that
does exactly same as an existing thing?
Let us assume a scenario where we have 100 test cases, and we have a test step in all of them, like
adding a party, that can be executed only once in WCC server and the test cases may have to be executed
more than once. For example, say we can add a party in each test case only once and our test cases work if
that party is added to the database once. We cannot add the party for the second time even if we run the
test case for second time. How do we deal with such a scenario? One solution is saving all the steps that
must be executed only once in a separate suite and all other steps in another suite. This works as long as
the adding the party for each test case is the first step, but what if the party has to be added as part of
second test table? This where a combination of Pass, ByPass and page-variables come to use. Did you get
how to do it?
Instead of hard coding Pass or ByPass, we use a fitnesse page-variable, in all our test tables, which
have to be run only once, as below.
|${ByPassOrPass}|C:\XMLs\addPerson.xml|
We have to define that page-variable in the parent suite page for all the test cases with either By
Pass or Pass. To run all the steps for the first time, we have to provide value Pass in the variable. Before
running the same test cases again, change the value in the variable to ‘ByPass’. Now from second time on
wards, addPerson will be by-passed and party will not be added again. The reason for doing this is, we can
modify the contents of a cell using these variables, but we cannot add new cells. ByPass can be made into
Pass and Pass can be made into ByPass, but default file handler cannot be converted to other file handler,
as there is no cell for default file handler.
4.3.3) Force
Observe Figure 44. If
you read the error message, it
says that variable ‘partyID?’
cannot be found from previous
test run. This PassThrough
problem will come when an un
defined variable is used in an
xml file for a default file hand
Figure 44: PassThrough exception is thrown when an undefined variable is used
ler. This may look like a valid in the xml file
scenario because when some
variable is not filled in request
xml, there is a high probability that WCC may throw error, because if party id is mandatory for transaction
like getPerson.
Nevertheless, it is not true all the times. There will be some optional fields as GivenNameTwo in
updatePersonName transaction. In such a scenario, it is not mandatory to throw this exception. Anyway,
the fixture does not always have to worry about the missing variables because WCC will obviously throw
error, if it is a mandatory field. So this Force file handler is introduced to handle such optional variables,
which may not be necessary to be defined.
Prasad Buddha 39
WCC Testing With FitNesse User Guide IBM
This is what Force does, whenever it finds a variable, which is not previously defined, it replaces
that variable with an empty string.
<TCRMService>
<TCRMInquiry>
<InquiryType>getPerson</InquiryType>
<InquiryParam>
<tcrmParam name=“partyID”>!!partyID?!!</tcrmParam>
<tcrmParam name=“inquiryLevel”>3</tcrmParam>
</InquiryParam>
</TCRMInquiry>
</TCRMService>
The above xml be converted as below when the variable ‘partyID?’ is not defined before. The re
quest shown below will be sent to WCC, of course, this xml will result into an error from WCC, party-id is
mandatory for getPerson transaction.
<TCRMService>
<TCRMInquiry>
<InquiryType>getPerson</InquiryType>
<InquiryParam>
<tcrmParam name=“partyID”></tcrmParam>
<tcrmParam name=“inquiryLevel”>3</tcrmParam>
</InquiryParam>
</TCRMInquiry>
</TCRMService>
4.3.4) Optional
As discussed in the previous
section, the force will push the xml to
WCC at any cost, by replacing the un
defined variables with an empty string.
However, ‘Optional’ file handler has
two different types of behaviors. It be
haves like a ByPass whenever a vari
able is not found in the xml file and
works like Pass when all the variables
used in a request are found. Figure 45: Optional just working as Pass as the variable partyID? is
defined
See the screen shots provided,
the first picture is a scenario where the
variable is defined. Optional file handler is used on getPerson.xml in which the variable ‘partyID?’ is used.
The variable ‘partyID?’ is defined in the first test table. Therefore, the optional keyword just behaved as
Pass and ResultCode exists in the response of getPerson transaction.
Prasad Buddha 40
WCC Testing With FitNesse User Guide IBM
If you observe the second pic
ture, the same script is run, however
with a small modification. Instead of
the variable name ‘partyID?’ the vari
able is defined as ‘CONT_ID?’. How
ever, the request of getPerson is not
modified and it still has !!partyID?!!.
Now, the Optional file handler behaved
as ByPass and did not send the getPer
son.xml to WCC. That is the reason
why the ResultCode is not found. If Figure 46: Optional behaving as ByPass because partyID? variable
you remember, with ByPass the request used in getPerson is not found
itself is considered as the response. As
the request does not have the tag ResultCode, the Exists assertion failed with an error: Tag Not Found.
Here is the syntax of Optional file handler…
|Optional|C:\XMLs\addPerson.xml|
4.3.5) No File
Sometimes we want to create tables without any xml file. It may be for performing some miscel
laneous operations like add, copy, variable assignments etc., without any interference with xml tags. Be
low is the example of ‘No File’ file handler.
Forget about what is CCopy and others, all you have to worry about is that there is no file name
mentioned in the third row and the word ‘no file’ is mentioned instead.
Prasad Buddha 41
WCC Testing With FitNesse User Guide IBM
4.4.1) ?UniqueKey?
'?UniqueKey?' is a predefined variable which is an alphanumeric string. This will be unique every
time we run a new test or new suite. However, when we run several test cases as a suite, the value in the
unique key variable will be same for all the tests. The fixture is designed in such a way that it creates the
variable when we click the test button or suite button.
You can use this variable like any other variable you created using passthrough actions. Either in
xml files or in a test script, you have to use it inside variable placeholders. How does it create a unique
string every time? To be precise, it does not create a new unique string every time, however, it creates a
new string for every one second. The algorithm used for generating a unique string is as follows. The fix
ture takes start date as July 22nd 2008 and counts number of seconds that paused until now. However, we
cannot use that number as it is, because it will be very big number, we need around 5-8 characters or else it
may cause problems because of its length. The fixture then converts that large number is a 32 base number
from decimal number. This converts that large number into a 6-character string as of now. The length is
going to be six until around 2040, so we do not have to worry change in its length. The value coming out
of this unique key variable is similar to 1A89B0.
4.4.2) ?UniqueNumber?
We have to use ‘?UniqueNumber?’ variable if we want to place a unique number in the xml file
while executing. It generates a minimum of six digits. It increases each time we execute a test case or test
suite. So, if there are ten test cases in a test suite and when we execute all the test cases as suite, the value
in the variable ‘?UniqueNumber?’ is going to be same for all ten test cases. If you want to change the
value in this variable, you will have to use Reset All. The convention we are following in our assignment
is, we have a ‘Reset All’ action at the end of each test script.
Generating a unique number is tough. Unlike UniqueKey (which is alphanumeric), unique number
variable is a numeric value. Therefore, there are only 10 digits, hence we cannot generate it using the time
difference. Because if we do so, just for ten days the number will be 864000 and in 100 days it will become
a 7 digit number. In 3 years, the length will be eight. You expect six digits in a tag and use this variable, but
it will become a seven-digit number in 100 days, which may cause unexpected failures.Therefore, it is not
safe to depend on it.
I decided to use a different approach that is using the properties file for this. If you remember, the
tag UniqueNumber holds an integer, whenever a test is initiated, the number from the tag is taken and
Prasad Buddha 42
WCC Testing With FitNesse User Guide IBM
stored in the variable '?UniqueNumber?' and the integer in the UniqueNumber tag of properties file is in
cremented. Therefore, we can guarantee the uniqueness of the value inside the variable ?UniqueNumber?.
However, even with this algorithm, length changes quickly. If we assume that we run a test every
10 seconds, it will take 3 years for us to 7 digits, but how are going to handle length of the UniqueNumber
initially? It adds zeroes in the beginning of the number until six digits. So it starts with filling 000001 in
place of !!?UniqueNumber?!!, and keeps on increasing. To reset the value, you can simply change the
value in properties file (remember the UniqueNumber tag?) and the unique numbers will start from the
number you provide.
4.4.4) ?CreateBackup?
‘?CreateBackup?’ is not just a regular variable. This is a behavioral modifier of the fixture. It is a
property that you can change. It can have two values either ‘yes’ or ‘no’. If the value inside this variable is
‘yes’, fixture creates backup copies of a request and a response xml files in old folder. If it has ‘no’ in it,
existing request and response files will be overwritten and the backup copies are not stored. Refer to the
section Storing request and response xml files about backing up of files while executing tests. You can
change the variable like any other variable using copy or some other means, which are explained in sec
tions New Passthroughs and Miscellaneous Key words. You can also change the value in the middle of a
test script.
Prasad Buddha 43
WCC Testing With FitNesse User Guide IBM
4.5.1) ##
This is a new variable placeholder that converts the value of the variable into uppercase and then
replaces the variable with the converted value. Here is the example screenshot of test runs with ## variable
placeholder.
Prasad Buddha 44
WCC Testing With FitNesse User Guide IBM
Part PassThrough XPath of the tag to be used Variable Name Start Point End Point Length
Illustration 3: Syntax of Part PassThrough action keyword
You know the first three cells. The fourth cell is for mentioning the starting character in the string
the index starts from one not from zero. The fifth cell is for the endpoint and the sixth cell is for length. To
pinpoint a portion of a string precisely, you have two ways to do that, mention either start point to end
point or endpoint and length. When a start point is provided, the fixture ignores the length. Otherwise,
length becomes mandatory.
|Part PassThrough|//TCRMPersonBObj/TCRMPersonNameBObj/GivenNameOne|name?|3|5|
The previous syntax line will extract from third character to fifth character from the Given
NameOne tag. Isn’t it simple? Try to answer this. How will you tell fixture to extract from 3rd character to
the last character? It is impossible to do it with whatever I explained you so far, because you will never
know what the length of the string is (at least not always). So, little more functionality is added to the Part
PassThrough action. The way to do it is, you give any number larger than the number of characters in the
Prasad Buddha 45
WCC Testing With FitNesse User Guide IBM
string like 999999. Then the Part PassThrough will reduce the given endpoint to the real endpoint of the
string(length of the string). This is how it looks like in the fitnesse script…
|Part PassThrough|//TCRMPersonBObj/TCRMPersonNameBObj/GivenNameOne|name?|3|99999|
You may get a doubt why the length parameter is provided. Can’t we just tell the start point and en
dpoint to extract portion of the string? You can, but how are you going to tell a fixture to pick last four
characters when we do not know the number of characters in the string. This length parameter is provided
to solve that problem. We use end-length pattern of Part PassThrough to pick last n number of characters
of a string. Let us look at an example of end-length pattern. In this end-length pattern, we mention the end
point of the portion you want to extract from the string and number of characters you want to extract. If
you want to extract last four characters of a string of length10 characters, you should provide endpoint as
10 and length as four. The syntax is as below…
|Part PassThrough|//TCRMPersonBObj/TCRMPersonNameBObj/GivenNameOne|name?||10|4|
Then how to pick the last four characters of a string, when the number of characters in the string is
unknown? The answer is similar, instead of providing the actual endpoint, we will provide something like
99999. Here is the answer…
|Part PassThrough|//TCRMPersonBObj/TCRMPersonNameBObj/GivenNameOne|name?||99999|4|
Make a note of an empty cell provided instead of start point, if you do not provide that empty cell
then 99999 will be the fourth cell and will be considered as a start point and 4 will be considered as end
point. If you provide a start point, which is greater than endpoint, this will reset the start point to make it
equal to the endpoint. If length is greater than endpoint, it will also be reduced to endpoint. Here is the
screen-shot of Part PassThrough run.
Figure 50: Test execution with various combinations of start, end and lengths
In the above example, to make it easy to understand, I provided 123456789 in the requesterName
tag. If the tag is not found or if more than one tag is found, the Part PassThrough will throw an error.
Prasad Buddha 46
WCC Testing With FitNesse User Guide IBM
4.6.3) CPassThrough
I should say this is one of the three most significant changes to the fixture. It revolutionized the
way we write automation scripts. The other two significant changes are ByPass and CValue IgnoreCase.
These three features drastically reduced the time needed to create automation scripts and debug them.
Even though the concept of CPassThrough is very simple, but when we used it along with CValue Ignore
Case it is a wonder. It took me nearly a week to design these features and develop them in the fixture. We
saved nearly two person months in a span of one month i.e., we would have nearly spent three months to
do the same work if we have to do it without CPassThrough, CValue IgnoreCase and ByPass. Half of the
time saved by them is directly saved because of these features and the remaining half of the time saved by
them indirectly. I mean, they paved a way to take a new
approach called Re-usability. It saved us hell a lot of
time. The reasons why I could come up with this new ap
proach are simply the above three mentioned. Without
these three, there is no concept of Re-usability.
The expanded form of CPassThrough is Condi
tional PassThrough. It conditionally decides whether to
create a variable or not. The difference between
PassThrough and CPassThrough is simple, if no tag is
found for CPassThrough, it does not throw any error it
simply ignores that row in the test table. It also ignores
the row in the test table if no value is found in the tag.
However, CPassThrough still requires a valid
XPath and that should match to one and only one tag. If
the XPath is invalid, it must be corrected. If more than
one tag is found for the XPath, fixture cannot decide,
which tag to store the value from. You may get a doubt
why that scenario can not be ignored. Let me explain you
the whole theory behind creating CPassThrough and
CValue IgnoreCase. When both are used one a same tag
in a script, if the tag does not have a value before it most
probably won’t have the value afterward, so if variable is
not defined before it won’t the CValue IgnoreCase ex
pects that tag to be empty. If the variable is defined,
CValue IgnoreCase expects that the tag to have a same
value. So, if more than one tag is found for the XPath,
CPassThrough throws error because if it just ignores that
line and the CValue IgnoreCase does not find the variable
and expects the tag to be empty. However, we have the
value in one or more tags.
Let me rephrase the above scenario in practical
terms, if the person has GivenNameTwo while adding the Figure 51: Flow of CPassThrough
party, the getPerson will also have that tag. If the person
is added without GivenNameTwo in the name, the getPerson will also do not have the tag. However, if
there are more than one GivenNameTwo tags, the getPerson will also have values in GivenNameTwo tags,
so the right thing to do is to throw an error instead of just ignoring the action keyword. Here is the syntax
of CPassThrough…
|CPassThrough|//TCRMPersonBObj/TCRMPersonNameBObj/GivenNameOne|name?|
The examples for passed, failed and ignored scenarios are provided in Figure 52.
Prasad Buddha 47
WCC Testing With FitNesse User Guide IBM
Observe the third and fourth CPassThrough in the above screen-shot. If you observe third cells in
both the rows, they are in gray color, it is a way of showing that the rows are just ignored without any er
ror. If you observe the messages in the second cells of both the rows, you will understand why each
CPassThrough failed. First message is Tag Not Found for XPath and the second message is No Value in
side tag. Do they need more explanations? I suppose not.
Cpart PassThrough XPath of the tag to be used Variable Name Start Point End Point Length
Illustration 4: Syntax of CPart PassThrough action keyword; Exactly like Part PassThrough
Prasad Buddha 48
WCC Testing With FitNesse User Guide IBM
4.6.5) CPassThrough Or Copy
This is slightly complicated than
CPassThrough, in fact, it is an extension to
CPassThrough. There will be many scen
arios where some default values will be as
signed when we do not provide the tag or
leave the tag blank. How do we deal with
such a scenario? ‘CPassThrough Or
Copy’ solves one special scenario of this
problem. We have other ways to solve the
remaining problems. Let us look at what
CPassThrough Or Copy does…
It checks if a unique tag is found for
XPath, and if it does, it will create the vari
able and copy the value from the tag into
the variable. However, if it does not find a
tag, it tries to fetch the value from fourth
cell, if a variable is found in cell 4, it
checks if the variable is already defined. If
the variable is not found, the action line is
ignored and if the variable is found, it re
places the variable with the value in the
variable and copies that final string into a
newly created variable.
However, if the tag is empty, then it
just ignores the action without considering
cell 4. If more than one tag is found, it is an
error.
Prasad Buddha 49
WCC Testing With FitNesse User Guide IBM
Fourth cell can be a variable or a constant or combination of both. It is same as third cell in value
assertion. The variable has to be enclosed in variable placeholders as usual. Here is the syntax of
CPassThrough Or Copy…
CpassThrough Or Copy XPath of the tag to be used Variable Name String With Or Without Variable
Illustration 5: Syntax for CPassThrough Or Copy
This action is widely used in testing update services. Let us say you are updating the name of a per
son who has a name with the elements GivenNameOne, GivenNameTwo, LastName. If you try to update
the name, and if you provide an empty tag for GivenNameTwo in updatePersonName request xml file,
then the GivenNameTwo will be deleted from the person’s name. However, if you do not provide the tag
in the request, then the existing value for the GivenNameTwo will be persisted.
This is the exact reason for which CPassThrough or Copy is designed. We mention the XPath of
the tag, which we want to store the value of, and provide a variable name and in the fourth cell, we give
the variable defined for the value of same tag previous variable. So, if the request xml has no value in that
tag, the value in the old variable will be ignored, that is what WCC does, it deletes the value in the tag. If
tag is not found, the old variable value will be copied into the new variable. WCC retains the value of that
tag if there is any before update transaction.
Prasad Buddha 50
WCC Testing With FitNesse User Guide IBM
4.7.2) Contains
So far, you have seen comparison of entire value inside a tag with another tag. ‘Contains’ checks
if the expected value (value in cell3) is inside the actual value (value of the tag). It also ignores the case.
There is no difference between flow of value assertion (Figure 24) and contains assertion except for the
last step, where it also passes if the expected value is inside the actual value (value inside tag). Syntax of
Contains assertion is similar to Value assertion.
|Contains|/TCRMService/TxResponse/*/TCRMPersonNameBObj/GivenNameTwo|##two?##|
4.7.3) Is Empty
‘Is Empty’ assertion checks if a tag exists, but is empty.
If there is a value in the tag, the assertion fails. The assertion also
fails when the tag is not found or the XPath is invalid.
Prasad Buddha 51
WCC Testing With FitNesse User Guide IBM
4.7.5) Length
Length Assertion checks if the number of characters in a tag is as expected. Here is the syntax for
Length assertion in Illustration 6…
This assertion can be useful if there Length XPath Number Of Characters
is a scenario where in WCC have to auto Illustration 6: Syntax of Length Assertion
generate some keys of specific
number of digits. Here are test
runs of Length assertion.
If you look at the last
assertion, it still needs more
clarity. For many errors, it
only says Problem with XPath.
It throws the same error mes
sage even for an XPath, which
matches to more than one tag.
I shall be fixing it in later ver
sion of the fixture. Figure 59: Test runs of Length assertion
4.7.6) Is PastDate
The assertions we looked at so far considers
the value in the tag as either a string or an integer.
However, that may not be enough all the times.
Sometimes, we will have to work with dates. Now
let us discuss about some date assertions. First one
of this kind is Is PastDate. This assertion checks if
the tag has a past date. It compares against the cur
rent system date. It will only check against dates, it
will not consider the time on which the assertion is
tested.
If the tag has a value ‘2009-10-10 00:00:00’,
and if we tested when the time is ‘2009-10-10
13:45:00’, assertion fails. It is because the date in
the tag is same as the current date.
I have created a dummy xml file with differ
ent dates so that testing will be easy. Observe the
screen shot in Figure 60 to understand how the Is
PastDate assertion works. That dummy xml contains Figure 60: Test runs of Is PastDate
several tags with different dates. The PastDate tag
has a past date in it, Future date has a future date,
RepeatedDate tag is repeated more than once etc.,
As I said Is PastDate compares value inside a tag with current system date, so we do not have to
provide any other dates we compare with. So, Is PastDate only requires two cells, Action keyword cell and
XPath cell.
4.7.7) Is FutureDate
‘Is FutureDate’ also works like ‘Is PastDate’ except that it checks if the tag has a future date.
Look at the Figure 64 to see how it works. The error messages also changed for Is future Date assertion.
Prasad Buddha 52
WCC Testing With FitNesse User Guide IBM
Figure 61: Test runs of Is PastDate Figure 62: Test runs of Is PastDate
4.7.8) Is Today
‘Is Today’ is an assertion that checks if the tag has a current system date. This assertion fails if the
tag does not have the current system date. Look at the Figure 63 for test run examples.
Prasad Buddha 53
WCC Testing With FitNesse User Guide IBM
4.7.9) Is Before
The previous three assertions work with
current system date and the tag. Sometimes we
may have to compare a tag with another tag. In
such a scenario, ‘Is Before’ and the next two asser
tions do the trick. Is Before checks the date inside a
tag with a variable or constant. It asserts that the
date inside the tag is before the date provided in
Cell 3.
The cell 3 can be either a variable or a constant. Here is the example usage
|Is Before|/DateTestXML/PastDate|2009-06-08|
If you remember, we have discussed about DateFormat tag in properties.xml file. Is Before, Is
After, Is SameDate will use the date format provided in that tag. So, if your implementation of WCC uses
Prasad Buddha 54
WCC Testing With FitNesse User Guide IBM
any date format other than yyyy-MM-dd, you have to mention that date format in the tag DateFormat in
properties.xml.
4.7.10) Is After
‘Is After’ action checks if the date inside a tag is after the date provided in the cell 3. There is no
difference between Is Before and Is After as long as the syntax is considered, Screenshots of test runs for
Is After assertion is in Figure 67.
4.7.11) Is SameDate
‘Is SameDate’ checks if the value inside a tag is same date as the provided in the cell 3. Here are
the test runs of Is SameDate assertion. Everything else is same as the Is Before and Is After assertions.
Prasad Buddha 55
WCC Testing With FitNesse User Guide IBM
4.7.12) CValue
Prasad Buddha 56
WCC Testing With FitNesse User Guide IBM
This is an advanced version of Value assertion, CValue means Conditional Value. The same way
CPassThrough decides whether to ignore the assertion, or pass or fail the assertion, CValue conditionally
decides.
Observe the flow chart in Figure 69. Do not worry. It looks big and complex, but it is not that
tough to understand. The concept is simple, if a variable is defined before, it means that there is a value in
side tag while defining it, so the tag must also have the same value now. If the tag is missing or value in
side tag blank or is different while comparing, there is something wrong because the variable is defined
before. If a variable is not defined, either the value in the tag is empty while defining the variable or the
tag is missing while using CPassThrough on that tag. So, either there must be no tag or the tag must be
blank even while comparing. If a non-empty tag is found while comparing, where did that value come
from? There must be something wrong. If variable and tag are not found that is OK, just ignore that. To
achieve this effect, we try to use CPassThrough to define the variables, on which we want to use CValue.
If more than one tag is found at any point of time, it is an error. There must only one tag found
when the variable used in cell 3 is already defined or else fixture cannot decide on which tag to work with,
so this one is also an error. That is it. The whole logic of the entire flowchart is in Figure 69.
Figure 70: All tags present with PassThrough and Value assertions
To get maximum benefit out of it, you should use CValue along with CPassThrough. I meant to
create the variable using CPassThrough and compare them with tags using CValue. You can also define
Prasad Buddha 57
WCC Testing With FitNesse User Guide IBM
the same variable with PassThrough and compare it with CValue. Hmm, you may ask me how the combin
ation of CPassThrough and CValue is going to be useful. Let us look at an example and compare it with
PassThrough and Value, then you will find an obvious difference. Let us assume that there is a person be
ing added to the WCC, and we have to compare his name from addPerson request to getPerson response
xml. Here is how you write a fitnesse script using a PassThrough and Value.
The previous screen-shot may be giving you a false sense of security that everything went right,
and it is perfect. Yes, you are right everything went right, but it is not perfect. What if tomorrow the ad
Figure 71: Test run of PassThrough and Value combination after removing tags
dPerson xml is modified because of some reason? Let us say GivenNameThree tag is made empty and
GivenNameFour is deleted. See the screen-shot of another test run after making the mentioned changes in
Figure 71.
Oops, the script has broken. Is there anything wrong with the way addPerson and getPerson work
ing? The answer is No. This is what we do not want from any automation script, we do not want attention
when we do not have anything wrong. The GivenNameThree and GivenNameFour are not added while
adding the party, so there is nothing wrong, even if we ignore them while comparing. So, moral of the
story is that if you want to modify xml file, you should also check if your fitnesse script is broken, and if it
Prasad Buddha 58
WCC Testing With FitNesse User Guide IBM
did, you should modify the script also. You cannot use the same script for some other test cases where
GivenNameTwo is also missing.
Let us use CValue instead of Value. Look at the Figure 72, for the screen-shot with the Value re
placed with CValue. As we did not have the values while adding the party, PassThrough did not create the
variables. As the variables used in Cell 3 are not defined by PassThrough in first test table, CValue
Figure 72: Using CValue didn't completely fix that problem; PassThrough still creates a problem
checked if any tags with the XPath provided in cell 2 are found as the response of getPerson does not have
any tags without values, the CValue simple ignored that action row in the test table. You can see the mes
sages that variable not found and tag not found for XPath the same rows.
However, as you can clearly see from the Figure 72, the problem is not completely fixed. Even
though things went right in getPerson test table, not everything looks right in test table 1. PassThrough
throws an error whenever you want to PassThrough an empty or missing tag. So, we cannot use
PassThrough when the xml file is tend to change. The other alternative we have is CPassThrough.
Observe Figure 73 to see how CPassThrough and CValue’s combination have adjusted itself to ig
nore when some tags are missing. Observe test run examples of CValue. The first example is straight.
Second CValue failed because there is a value in GivenNameTwo tag in request (I have used same request
xml and same pass through actions as used in Figure 73 and Figure 72) but the variable ‘undefVariable?’ is
Prasad Buddha 59
WCC Testing With FitNesse User Guide IBM
never defined before. As a result, it failed. The last two assertions failed because more than one tag is
found for comparison. This is it, did you sense the flexibility you got while using CPassThrough and
CValue. This is why CPassThrough and CValue are one of the best features, I added to the fixture.
4.7.14) CContains
Do you remember what ‘Contains’ does? It just checks the same way but conditionally as CValue
IgnoreCase does. Here are the test run examples of CContains.
Prasad Buddha 60
WCC Testing With FitNesse User Guide IBM
Prasad Buddha 61
WCC Testing With FitNesse User Guide IBM
Figure 77: Test run of All CValue IgnoreCase with an XPath matching more than one tag
Observe last two cells in All CValue IgnoreCase test run, it is saying 12345678901 !=
12345678903 in the last but one line and all the rows above it said all those tags match with the value
provided in cell 3.
If we use a variable in cell three, the variable will be replaced with its value as usual, and comparison will be
done with all the tags as shown in Figure 78. If the variable is not found, but values found in the tags
matching to that XPath, it is an error as in Figure 79.
Prasad Buddha 62
WCC Testing With FitNesse User Guide IBM
The conditional failures are also same as other conditional assertions, does not deserve any separ
ate mention over here again.
4.8.1) Copy
Copy acts like a PassThrough but there will not be any need for a tag. We can create a variable us
ing a constant or a variable enclosed in variable placeholder. It simply copies a constant or value inside a
variable into a new variable. Once a variable is created, there will not be any difference between the vari
able created by it and the variables created by PassThrough keywords. Look at the Figure 81 to find out
how to create a variable using copy.
Prasad Buddha 63
WCC Testing With FitNesse User Guide IBM
4.8.2) CCopy
CCopy is a conditional action. If we do not want the error to be thrown if any variable used in cell
2 is not defined beforehand, just ignore that line, we use Conditional Copy in short CCopy. Nothing much
is there to explain, here is the screen-shot of CCopy execution.
Prasad Buddha 64
WCC Testing With FitNesse User Guide IBM
4.8.3) Add
This is another miscellaneous action keyword
that actually adds two integers or two strings and
stores them in a new variable. However, if you acci
dentally give a string in any of the cells in which you
have to give integers, both will be treated as strings. If
both are integers they will be added, if they are
strings, they will be concatenated.
So, in total, we need four cells for Add
keyword. Syntax of Add action keyword is provided
in Illustration 7.
You can provide anything in cell 2 and cell 3.
All the variables will be replaced with their values if
the variables are provided inside variable placehold
ers. If the final values in both the cells are integers
then an integer addition will take place. If one of them
is string or a real number with some decimal places,
then both will be treated as string and will be concat
enated.
Refer Figure 84 for examples of test runs of
add. You can clearly see when Integer addition oc
curred and when string concatenation occurred. If we
miss any cell, it will throw an error. Figure 84: Test runs of Add Keyword
Prasad Buddha 65
WCC Testing With FitNesse User Guide IBM
false. We have to provide the name of
the variable in the third cell. Action
Lines between If and EndIf can be
normal rows as in a test table.
Now, here is the syntax of If
Variable Exists … EndIf. The first cell
of the first row of If … EndIf block
should be ‘If’ as any other action
keyword. The second cell in the first
row is the action keyword, in this case,
it should be Variable Exists. The third
cell is for the name of the variable,
which we should check if it is defined Figure 85: Test runs of If Variable Exists ... EndIf
or not. From the second line of If …
EndIf block, the action lines and to mention the end of the conditional block you have to provide EndIf.
Look at these examples in Figure 85. The wiki script for the screen-shot is also provided.
|${WCCInputDirBase}Samples\addPerson.xml|
|Copy|123|var?|
|If|Variable Exists|var?|
|Exists|/TCRMService/TxResponse/*/*/PartyId|partyID?|
|Value|/TCRMService/TxResponse//TCRMPersonNameBObj/GivenNameOne|Indiana|
|Value|/TCRMService/TxResponse//TCRMPersonNameBObj/GivenNameTwo|Ind|
|EndIf|
|If|Variable Exists|undefinedVar?|
|Value|/TCRMService/TxResponse//TCRMPersonNameBObj/GivenNameOne|Indiana|
|Value|/TCRMService/TxResponse//TCRMPersonNameBObj/GivenNameTwo|Ind|
|EndIf|
There are two If blocks in this script. First block is with a defined variable. Observe that the action
lines are run as the variable ‘var?’ is defined. They behave normally as ever. Observe that second assertion
failed because. If you observe the second If Variable Exists … EndIf block, you can see that the variable
‘undefinedVar?’ is not defined before and so the action lines in that conditional block are skipped.
Prasad Buddha 66
WCC Testing With FitNesse User Guide IBM
4.8.6) Display Count
Display Count displays the number of tags match
ing the XPath. Display Count also throws assertions. Check
Figure 87. Figure 87: Test runs of Display Count
4.8.7) Exception
This simply throws an exception to alert of
something the tester wants to be alerted. A comment
Figure 88: Test runs of Exception and Remind
can be added to the Exception. Check Figure 88.
4.8.8) Remind
Same as exception, no difference at all, except for the action keyword. Check Figure 88.
4.8.9) #
# is for providing com
ments in the middle of a test table.
The fixture simply ignores the
line in which the action keyword
in #. The Cell will remain Grey
when we run the test. Comment
Figure 89: Observe that the line above exists is ignored without any action
can have any number of cells
based on need.
4.8.10) Reset
So far, we have seen different action
keywords that create or use a variable. Reset
and Reset All are different from everything
else. They are terminators. Reset will
remove all the variables that are defined
using PassThrough action keywords and
Miscellaneous Keywords. If there is any
predefined variable, they will not be
disturbed at all.
The syntax is simply a one-cell row
with reset in the cell. Observe the screen-
shot first.
If you observe the value in the vari
able '?UniqueKey?' is 1M9NGA, and is
copied into a variable ‘var?’. If … EndIf
does not skip the Remind action line as the
variable ‘var?’ is defined. However, if you
observe the reset keyword, it says ‘Variables
Map is Reset’. If you observe the second If Figure 90: Test runs of reset
block skipped Remind action line, because
the ‘var?’ is destroyed. If you check the second copy line ?UniqueKey? Still has the same 1M9NGA. As
evident from the Figure 90 Reset will not reset predefined variables. We generally insert Reset at the end
of a script.
Prasad Buddha 67
WCC Testing With FitNesse User Guide IBM
4.8.11) Reset All
The Reset All is a kind of extension to
Reset. It resets the entire variable set and re
sets the predefined variables. Observe that
variable ‘?UniqueKey?’ is also changed after
reset all, the initial value in Unique Key is
1MAFQ0 where as the value after reset all is
1MAFQ4. A new unique key will be gener
ated with the same logic as discussed. Unique
number variable will be incremented by one.
Prasad Buddha 68
WCC Testing With FitNesse User Guide IBM
Figure 92: By mixing the assertions of basic fixture and new fixture can yield best results
Figure 93: Difference between old WccXMLFixture and current WccXMLFixture because of custom
izations
Prasad Buddha 69
WCC Testing With FitNesse User Guide IBM
All these new actions opened the doors for testing complicated requirements. Even some actions
are taken from existing fixture, some of them are updated to handle some of the exceptions that used to
crash the test run without letting us test anymore. Most of such crashes are caught now so that we can run
the test continuously without much fuss.
4.9.5) Unique Key generators and Unique Number generators and several other pre
defined variables
We generally need some unique data in every automation project. With the new predefined vari
ables like ‘?UniqueNumber?’, ‘?UniqueKey?’ you can get unique data. You can use these variables any
where, just as any other variable defined via fitnesse script.
Other predefined variables like ‘?YYYY?’, ‘?MM?’, ‘?DD?’ can be used to generate date kind of
data based on current system date. The reason for giving three different variables is, they can be used to
achieve any kind of format.
4.9.6) Customized log makes it easy to open xml files for debugging
As I have explained in 4.2.3) Output Captured the output logging in the customized fixture not only
looks good, but also reduces the load on FitNesse as it does not have to print all the files to the log. Open
ing xml files in browser with colors will make finding some data easy, especially when the xml file is big.
You can also see the xml before replacing with variables and after variable replace so that we can
debug some more problems that can come by using wrong variables in xml.
Prasad Buddha 70
WCC Testing With FitNesse User Guide IBM
5.Re-usability
Until now, I have just discussed about linear way of creating scripts. If you have used any automa
tion tool before, you will still see one missing feature, Re-usability. We cannot just prepare automation
scripts for hundreds of scripts in a linear fashion. One small change in the requirements or missing portion
of scripts will leave you in front of a heap of changes to be done on all your scripts. When we are testing
applications like WCC, MDM, we will find that we need to create similar portions of scripts repeatedly.
We need a better approach than just linear way of creating fitnesse scripts.
In any automation framework, we will generally create some reusable components and use those
components to achieve the logic of the test case. In order to be able to do that way, we have to separate the
scripts from data. The same script component should work for different sets of data. Maybe not for all sets
of data, but the component should at least work for wide varieties of data. With the new actions and fea
tures, we can think of using the same components for multiple scripts. I have designed a new methodology
to create fitnesse scripts in our project by using the new features I have added and the features provided by
FitNesse. Let me explain you how it is done in our project.
FitNesse by default provides a functionality called ‘Page in lining’. Using this feature, we can in
clude one page in another. This is the base for our entire methodology. Here is an example for including a
page in Figure 94. The figure has two things. One: there are two test tables. Two: one of the test tables
looks different. There is a border around the first test table. It is an example of Page in lining.
FitNesse uses ‘!include’ to include a page. The path can be either relative or absolute. An absolute
path must start with a ‘.’ and should include from the top most page. I have marked an area on the figure
with a red ellipse. It shows the path of the component included in the current script. The path says Re
usableComponents.CisAddParty. There is no ‘.’ at the beginning of the path hence it is a relative party. We
can infer that there is a suite named ReusableComponents as a sibling (two pages defined as children for
same script are called siblings) of the current script being shown in the figure. Inside the ReusableCom
ponents suite, there is a children page defined with the name CisAddParty and is included in the current
script. Look at the raw wiki script to see how it is done.
Prasad Buddha 71
WCC Testing With FitNesse User Guide IBM
'''Test: '''!-Verify that the MaintainPartyAlias transaction successfully adds a new Alias name to the
party. Party has only legal name and the party is an Individual. NameType, FirstName, Middle
Name, LastName, Effective Date are provided in the request.-!
----
!include ReusableComponents.CisAddParty
!|com.ibm.wcc.fitnesse.WccXMLFixture|
|${WCCInstanceName}|${WCCProviderUrl}|
|optional|${WCCInputDirBase}Samples\getPerson.xml|
|Exists|/TCRMService/TxResponse/TxResult/ResultCode|
|Value|/TCRMService/TxResponse/TxResult/ResultCode|SUCCESS|
|Value|/TCRMService/TxResponse/ResponseObject/TCRMPersonBObj/PartyId|!!partyID?!!|
Look at the line that starts with !include. It helped us include the page CisAddParty into the current
script. Not Everything else is of much importance now. If you go to the CisAddParty component, you will
just find a test table that is being shown here nothing else. We can include entire page but we cannot in
clude portion of a page.
In the script of the component, there is nothing new it will be simply as below…
!|com.ibm.wcc.fitnesse.WccXMLFixture|
|${WCCInstanceName}|${WCCProviderUrl}|
|BYPass|${WCCInputDirBase}\MPAL10001a-aCISAddParty.xml|
|Value|/TCRMService/TxResponse/TxResult/ResultCode|SUCCESS|
|Passthrough|/TCRMService/TxResponse/ResponseObject/*/PartyId|PartyId?|
Just ignore the variable ‘${WCCInputDirBase}’ it is just a variable to store path. We prepare
these portions of scripts, that can be reused, and save them at one location. Later we include these com
ponents in the actual test scripts, wherever we need it. So, the steps involved are pretty straight forward.
Here they are…
Creating the Reusable Components
Using or Including the Reusable Components
5.1 Designing the Reusable Components
Before we can design these, we have to plan. The first thing we need to decide is what must be the
reusable component? In our project we typically planned the reusable components by dividing the com
ponents based on BObj (if you are not aware of what is a BObj, this is the terminology we use in xml it is
a parent tag for similar elements.) A typical example is creating a reusable component for TCRMPerson
NameBObj and all of its children tags.
This can again be divided into two different components. Generally in most of our test cases, we
PassThrough the elements of one BObj, and compare all of them again after doing a specific task. To
quote an example, we can check whether all the elements of TCRMPersonNameBObj are added into the
database properly or not. We achieve it by passing through all elements of TCRMPersonNameBObj from
the request of addPerson and then by comparing them in the response of addPerson and getPerson. So, it
will be beneficial if we divide passing through and comparing those elements with the defined variables
into two different components.
There are several things to be noted before we can build a reusable component. I have just men
tioned that we cannot include part of a page. So, we have to build atomic(cannot be broken down) com
ponents. They have to be planned in such a way they need not be broken. That is the reason why we have
divided passing through and asserting into two different components as just explained.
Prasad Buddha 72
WCC Testing With FitNesse User Guide IBM
As you can see from the Figure 94, there is a file name in the first test table. Did you get a doubt
now? Will not the file name be same if we include the same component in multiple scripts? Yes it will be.
If we hard code the file name in the script, it will be same in every script. Therefore, you will have to
parameterize (any variable that is declared or created at the time of creating a script is called as page-vari
able). The same is the case with file handler. It may have to be modified based on the situation as shown
below.
!|com.ibm.wcc.fitnesse.WccXMLFixture|
|${WCCInstanceName}|${WCCProviderUrl}|
|${FileHandler}|${WCCInputDirBase}\${FileName}|
|Value|/TCRMService/TxResponse/TxResult/ResultCode|SUCCESS|
|PassThrough|/TCRMService/TxResponse/ResponseObject/*/PartyId|PartyId?|
A typical component as we just discussed is to PassThrough all the name elements. If we want to
use the same reusable component in two different scripts or twice in a single script, to PassThrough two
different names, we cannot hard code the xpath. If we do so, the xpath is going to point same name BObj.
We should also use a variable to change the index of the Xpath. The same logic applies for name of the
variables also. Each name elements must be stored in a different variable. This is how it can be done…
!|com.ibm.wcc.fitnesse.WccXMLFixture|
|${WCCInstanceName}|${WCCProviderUrl}|
|${FileHandler}|${WCCInputDirBase}\${FileName}|
|CPassThrough|/TCRMService/TxResponse/ResponseObject/TCRMPersonBObj/TCRMPersonName
BObj${XpathIndex}/PrefixType|PersonName${VariableIndex}PrefixType?|
|CPassthrough|/TCRMService/TxResponse/ResponseObject/TCRMPersonBObj/TCRMPersonName
BObj${XpathIndex}/PrefixDescription|PersonName${VariableIndex}PrefixDescription?|
|PassThrough|/TCRMService/TxResponse/ResponseObject/TCRMPersonBObj/TCRMPersonName
BObj${XpathIndex}/GivenNameOne|PersonName${VariableIndex}GivenNameOne?|
|CPassthrough|/TCRMService/TxResponse/ResponseObject/TCRMPersonBObj/TCRMPersonName
BObj${XpathIndex}/GivenNameTwo|PersonName${VariableIndex}GivenNameTwo?|
|CPassthrough|/TCRMService/TxResponse/ResponseObject/TCRMPersonBObj/TCRMPersonName
BObj${XpathIndex}/GivenNameThree|PersonName${VariableIndex}GivenNameThree?|
|CPassthrough|/TCRMService/TxResponse/ResponseObject/TCRMPersonBObj/TCRMPersonName
BObj${XpathIndex}/GivenNameFour|PersonName${VariableIndex}GivenNameFour?|
|PassThrough|/TCRMService/TxResponse/ResponseObject/TCRMPersonBObj/TCRMPersonName
BObj${XpathIndex}/LastName|PersonName${VariableIndex}LastName?|
|CPassthrough|/TCRMService/TxResponse/ResponseObject/TCRMPersonBObj/TCRMPersonName
BObj${XpathIndex}/Suffix|PersonName${VariableIndex}Suffix?|
Prasad Buddha 73
WCC Testing With FitNesse User Guide IBM
Figure 96: Variable defined in the Reusable Component will cause scripts to throw an error un
defined variable
Figure 97: A typical component for passing through all the name tags
How do we handle this? Simply by defining the variables in the page in which we have to use this
component. Observe Figure 98 where the variables are defined before using the reusable component. The
values in the variables appear the included component.
We have to do the
same thing for all the auto
mation scripts, wherever
these components have to be
used. This way, the compon
ent can be called as a re
usable component. Where
ever you want to reuse the
component, define the vari
ables along with it. You
know, how to define vari Figure 98: Variables are defined before using the component where in the variables
ables in fitnesse pages. To are used
define a variable we use ‘!
define’ in the raw wiki script. It is already explained in section Syntax for Base Fixture.
Prasad Buddha 74
WCC Testing With FitNesse User Guide IBM
Let us look at it one more time. The syntax for defining a variable is as follows…
!define <Variable Name> {Value}
As an example, let us see how the script is written for using (including) a reusable component as in
Figure 98. Here is how the script has to be…
!define FileName {MPAL10001a-aCISAddParty.xml}
!define FileHandler {Pass}
!include ReusableComponents.CisAddParty
If we assume that, we have a script where we have to add a party and PassThrough two of his
names. The script that uses our reusable components, I have explained so far, should use the CisAddParty
component once and PassThrough Name component twice (there are two names to PassThrough, but the
component at a time deals with one).
Figure 99: A script that stores values in two name BObjs after adding the party
Prasad Buddha 75
WCC Testing With FitNesse User Guide IBM
Look at Figure 99. The same reusable component is used for passing through values in tags in two
different name BObjs in the same file. Observe that in both the name PassThrough reusable components (it
is named as CisRetrievePersonPassthroughOneName in our script, check the screen-shot in the previous
figure.) same file is used by setting its FileHandler to be ByPass. The file used by both components that
are passing through names is the response file generated in the first component. The files can be used in
any way you have to. As we are using ByPass file handler, it is just used for storing the variables. Notice
the way XPath and variable name is changed with the help of the variables XpathIndex and VariableIndex
in the reusable component. You can define the variable any number of times, the included component will
get recent value. The raw wiki script for achieving what is done in Figure 99 should be as below…
Look at the amount of clarity we have in the script. If the same script has to be written in a linear
fashion instead of using reusable components, the script would be 28 lines instead of just 13 lines in con
trast to what is shown above. Using the reusable components will reduce the rework. If we have to add one
more tag named StartDate in all our scripts while declaring name variables. Add it in the component where
we defined all the variables for nametags. It gets reflected in all the scripts where ever it is included.
Check that the included portion
is updated when we modify the exist
ing reusable component. Observe that
in Figure 100.
Modifying the reusable com
ponent works fine as long as you do
not have to add a variable, if the script
is already included. What are you go
ing to do, if you have to add a new
variable in a reusable component that
is already included in 100 test scripts? Figure 100: Modifying the reusable component will also effect all the
pages where it is included
Addition of new variable will break
the existing scripts, you will have to
add the definition of the variable in all the 100 scripts. To do that, you simply add the variable in the com
ponent and to assign the default blank value in the existing scripts, define the variable with a blank value
in the parent page where all these test cases are defined.
Prasad Buddha 76
WCC Testing With FitNesse User Guide IBM
Legend
All the cells in white are mandatory cells
All the cells that are in dark Grey color are optional cells
All the cells that are marked in black are conditional cells, they become mandatory when
some other cell is not provided
Note: Wherever I mentioned String (or Integer or Integer/String), it can be a constant
string(or integer) or a variable name included in a variable placeholder.
Prasad Buddha 77
WCC Testing With FitNesse User Guide IBM
Prasad Buddha 78