Cloud Service Test Grounding
Introduction
This page grants access to a web service for generating low-level Java
tests from a cloud software service specification. This test grounding
tool was developed for the EU FP7 Broker@Cloud project, to support the
continuous quality assurance objective.
Test grounding is the final stage in the model-based testing process,
whereby high-level abstract test sequences are converted into concrete tests
that can be executed on a given platform. The conversion process is achieved
using a simple Visitor Pattern algorithm which traverses the memory
model of the high-level test suite generated earlier. Having a separate test
grounding stage is useful, because it decouples the test generation phase, a
formal process, from any particular implementation technology for the service.
In the following example, we assume that the System-Under-Test is either a
plain old Java object, or a Java SOAP client built using JAX-WS, or a REST
client build using JAX-RS (Apache Jersey) and generate tests grounded in Java
for a JUnit test driver fixture.
Platform-Specific JUnit Test Grounding
This web service generates a low-level test suite from a software service
specification. It returns a Java source code file, defining a JUnit test driver.
Please supply the public URL of the XML file containing the service specification
in XML format. (You may copy an example URL from the
specification page).
Please also supply the depth to which tests will be generated
(the maximum path length to be explored from each state) and whether
multi-objective tests are to be generated (fewer paths, possibly verifying
multiple properties per path). Choose whether to ground for a plain Java system,
or for a JAX-WS client for SOAP, or for a JAX-RS client for REST, and indicate
whether to verify the states and transitions that were fired (if the service offers
access to this information).
If the input file can be read, the output will be Java source file containing
the executable tests (otherwise an error message will be displayed). The file will
define a JUnit test driver class, whose set-up method creates an instance of the
Service-Under-Test, presumed here to be either a plain old Java object, or a Java
SOAP client interface built using JAX-WS. The driver and the SUT can be in
different Java packages (dummy package names are created here). The test methods
of the driver correspond to the test sequences generated by the high-level test
generator. By default, each test consists of set-up steps, followed by a verified
step, in which the outputs of methods are verified using JUnit assertions.
If multi-objective testing was selected, each test may contain multiple verified
steps, corresponding to shorter tests merged into the longer test. This minimises
the number of test sequences, while still testing the same objectives. When verifying
full state and transition behaviour, further JUnit assertions are generated, to query
the system about the last scenario executed and the reached state. The implemented
service must follow certain design-for-test conditions to be fully testable, with
operations to reveal its last action and reached state.
Comparing the Different Groundings
The grounded output file defines a JUnit test driver class, which may be executed
within the JUnit testing framework. The names of the test driver class and the
Java client class representing the Service-Under-Test are derived from the service
name given in the original specification. The test driver contains test-methods,
which are numbered in a corresponding way to the TestSequences, and which
will be executed in the same order. The test driver and the tested service may be
located in the same, or in different Java packages (the Java import
instructions will change accordingly).
Apart from these commonalities, there are subtle differences between the code
generated for a plain old Java object, or for a JAX-WS Java SOAP client, or for a
JAX-RS Java REST client.
The JavaGrounding algorithm assumes that the Service-Under-Test is a plain
old Java object, whose methods represent the operations in the SUT's API. A fresh
instance of the service object is created (in the setUp() method) before the
start of each test sequence, since it is cheap to re-create a simple Java object.
This object is stored in the system attribute of the test driver, and is
the target of all subsequent requests.
The JaxWsGrounding algorithm assumes that the Service-Under-Test is a SOA
webservice, described using WSDL and SOAP, which was created and deployed using the
standard JAX-WS toolset. This toolset also creates an automatic client in Java, used
to dispatch SOAP messages and interpret the responses. The client is actually two
Java objects, one representing the service implementation and the other representing
its interface (or service API). These two objects are stored as attributes of the
test driver. Since it is expensive to create a SOA webservice, these are created just
once in the setUp() method. Before every test sequence, the service is
reset() using the method provided for this purpose.
The JaxRsGrounding algorithm assumes that the Service-Under-Test is a REST
webservice, which was created and deployed using the standard JAX-RS toolset. A REST
client was developed in Apache Jersey to submit HTTP requests, encoding the
request in the URL and transmitting any response data in JSON. The test grounding
follows this pattern, and generates a function to translate JUnit method-invocations
into REST requests, and to interpret JSON responses using Google's Gson library. The
service is created once in the setUp() method. Before every test sequence,
the service is reset() using the request provided for this purpose.
|