Getting Started
Aerial is designed to be extensible and to cover various input and output formats. It should be extensible not only by internal design it should also provide an ability to include some external modules which can be easily used together with the entire engine. Mainly, it’s all about being able to create some kind of plug-ins. There are several areas where it can be done:
-
Input readers - components responsible for getting input data from some external source (any external system, file system etc.)
-
Output writers - components responsible for producing the output in some specific format
-
Scenario generators - components responsible for custom algorithms implementation which are targeted to produce new types of scenarios
-
Test Data generators - components targeted to implement various settings and algorithms for custom data types and corresponding input values generation process
All of the above component types implement specific interface and main things the Aerial needs are:
-
Configuration - the engine itself should be configured to use or include each specific module from specific location. Otherwise, it is decided that the component operates with built-in classes
-
Library availability in classpath - since we use Java and create some modules which are stand-alone libraries they definitely should be included into classpath before engine starts using it
All the above things are needed to be defined. On this page we’ll describe each of the component types in more details with examples of how to extend existing functionality in the direction of each specific component.
Custom Input Readers
Since version 0.0.4
Overview
All Aerial input readers are defined via classes extending AerialReader abstract class. Actually this class only defines default constructor and prototypes for core methods. They are:
Method | Description |
---|---|
open | Performs data initialization. Normally it identifies the scope of items to process and contains either some references or local copies of resources to read |
close | Cleans up all data and resets the entire reader |
hasNext | Used for iterative input elements processing. It indicates whether input source with settings specified contains more data |
readNext | Reads next portion of data from the specified source |
Since all the above methods are pretty typical by their structure and functions they are used in typical way. Actually, all necessary set of actions are performed by AerialProcessor class so it is highly recommended to keep existing structure and approaches for AerialReader extensions.
Write Custom Reader
All classes inherited from AerialReader class should have constructor like:
| public AerialReader(AerialParams params, AerialTagList tagsValue) {
...
}
|
Tags handling isn’t really required. It is still desired feature but the actual tags handling is up to each specific implementation. There is no any specific interface for it. Actually, all user needs to do for tags is to fill their values depending on some rule. If tags are empty they simply won’t be used in generated files.
Configure Aerial to Use Custom Reader
Custom reader class can be passed as readerClass named parameter, e.g. readerClass=com.sample.CustomReaderClass. At the same time the input type parameter should be defined as CUSTOM.
Custom Output Writers
Since version 0.0.4
Overview
All Aerial output writers are defined via classes extending AerialWriter abstract class. It is abstract class defining common methods which should be implemented by any writer class. They are:
Method | Description |
---|---|
open | Initializes internal data. Normally this method is designed to take the list of parsed documents and set the reference to iterator so that engine will use it when processing each document items iteratively |
close | Closes and removes all internal data. Mainly it is invoked after entire writing is done |
writeNext | Used for iterative output elements processing. It takes next available document item and writes it to specific output in specific format. Main output is the string containing final representation of the generated text |
hasNext | Used for iterative processing. Indicates whether writer has more document items to process |
Write Custom Writer
Configure Aerial to Use Custom Writer
Custom writer class can be passed as writerClass named parameter, e.g. writerClass=com.sample.CustomWriterClass. At the same time the output type parameter should be defined as CUSTOM.
Custom Types Definition
Since version 0.0.5
Overview
In some cases we have some data which is either very specific to application under test or it is some data which is logically grouped and you need to apply data generation for that using some specific rules. This is the case where built-in types are not enough and we need to use some custom type. For instance, we can create some custom type to operate with address which is the combination of strings and numbers in specific order.
Write Custom Input Type
Every custom type should be an extension of ValueExpression class. In this class we should override the following methods:
Method | Description |
---|---|
public String getMatchPattern() | Returns the regular expression which should be the pattern for any acceptable value of this type. In other words all positive values of this type should match the pattern |
public String getValueTypeName() | Returns the name of the custom type. This name should then be used in input data table |
public List |
Returns the list of generated data |
Here is an example of custom input type:
| package com.github.mkolisnyk.aerial.datagenerators;
import java.util.ArrayList;
import java.util.List;
import com.github.mkolisnyk.aerial.document.InputRecord;
import com.github.mkolisnyk.aerial.expressions.ValueExpression;
public class CustomExternalTypeExpression extends ValueExpression {
@Override
public String getMatchPattern() {
return "(.*)";
}
@Override
public String getValueTypeName() {
return "Season";
}
public CustomExternalTypeExpression(InputRecord inputValue) {
super(inputValue);
}
@Override
public List<InputRecord> generate() throws Exception {
List<InputRecord> result = new ArrayList<InputRecord>() {
{
new InputRecord(
getInput().getName(),
getInput().getType(),
"Winter",
getInput().getCondition(),
true);
new InputRecord(
getInput().getName(),
getInput().getType(),
"Spring",
getInput().getCondition(),
true);
new InputRecord(
getInput().getName(),
getInput().getType(),
"Summer",
getInput().getCondition(),
true);
new InputRecord(
getInput().getName(),
getInput().getType(),
"Autumn",
getInput().getCondition(),
true);
new InputRecord(
getInput().getName(),
getInput().getType(),
"Unknown",
getInput().getCondition(),
false);
}
};
return result;
}
}
|
In some cases we may need to define custom input type as an inner class. It can be done in the same fashion but with some restrictions: 1. That should be just a top level sub-class. So, inner class of inner class wouldn’t work 2. The container class should have default constructor
Configure Aerial to Use Custom Input Type
The list of classes representing custom types is defined either via aerial.types.custom.classes global property or via similar named system property. The value should contain canonical names as well as those classes should be available in the classpath.
Custom Scenario Generators
Since version 0.0.6
Overview
Besides standard generated scenarios Aerial provides an ability to extend case scenario generation engine to define specific scenarios which should be generated based on input.
Write Custom Scenario Generator
All custom scenarios must be an implementation of CaseScenarioGenerator class. Mainly we should implement the following methods:
Method | Description |
---|---|
generate | Returns final generated scenario or scenario outline. This is the main method which is being used by Aerial |
isApplicable | Returns true when this scenario is applicable for some specific data set. E.g. we may avoid the scenario generation if some specific test data attribute isn’t set |
getScenarioName | Returns string which defines suffix uniquely identifying the scenario name |
getTags | Returns the list of tags which should be applied to the scenario of current custom type |
Configure Aerial to Use Custom Scenario Generator
The list of custom classes can be configured via aerial.gen.custom.classes configuration property or the same system property.