Package org.jwalk.core

This sub-package for JWalk 1.1 contains the core JWalk test engine, © Anthony J H Simons, 2006-2011.

See:
          Description

Class Summary
AlgebraWalker AlgebraWalker exercises all the algebraic constructions of the test class.
ArrayGenerator ArrayGenerator is an abstract generator of arrays and primitive values.
ClassInspector ClassInspector detects the public method interface of the test class.
CreateTestCase CreateTestCase is a kind of test case that constructs a single object.
EnumTestCase EnumTestCase is a kind of test case that selects an enumerated constant.
InvokeTestCase InvokeTestCase is a kind of test case that invokes a single method.
LicenseManager LicenseManager grants a licensed user authority to use the JWalk tool suite.
ObjectGenerator ObjectGenerator is the standard generator of object, array and basic values.
Oracle Oracle is the test oracle used to store and predict test outcomes.
ParamTestCase ParamTestCase is a kind of test case that accepts input parameters.
ProtocolWalker ProtocolWalker exercises all the method protocols of a test class.
StateInspector StateInspector inspects the concrete state of a test object.
StateSpaceWalker StateSpaceWalker exercises all the high-level states and transitions of the test class.
TestCase TestCase represents a single invocation, construction or constant selection.
TestSequence TestSequence represents a constructor and method invocation sequence.
ValueGenerator ValueGenerator is an abstract generator for synthesising simple values.
 

Enum Summary
Category Category enumerates the algebraic category of each operation.
Outcome Outcome enumerates all the possible test outcomes as judged by an oracle.
 

Package org.jwalk.core Description

This sub-package for JWalk 1.1 contains the core JWalk test engine, © Anthony J H Simons, 2006-2011. Programmers are not expected to need to interact with components in this package directly, unless they are building third-party testing tools that wish to access individual TestSequence objects, in order to report results in a customised way. Otherwise, programmers should not touch the objects in this package. Doing so might affect the process of testing in a deleterious way. Other parts of the JWalk 1.1 tool suite are described in the following packages:

The rest of this package documentation gives an overview of the various JWalker strategy classes that implement the test engine; the TestSequences that these construct, consisting of a number of TestCases that exercise the methods of the test class; and the various Generators that synthesise input values for each TestSequence.

The JWalk Test Engine

The core JWalk test engine consists of a number of test strategy objects, known as JWalkers. These are classified in a hierarchy of JWalkers, according to their abilities to inspect or explore the test class.

Each JWalker inherits the capabilities of its ancestors and redefines the main execute() method. From the programmer's point of view, the entry point is the class JWalker, which acts as a dispatcher and launches the appropriate JWalker subclass, according to the test settings chosen by the tester. Each JWalker performs interleaved cycles of test generation, test execution and dynamic analysis of the test results. Feedback from the latest test cycle is used to inform the JWalker about which paths should be expanded in the next test cycle. The behaviour of the individual JWalkers is described below.

JWalker

This is the entry point to the JWalk test engine. It offers the two APIs called Channels, for setting up communication channels, and Settings, for initialising the engine with test settings. See the main package documentation for how to use these. The engine may be launched explicitly using execute(), which runs in the same thread, or (from version 1.1) may be launched in a separate thread using:

        JWalker walker = new JWalker();
        // ... initialise the channels and settings
        Thread thread = new Thread(walker);
        thread.setPriority(NORM_PRIORITY - 2);  // for a worker thread
        thread.start();
which implicitly invokes the run() method, declared in the interface Runnable. This calls execute(), but has to handle all exceptions. After this, the JWalker delegates to one of the following subclasses to do the work.

ClassInspector

This JWalker performs a detailed static analysis of the test class's public constructor and method interface. If the test class is an enumerated type, it extracts the enumerated constants. It also provides the ability to estimate the baseline test-set size after exploring the test class breadth-first, to any bounded depth. This information is used later to calculate how effective the test path pruning strategy of other JWalkers has been. The results of a ClassInspector are reported in a ProtocolReport.

ProtocolWalker

This JWalker performs a detailed static analysis of the test class's public constructor and method interface and then explores the test class's constructors and methods to a given bounded depth. It then "walks through the protocol", meaning that it attempts all constructors, followed by all possible interleaved combinations of the test class's methods. In each subsequent test cycle, it prunes all those test paths whose prefix terminated in an exception. This may yield a reduction over the baseline test set, if certain methods raised exceptions. The initial analysis after class inspection is reported in a ProtocolReport and the resuts of exploring the protocols of the test class are reported in a number of CycleReports, one for each test cycle of increasing depth, followed by a SummaryReport, giving summary statistics.

AlgebraWalker

This JWalker performs a detailed static analysis of the test class's public constructor and method interface, then performs a dynamic analysis of the test class's algebraic structure, by constructing probing paths through the protocol of the test class and noting whether certain sequences modify the test object's state, leave it unchanged, or return to a previously visited state. The methods of the test class are classified into primitive, transformer or observer categories (constructors may be primitive, or derived also). Finally, this JWalker explores the test class's algebraic constructions to a given bounded depth. It "walks through the algebra", meaning that it grows only those test paths that consist of primitive operations, and examines all operations at the leaves of this tree. In each subsequent test cycle, it prunes all those test paths whose prefix terminated in an exception, an observer, or a transformer. This yields a considerable reduction over the baseline test set. The initial analysis after class inspection is reported in an AlgebraReport and the remaining results are reported as per ProtocolExplorer, above.

StateSpaceWalker

This JWalker a detailed static analysis of the test class's public constructor and method interface, then performs a dynamic analysis of the test class's high-level state space, using any state predicates supplied in the test class's interface as hints about its high-level or abstract states. It does this by constructing probing paths through the test class's algebraic structure, seeking those paths that cause state predicates to return true or false in different combinations. The high-level states correspond to (possibly a subset of) the boolean product. Finally, this JWalker explores the test class's high-level states and transitions to a given bounded depth. It "walks the states and transitions" by constructing the state cover, then extending this with transition paths of increasing length. It prunes paths in a similar way to ProtocolExplorer and generates CycleReports for each high-level state and transition path depth. The initial analysis after class inspection is reported in a StateReport, which lists the states and the state cover, and the remaining results are reported as per ProtocolExplorer, above.

TestSequence and TestCase

A single execution path is represented as a TestSequence that consists of a number of TestCases. There are different kinds of TestCase, classified in a hierarchy according to the kind of element that they execute. The featured classes involved in test sequences are:

Any single TestSequence commences with either a CreateTestCase or an EnumTestCase, followed by an arbitrary number of InvokeTestCase test cases. The sequence is created by a JWalker when the latter is computing the next set of paths to explore, then populated with actual values just prior to execution. After execution, the TestSequence may be inspected to determine a number of properties about the last-executed operation in the sequence.

Generators of Test Inputs

The various JWalker strategy classes construct their chosen TestSequences of increasing length, up to the specified bounded depth. Prior to executon, each TestSequence must be populated with actual test inputs, passed as arguments to the constructors and methods being executed. This is achieved using a family of Generators. There are two main kinds of Generator, declared as the following interfaces, with suitable concrete implementations:

A MasterGenerator is a top-level generator which, in addition to synthesising values of different types, is capable of logging the created values and mapping from these to a persistent string representation, called the oracle value encoding. A CustomGenerator is a special purpose generator, possibly supplied by the tester, which generates test inputs for one or more types in a specific way, controlled by the tester.

The default value-generation strategy synthesises quasi-unique values of each type, in a monotonically increasing way. To change this strategy, the tester may add a CustomGenerator as a delegate of the current MasterGenerator, to take control of how instances of a specific type are to be created. Four custom generators are installed as standard. The tester may install further custom generators. See the associated documentation for the package org.jwalk.gen.