Software Development Document-MUnit Test Generator
Software Development Document-MUnit Test Generator
1.2 Scope
The MUnit Test Generator should be able to generate the framework of an MUnit
Test Suite when given a functioning Mule XML file. The project should allow for
instant generation of mostly complete MUnit tests, resulting in a significantly
shorter test development time.
The tests may lack specific input or output values, or may not check values
against certain criteria. The user must specify the expected input or output
values, as well as criteria when necessary.
1.3 Overview
The document will provide information pertaining to the functionality, design,
and context of the MUnit Generator.
System Architecture and Component Design both contain information pertaining
to class structure and code design.
Data Design contains information pertaining to data types expected throughout
the project.
Human Interface Design contains information pertaining to the use of the
software and the overall design of the user interface.
Requirements details the required functions of the completed application.
1.4 Reference Material
2. System Overview
This project originated from a need at my summer software development internship.
The company was transitioning services to MuleSoft and was looking for a way to
test code, ideally without wasting time backtracking to reorganize flows to allow for
easy MUnit Test design. I decided to attempt to automate the process, by parsing
the Mule XML code and writing equivalent MUnit XML blocks to a specified output
file.
The project should able to parse a Mule XML file from a user specified location, and
outputting an equivalent MUnit Test Suite to a user specified output directory.
3. System Architecture
3.1 Architectural Design
The software should be split into several modules to isolate responsibilities and
allow for easier orchestration of project tasks. For this project, I want to create
data structures to simplify the management of Mule XML parsing. To do this, I
will need to create a TagPair object which will represent and XML tag paired with
an ordered dictionary containing the XML attributes for the tag. I will also need to
create a TagList data structure which will be a meta-class of a standard list. Each
TagList will contain TagPair objects and provide methods to allow for simple
access to the data.
Most of the work will take place in a MuleLines object, which will parse the lines
of XML code and store them as one of its attributes. The MuleLines object will
generate a TagList of the original XML, and will use the TagList to generate a
corresponding TagList of MUnit XML code.
The orchestration of the main process for the program will take place in an MUnit
Generator file which will handle command line argument parsing as well the
creation of necessary objects and the calling of various methods.
MuleLines
Read and
MuleLines has multiple Write to
TagLists TagLists
TagList TagList
TagPair TagPair
3.2 Design Decomposition
MUnit Generator
Required Attributes:
parser: ArgumentParser
mule: MuleLines
Required Methods:
main() -> None
MuleLines
Required Attributes:
inputFileName: string
muleFileLines: string list
muleTagList: TagList
mUnitTagList: TagList
Required Methods:
parseMuleFileLines(inputFilePath : string) -> None
createMUnitTests() -> None
createMUnitSuiteFile(outputFilePath : string) -> None
convertMuleToMUnit(TagList) -> TagList
TagList
Required Attributes:
list: TagPair list
Required Methods:
append(pair: TagPair) -> None
clear() -> None
contains(targetPair: TagPair) -> boolean
copy() -> TagList
pairs() -> TagPair list
remove(targetPair: TagPair) -> None
TagPair
Required Attributes:
tag: string
attributes: dictionary (string: string)
Required Methods:
getAttributes() -> dictionary
setAttributes(newAttributes: dictionary) -> None
getAttribute(attributeName: string) -> string
setAttribute(attributeName: string,
attributeValue: string) -> None
removeAttribute(attributeName: string) -> None
3.3 Design Rationale
The choice to create TagPair and TagList objects was led by a need to maintain an
ordered list of XML tags, while tracking the tag name and its corresponding
attributes.
The TagPair seemed to be a natural structure to create, as it allows for effective
mapping of XML tags to their attributes. A list of TagPairs is preferable to a
dictionary alternative, as it allows for repetition of XML tags, which is to be
expected in a Mule or MUnit XML document.
Although the TagList is like a standard list object in Python, its custom design
allows for more granular interaction with the contents of the list without
exposing the contents to the user. For instance, the TagList can be given the
option to search for a tag, and not a TagPair, allowing an easy search by the end
user.
I chose to isolate all file parsing, writing, and code generation to MuleLines, as it
allows for easy reusability of the object if ever necessary. It wouldnt make sense
to allow multiple classes to handle the process of XML parsing and conversion, as
the process would involve passing of relatively large amounts of data between
several objects. As a result, I opted for a single object to orchestrate all
processing of Mule code.
The MUnit Generator class is a simple class that orchestrates user interaction and
creates and calls all necessary processes for the software. This allows for a
simple, accessible interaction for the user, while all complicated details are
handled behind the scenes.
4. Data Design
4.1 Data Description
Data in this project is read in from a specified input file, which is broken down
into lines and parsed. Each line is split to isolate the XML tag and the
corresponding attributes of the tag. A TagPair is created, pairing the XML tag with
a dictionary containing attribute : value pairs. Each of these TagPairs is then
mapped to a TagList for future processing.
The original file lines are also stored within the system, in case future versions
have a requirement to access the file twice. This will allow for a single access to
the input file with a potential for multiple parsing iterations over the file
structure.
All MUnit XML that is generated should be immediately mapped to a TagList for
storage in the system. The MUnit TagList will eventually be iterated through and
written to the user specified output file location.
Required Attributes:
Required Methods:
main():
get input file path
get output file path
MuleLines
Required Attributes:
inputFileName: string
muleFileLines: list of strings
muleTagList: TagList
mUnitTagList: TagList
Required Methods:
parseMuleFileLines(input file path: string):
store input file name
read input file
split file by lines
store lines into muleFileLines
convertMuleToMUnit():
for each mule line:
if the line has an MUnit equivalent:
add the MUnit to mUnitTagList
else:
skip the line
TagList
Required Attributes:
list: list of TagPairs
Required Methods:
append(pair: TagPair):
append pair to list
clear():
for x in list:
remove x from list
contains(targetPair: TagPair):
for x in list:
if x == targetPair:
return True
return False
copy():
create new TagList
for x in list:
append x to new TagList
return new TagList
pairs():
create output list
for x in list:
add x to output list
return output list
remove(targetPair: TagPair):
if targetPair in list:
remove targetPair from list
else:
return
TagPair
Required Attributes:
tag: string
attributes: dictionary (string: string)
Required Methods:
getAttributes():
return attributes
setAttributes(newAttributes: dictionary):
attributes = newAttributes
getAttribute(attributeName: string):
if attributeName in attributes:
return attribute value from attributes
setAttribute(attributeName: string,
attributeValue: string):
add (attributeName: attributeValue) to attributes
removeAttribute(attributeName: string):
if attributeName in attributes:
remove attributeName from attributes
The script will check that the input file path is valid and proceed from that point.
If the input file cannot be found, an exception will be thrown and the user will be
notified that the file path is invalid.
If the output file path does not exist, it will be automatically created.
7. Appendices