Fastest
Computer programming testing tool
- 7 min read
- 5 chapters
Related on Lably
Through Cartesian product, Satisfiability and Java (programming language)
Usage
Fastest presents a command-line user interface. The user first needs to load a Z specification written in LaTeX format verifying the ISO standard. Then, the user has to enter a list of the operations to test as well as the testing tactics to apply to each of them. In a third step Fastest generates the testing tree of each operation. After testing trees have been generated, users can browse them and their test classes, and, more importantly, they can prune any test class both automatically or manually. Once testing trees have been pruned, users can instruct Fastest to find one abstract test case for each leaf in each testing tree.
Sign in to keep reading
4 more chapters are free with a Lably account.
Testing tactics supported by Fastest
Currently, Fastest supports the following testing tactics:
- Disjunctive Normal Form (DNF). It is the only testing tactic applied by default (regardless of whether the user has added or not other testing tactics) and the first one to be applied.
- Standard partitions (SP). The user can add, modify and delete standard partitions for any predefined Z mathematical operator by simply editing a text file.
- Free Types (FT)
- In Set Extension (ISE)
- Proper Subset of Set Extension (PSSE)
- Subset of Set Extension (SSE)
Pruning testing trees in Fastest
Fastest provides two ways of pruning testing trees:
- Automatic pruning.
- To prune a testing tree, Fastest analyzes the predicate of each leaf to determine if the predicate is a contradiction or not. Since this problem is undecidable, the tool implements a best-effort algorithm that can be improved by users. The most important aspect of the algorithm is a library of so called elimination theorems each of which represents a family of contradictions. This library can be extended by users by simply editing a text file. Elimination theorems are conjunctions of parametric Z atomic predicates.
- Manual pruning.
- Fastest users can prune subtrees or individual leaves of testing trees by issuing two commands. These commands will prune all the test classes in the subtree regardless of them being empty or not. The main purpose of these commands is to allow engineers to reduce the number of or to eliminate unimportant test cases.
How Fastest finds abstract test cases
The tool finds abstract test cases by calculating a finite model for each leaf in a testing tree. Finite models are calculated by restricting the type of each VIS variable to a finite set and then by calculating the Cartesian product between these sets. Each leaf predicate is evaluated on each element of this Cartesian product until one satisfies the predicate (meaning that an abstract test case was found) or until it is exhausted (meaning that either the test class is unsatisfiable or the finite model is inadequate). In the last case, the user has the chance to assist the tool in finding the right finite model or to prune the test class because it is unsatisfiable.
Architecture and technology
Fastest is a Java application based on the Community Z Tools (CZT) project. The tool can be used in one of two modes:
- In distributed mode Fastest works as a client–server application. The application can be installed in a number of computers each acting as client, a server or both. Users access the application through clients which send test classes to servers (called testing servers) which try to find an abstract test case out of them. In this way the heaviest task is distributed across as many computers as possible. Since the calculation of an abstract test case from a test class is completely independent from each other, this architecture speeds up the entire process proportionally with respect to the number of testing servers.
- In application mode each instance of Fastest is completely independent of each other. All the tasks are computed in the local computer.
Adding new testing tactics
As can be seen from the TTF presentation, testing tactics are essential to the method. They are the tools that engineers must use to create the most discovering test cases possible. Then, the more sound testing tactics available to engineers the better.
In Fastest users can add testing tactics of their own by implementing the Tactic interface provided by the tool. This interface has methods to configure and apply testing tactics. The interface definition is the following:
<span id="mwYQ"></span><span class="kn" id="mwYg">package</span><span class="w" id="mwYw"> </span><span class="nn" id="mwZA">client.blogic.testing.ttree.tactics</span><span class="p" id="mwZQ">;</span> <span class="kn" id="mwZg">import</span><span class="w" id="mwZw"> </span><span class="nn" id="mwaA">java.util.*</span><span class="p" id="mwaQ">;</span> <span class="kn" id="mwag">import</span><span class="w" id="mwaw"> </span><span class="nn" id="mwbA">net.sourceforge.czt.z.ast.Spec</span><span class="p" id="mwbQ">;</span> <span class="kn" id="mwbg">import</span><span class="w" id="mwbw"> </span><span class="nn" id="mwcA">common.z.TClass</span><span class="p" id="mwcQ">;</span> <span class="kn" id="mwcg">import</span><span class="w" id="mwcw"> </span><span class="nn" id="mwdA">common.z.OpScheme</span><span class="p" id="mwdQ">;</span> <span class="cm" id="mwdg">/**</span> <span class="cm" id="mwdw"> * Interface that abstracts a testing tactic (needed to generate test trees) and</span> <span class="cm" id="mweA"> * makes possible its application to a test class in order to generate new ones.</span> <span class="cm" id="mweQ"> */</span> <span class="kd" id="mweg">public</span><span class="w" id="mwew"> </span><span class="kd" id="mwfA">interface</span> <span class="nc" id="mwfQ">Tactic</span><span class="w" id="mwfg"> </span><span class="p" id="mwfw">{</span> <span class="w" id="mwgA"> </span> <span class="w" id="mwgQ"> </span><span class="cm" id="mwgg">/**</span> <span class="cm" id="mwgw"> * Applies this tactic to the specified test class and returns the list with</span> <span class="cm" id="mwhA"> * the generated test classes.</span> <span class="cm" id="mwhQ"> * @param tClass</span> <span class="cm" id="mwhg"> * @return</span> <span class="cm" id="mwhw"> */</span> <span class="w" id="mwiA"> </span><span class="kd" id="mwiQ">public</span><span class="w" id="mwig"> </span><span class="n" id="mwiw">List</span><span class="o" id="mwjA"><</span><span class="n" id="mwjQ">TClass</span><span class="o" id="mwjg">></span><span class="w" id="mwjw"> </span><span class="nf" id="mwkA">applyTactic</span><span class="p" id="mwkQ">(</span><span class="n" id="mwkg">TClass</span><span class="w" id="mwkw"> </span><span class="n" id="mwlA">tClass</span><span class="p" id="mwlQ">);</span> <span class="w" id="mwlg"> </span> <span class="w" id="mwlw"> </span><span class="cm" id="mwmA">/**</span> <span class="cm" id="mwmQ"> * Sets the specification of the system under test.</span> <span class="cm" id="mwmg"> * @param opScheme</span> <span class="cm" id="mwmw"> */</span> <span class="w" id="mwnA"> </span><span class="kd" id="mwnQ">public</span><span class="w" id="mwng"> </span><span class="kt" id="mwnw">void</span><span class="w" id="mwoA"> </span><span class="nf" id="mwoQ">setSpec</span><span class="p" id="mwog">(</span><span class="n" id="mwow">Spec</span><span class="w" id="mwpA"> </span><span class="n" id="mwpQ">spec</span><span class="p" id="mwpg">);</span> <span class="w" id="mwpw"> </span> <span class="w" id="mwqA"> </span><span class="cm" id="mwqQ">/**</span> <span class="cm" id="mwqg"> * Gets the Z schema box of the operation under test.</span> <span class="cm" id="mwqw"> * @return</span> <span class="cm" id="mwrA"> */</span> <span class="w" id="mwrQ"> </span><span class="kd" id="mwrg">public</span><span class="w" id="mwrw"> </span><span class="n" id="mwsA">Spec</span><span class="w" id="mwsQ"> </span><span class="nf" id="mwsg">getSpec</span><span class="p" id="mwsw">();</span><span class="w" id="mwtA"> </span> <span class="w" id="mwtQ"> </span> <span class="w" id="mwtg"> </span><span class="cm" id="mwtw">/**</span> <span class="cm" id="mwuA"> * Sets the Z schema box of the operation under test.</span> <span class="cm" id="mwuQ"> * @param opScheme</span> <span class="cm" id="mwug"> */</span> <span class="w" id="mwuw"> </span><span class="kd" id="mwvA">public</span><span class="w" id="mwvQ"> </span><span class="kt" id="mwvg">void</span><span class="w" id="mwvw"> </span><span class="nf" id="mwwA">setOriginalOp</span><span class="p" id="mwwQ">(</span><span class="n" id="mwwg">OpScheme</span><span class="w" id="mwww"> </span><span class="n" id="mwxA">opScheme</span><span class="p" id="mwxQ">);</span> <span class="w" id="mwxg"> </span> <span class="w" id="mwxw"> </span><span class="cm" id="mwyA">/**</span> <span class="cm" id="mwyQ"> * Gets the Z schema box of the operation under test.</span> <span class="cm" id="mwyg"> * @return</span> <span class="cm" id="mwyw"> */</span> <span class="w" id="mwzA"> </span><span class="kd" id="mwzQ">public</span><span class="w" id="mwzg"> </span><span class="n" id="mwzw">OpScheme</span><span class="w" id="mw0A"> </span><span class="nf" id="mw0Q">getOriginalOp</span><span class="p" id="mw0g">();</span> <span class="w" id="mw0w"> </span> <span class="w" id="mw1A"> </span><span class="cm" id="mw1Q">/**</span> <span class="cm" id="mw1g"> * Parses the parameters of this tactic.</span> <span class="cm" id="mw1w"> * @param str</span> <span class="cm" id="mw2A"> * @return</span> <span class="cm" id="mw2Q"> */</span> <span class="w" id="mw2g"> </span><span class="kd" id="mw2w">public</span><span class="w" id="mw3A"> </span><span class="kt" id="mw3Q">boolean</span><span class="w" id="mw3g"> </span><span class="nf" id="mw3w">parseArgs</span><span class="p" id="mw4A">(</span><span class="n" id="mw4Q">String</span><span class="w" id="mw4g"> </span><span class="n" id="mw4w">str</span><span class="p" id="mw5A">);</span> <span class="w" id="mw5Q"> </span> <span class="w" id="mw5g"> </span><span class="cm" id="mw5w">/**</span> <span class="cm" id="mw6A"> * Sets the instance of TacticInfo associated to this object.</span> <span class="cm" id="mw6Q"> * @param tacticInfo</span> <span class="cm" id="mw6g"> */</span> <span class="w" id="mw6w"> </span><span class="kd" id="mw7A">public</span><span class="w" id="mw7Q"> </span><span class="kt" id="mw7g">void</span><span class="w" id="mw7w"> </span><span class="nf" id="mw8A">setTacticInfo</span><span class="p" id="mw8Q">(</span><span class="n" id="mw8g">TacticInfo</span><span class="w" id="mw8w"> </span><span class="n" id="mw9A">tacticInfo</span><span class="p" id="mw9Q">);</span> <span class="w" id="mw9g"> </span> <span class="w" id="mw9w"> </span><span class="cm" id="mw-A">/**</span> <span class="cm" id="mw-Q"> * Gets the instance of TacticInfo associated to this object.</span> <span class="cm" id="mw-g"> * @return</span> <span class="cm" id="mw-w"> */</span> <span class="w" id="mw_A"> </span><span class="kd" id="mw_Q">public</span><span class="w" id="mw_g"> </span><span class="n" id="mw_w">TacticInfo</span><span class="w" id="mwAQA"> </span><span class="nf" id="mwAQE">getTacticInfo</span><span class="p" id="mwAQI">();</span> <span class="w" id="mwAQM"> </span> <span class="w" id="mwAQQ"> </span><span class="cm" id="mwAQU">/**</span> <span class="cm" id="mwAQY"> * Gets the description of this tactic.</span> <span class="cm" id="mwAQc"> * @return the string with the description of this tactic.</span> <span class="cm" id="mwAQg"> */</span><span class="w" id="mwAQk"> </span> <span class="w" id="mwAQo"> </span><span class="kd" id="mwAQs">public</span><span class="w" id="mwAQw"> </span><span class="n" id="mwAQ0">String</span><span class="w" id="mwAQ4"> </span><span class="nf" id="mwAQ8">getDescription</span><span class="p" id="mwARA">();</span> <span class="w" id="mwARE"> </span> <span class="w" id="mwARI"> </span><span class="cm" id="mwARM">/**</span> <span class="cm" id="mwARQ"> * Sets the description of this tactic.</span> <span class="cm" id="mwARU"> * @param description</span> <span class="cm" id="mwARY"> */</span> <span class="w" id="mwARc"> </span><span class="kd" id="mwARg">public</span><span class="w" id="mwARk"> </span><span class="kt" id="mwARo">void</span><span class="w" id="mwARs"> </span><span class="nf" id="mwARw">setDescription</span><span class="p" id="mwAR0">(</span><span class="n" id="mwAR4">String</span><span class="w" id="mwAR8"> </span><span class="n" id="mwASA">description</span><span class="p" id="mwASE">);</span> <span class="p" id="mwASI">}</span>
