Worked as a QA for many years, and ever faced to various test automation tools, like Selenium, Watir, Appnium, SAHI, QTP, etc. But none of those tools ever had an eye on automating the test design tasks - which is the most human intensive tasks in QA's domain.
After many reading of automated test case/script generation articles, publications, we decided to develop a tool to support test case design using some approach similar to Model Based Testing, we named it MBTester - though it's not constrained by MBT methodologies.
Nowadays, software applications, device types and platforms are rapidly increasing in numbers, complexity, and inter-operation. As a result, testing complexity and requirements are growing exponentially while at the same time the release cycles have decreased from years to months, even days.
Testing, in the other side, still remains mainly a manual task, is time-consuming and expensive. Roughly to say, 80% of testing is carried out entirely manually, and the automation mostly focuses on test execution tasks only. Some of the key challenges of testing are listed below:
◼ Manual test design brings significant risk, is hardly reproducible, and depends on ingenuity of individual test engineer and is costly.
◼ Test coverage is hard to measure, or the coverage remains low.
◼ Maintenance of manually designed test case is a nightmare. Every test engineer has the experience that when requirement change comes, searching the test case repository to locate the test cases to update, delete, to add new test cases, to filter test cases for regression, etc. The test cases written in human language soon become outdated and useless, sometimes, even misleading.
◼ Building/maintaining a requirement coverage matrix is hard even impossible. A requirement coverage matrix would be an exciting tool to help test engineers to select test cases based on some criteria.
The key to concur these issues is automation. So we developed the MBTester by modeling behavior aspect of the System Under Test (SUT), and then generating manual test case suites / test scripts automatically from the model, the tool brings automation in the whole cycle of testing - from test design to test execution to test maintenance.
By adopting MBT approach, there are many modeling techniques can be used to modeling behaviors of SUT, such as UML State Chart, Finite State Machine(FSM), Extended Finite State Machine (EFSM), Flow chart, Petri Net, Swim Lane Event-Driven Petri Net (SLEDPN), Business Process Modeling and Notation (BPMN), Decision Table, etc.
In all above listed modeling techniques, it’s believed that State Chart and SLEDPN has the most expressive power among others, and they are somehow equivalent.
However, we chose to use a different approach: the Behavior Tree (BT) notation originally developed by Dromey, because:
◼ It is elegant and easy to learn, easy to use, and easy to understand.
◼ It has similar (if not all) expressive power as State Chart / SLEDPN.
◼ It is easy to be modeled graphically.
◼ It supports model composition natively, this is especially powerful for team work.
A BT is a formal, tree-like graphical form that represents the behavior of individual or networks of entities (Since our focus is on software testing, so the entities that are captured using BTs are software components, but the concept is widely applicable) which realize and change states, create and break relations, make decisions, respond to and fire events, and interact by exchanging information and passing control. BTs were created to capture and formalize the dynamic information in natural language descriptions. BTs have been used to capture and formalize natural language descriptions of information in legal contracts, standards, business process, medical diseases and genetics.
In addition to being applicable to a wide variety of domains (i.e. the rich expressive power), BTs have a few unique characteristics leading it to be a better choice as a modeling language:
◼ BTs avoid a network structure by using a tree-like graphical form which makes cycles implicit and use a different approach to modularization that links each node to a component.
◼ The syntax of BTs creates a secondary notation which allows expert readers to easily view the flow of control and concurrency in the model.
◼ BTs uses formal transition types which are defined graphically. These transition types are defined by a formal semantics in a lower level language called the Behavior Tree Process Algebra(BTPA), and recently have been revised to be based upon an extension to CSP which supports hierarchical states.
Those characteristics together allow BTs to scale by comprehensively describing large amounts of information where network structures would overwhelm a reader with a web of complex interconnections.
To get a solid understanding of BT notation, this Wikipedia page is wonderful:
Behavior tree
We already know that a BT is composed of behavior nodes, and BT specifies a bunch of node types to express the behaviors of a system. In this section, we will briefly view those node types. However, you should not expect that you will see all the behavior node types BT specifies, because we only use those node types which are relevant to software testing. Also please note that the syntax we use is slightly different from the formal definition, we made those changes, because we think it’s easier for a modeler to use.
◼ Alternative branching - Pass control to only one of the child nodes. If multiple choices are possible, make a non-deterministic choice.
◼ Parallel branching - Pass control to all child nodes concurrently.
You have seen many examples of branching in the above screenshots, generally speaking, alternative branching will pick up one and only one child node to pass control to, and parallel branching will pass control to all child nodes concurrently. The node takes alternative branching has a diamond attached to, and the node takes parallel branching has a black bar attached to.
Every QA has his/her own set of secret data to support his/her daily test execution tasks. In the MBTtester's modeler, data constraints can be fed to each input event node types, as below screenshot shows (a behavior node's inspector window):
A few data constraint types you can attach:
◼ bag - a value list, the backend engine will choose a value randomly from this list whenever it needs a value.
◼ number range - a range of real numbers, the backend engine will choose a value randomly from this range whenever it needs a value.
◼ whole number range - just like number range, but this range only contains whole numbers (integers).
◼ sequence - a sequence, modeler can control the length of this sequence, and how each element should be generated (using sub-constraints).
◼ set - like sequence, but set is orderless and elements are distinct from each other.
◼ map - a dictionary structure, each key in this map has a separate data generator, modeler can control how many keys in the map, which keys are optional, which keys should be present together, and which keys should be mutual exclusive.
◼ custom - generate value from modeler defined function.
◼ composite - a composite data generator with a list of data generators, the backend engine will choose a data generator randomly to use whenever it needs a value.
For example, say we have a behavior node which takes the customer ‘age’ as an input parameter, a whole number range is enough (assume in our requirement, age takes
value from range [0,131]):
Note that we attach a tag ‘valid age’ to this whole number range, this is optional, however, the tags can serve as the classifier for equivalence classes, as we all know, equivalence class partitioning is an important technique widely used by QAs. For example, we could design the data generators for ‘age’ parameter as below (a composite data generator with 5 child whole number range generators corresponding to the 5 equivalence classes of ‘age’ parameter). But to make this example easily to be followed, we just use the singleton range [0,131] as above shows.
As a final example, below screenshot shows all input parameters are decorated by their respective data constraints:
As we've mentioned above, every behavior node can be assigned a traceability tag (a requirement ID, for example):
From those metadata, traceability matrix can be easily generated, a piece of a cake:
Before generating testing related artifacts, only the behavior tree itself can provide you many benefits. You can communicate with the project stakeholders using this graphical model, especially with those from business background, since the behavior tree is easy to understand, and unambiguity. This means you can start to model the requirement as early as you can, and get feedback from business at the early stage.
Additionally, there are a few utilities you can use to gain more insights into the BTs, thus the requirements. Here we will give each a glance.
You can generate activity diagram from BT, many people understand activity diagram, hence this can help them view the requirement from a different aspect.
For a behavior tree with many subjects work together, a Component Interact Network (CIN). Below is an example of modeling an ATM benchmark.
If you prefer the more traditional tree structure, you can outline the requirement tree. You can make any node as root in the outline, so you can zoom-in/zoom-out in the tree hierarchy.
In case that you are interested in only the behaviors of a specific component, you can filter the nodes related (below shows only the behavior nodes related to card reader in the ATM model). Below is the list of all components in the ATM model:
Below screenshot shows the filtered behavior nodes when only subject ‘Reader’ is selected:
The default layout of a BT is a top-down tree like structure. When different layout is desired, you can right click on any behavior node, and select Behavior Tree Layout menu to call out the layout configuration dialog for the node:
In this dialog, 3 layout types are provided: Default, Orthogonal, and Compact tree. You can also ask a different layout direction other than top-down, i.e. if the ‘Left to Right?’ choice is selected, the layout manager will layout the tree nodes from left to right instead of from top to down. The node spacing and level spacing provide you fine-grained control of spacing of nodes and levels. If ‘Apply recursively?’ is not selected, the configuration will apply to the behavior node you selected only, otherwise, the configuration will apply to all descendants. Below is an example of left-to-right Compact tree layout:
After modeling your requirement into behavior trees, and perhaps, integrated a few related trees into a big one, you can fed the behavior tree into our backend engine to generate full suite of manual test cases, automated test scripts (currently, only selenium in JAVA is supported, more bridges are under heavy development).
You already saw it above, no repeat here.
We've applied this tool in a few internal real projects, it shows its value, much much value. Maybe in a later opportunity, I will show you an example.
Well, we have finished this short introduction. Many are not covered yet, but we believe that it should give you enough information about this tool.
If you have any idea, suggestions, comments, whatever :-), please tell us, we will be happy to hear from you!
If you have reached here... you may also want to see more of MBTester.