The following tutorial is an introduction to the Java runner. Note, that it does not cover the ecFeed basics. Therefore, if you want to learn how to create a sample model and generate a personal keystore, visit the tutorial section on our webpage.
Prerequisites:
For complete documentation check the source directly at GitHub.
The ecFeed library can be found in the Maven Repository.
Methods, used in the tutorial, are a part of the welcome model, created during the registration process at the 'ecfeed.com' webpage. If the model is missing (e.g. it has been deleted by the user), it can be downloaded from here.
Create directory on you disk. In this directory place file pom.xml with the following content:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.runner.test</groupId>
<artifactId>ecfeed-runner-test</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.ecfeed</groupId>
<artifactId>ecfeed.runner</artifactId>
<version>2.2.1</version>
</dependency>
</dependencies>
</project>
In subdirectory src/main.java place a source file 'Main.java'.
import com.ecfeed.TestProvider;
import com.ecfeed.TypeExport;
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
TestProvider testProvider = TestProvider.create("XXXX-XXXX-XXXX-XXXX-XXXX"); // The model ID.
for (String chunk : testProvider.exportNWise("QuickStart.test", TypeExport.CSV)) { // The name of the method.
System.out.println(chunk);
}
}
}
Compile the code with command: mvn compile (in the directory where is pom.xml file).
Run the code with command: 'mvn exec:java -Dexec.mainClass=Main'.
Do not hesitate to experiment with the code and modify the welcome model. It can be recreated easily and there is no better way to learn than hands-on exercises.
However, have in mind that the ID of each model (including the welcome model) is unique. If you want to copy and paste the example, be sure to update it accordingly.
The ecFeed library can be used to create test cases for JUnit, which is one of the most common testing frameworks for Java. It is possible, because generation methods return the 'Iterable<Object[]>' interface, which can be directly used as the data source.
Create an empty directory and place there file pom.xml with the following content:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ecfeed.runner.test</groupId>
<artifactId>ecfeed-runner-test</artifactId>
<version>1.0</version>
<properties>
<junit-jupiter.version>5.5.2</junit-jupiter.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.ecfeed</groupId>
<artifactId>ecfeed.runner</artifactId>
<version>2.2.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
In subdirectory src/test/java/com/ecfeed place file Junit5Test.java with the following code:
package com.ecfeed;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class Junit5Test {
static Iterable<Object[]> testProviderNWise() {
TestProvider testProvider = TestProvider.create("XXXX-XXXX-XXXX-XXXX-XXXX"); // Place your model Id here
return testProvider.generateNWise("QuickStart.test");
}
@ParameterizedTest
@MethodSource("testProviderNWise")
void testProviderNWise(int arg1, int arg2, int arg3) {
System.out.println("arg1 = " + arg1 + ", arg2 = " + arg2 + ", arg3 = " + arg3);
}
}
Compile and run tests with command: 'mvn test'.
It is also possible to use enums as arguments. To do so, they must be defined (and visible) somewhere in the project.
package com.ecfeed;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
public class Junit5Test {
enum Gender {
MALE, FEMALE
}
enum ID {
PASSPORT, DRIVERS_LICENSE, PERSONAL_ID
}
static Iterable<Object[]> testProviderNWise() {
TestProvider testProvider = TestProvider.create("XXXX-XXXX-XXXX-XXXX-XXXX"); // Place your model Id here
return testProvider.generateNWise("com.example.test.LoanDecisionTest2.generateCustomerData");
}
@ParameterizedTest
@MethodSource("testProviderNWise")
void testProviderNWise(String name, String firstName, Gender gender, int age, String id, ID type) {
System.out.println("name = " + name + ", firstName = " + firstName + ", gender = " + gender + ", age = " + age + ", id = " + id + ", type = " + type);
}
}
To send feedback, you need to have a BASIC account type or be a member of a TEAM.
A feedback example looks as follows:
static final String MODEL = "XXXX-XXXX-XXXX-XXXX-XXXX";
static final String METHOD = "QuickStart.test";
static Iterable<Object[]> feedback() {
return TestProvider.create(MODEL).generateRandom(METHOD, ParamsRandom.create().feedback().length(1));
}
@ParameterizedTest
@MethodSource("feedback")
void feedbackTest(int arg1, int arg2, int arg3, TestHandle testHandle) {
Assertions.assertTrue(arg1 < 2, () -> testHandle.addFeedback(false, "Failed - arg1 < 2"));
testHandle.addFeedback(true, "OK");
}
To the generation method an additional parameter, i.e. 'TestHandle testHandle', must be added. The class contains an overloaded method 'addFeedback'. The required argument denotes the result of the test, everything else is optional.
public String addFeedback(boolean status, int duration, String comment, Map<String, String> custom)
Note, that each test must return a feedback, regardless whether it has passed or failed. In each test, only the first invocation of the 'addFeedback' method takes effect. All subsequent invocations are neglected.
Generated feedback can be analyzed on the 'ecfeed.com' webpage.
The library provides connectivity with the ecFeed test generation service using the 'TestProvider' class. It requires the model ID, the keystore location, the keystore password, and the generator web address.
The 'TestProvider' constructor consists of one required and three optional parameters which can be provided in the form of 'Map<String, String>'. If they are non-existent, default values are used (which, for the vast majority of cases, are sufficient).
TestProvider testProvider = TestProvider.create("XXXX-XXXX-XXXX-XXXX-XXXX");
Map<String, String> configProvider = new HashMap<>();
configProvider.put("keyStorePath", "testKeyStorePath");
TestProvider testProvider = TestProvider.create("XXXX-XXXX-XXXX-XXXX-XXXX", configProvider);
Map<String, String> configProvider = new HashMap<>();
configProvider.put("keyStorePassword", "testKeyStorePassword");
TestProvider testProvider = TestProvider.create("XXXX-XXXX-XXXX-XXXX-XXXX", configProvider);
Map<String, String> configProvider = new HashMap<>();
configProvider.put("generatorAddress", "testGeneratorAddress");
TestProvider testProvider = TestProvider.create("XXXX-XXXX-XXXX-XXXX-XXXX", configProvider);
'TestProvider' can invoke five methods to access the ecFeed generator service. They produce data parsed to 'Object[]'. Additional parameters can be included in a configuration object (or a map).
Generate test cases using the NWise algorithm.
Arguments:
String[] constraints = new String[]{ "constraint" };
Map<String, String[]> choices = new HashMap<>();
choices.put("arg1", new String[]{ "choice1", "choice2" });
Map<String, String> custom = new HashMap<>();
custom.put("key1", "value1");
Param.ParamsNWise config = new Param.ParamsNWise()
.constraints(constraints)
.choices(choices)
.coverage(100)
.n(3)
.feedback()
.label("label")
.custom(custom);
testProvider.generateNWise("QuickStart.test", config)
Also, additional parameters can be passed using a map.
Map<String, Object> config = new HashMap<>();
config.put("n", "2");
config.put("coverage", "100");
String[] constraints = new String[]{ "constraint" };
config.put("constraints", constraints);
Map<String, String[]> choices = new HashMap<>();
choices.put("arg1", new String[]{ "choice1", "choice2" });
config.put("choices", choices);
config.put("feedback", "true");
config.put("label", "label");
Map<String, String> custom = new HashMap<>();
custom.put("key1", "value1");
config.put("custom", custom);
testProvider.generateNWise("QuickStart.test", config)
If the configuration object/map is not provided, default values are used.
Calls the '2-wise' generation procedure. For people that like being explicit. Apart from 'n' (which is always 2 and cannot be changed), the method accepts the same arguments as 'generateNWise'.
Generate test cases using the Cartesian product.
Arguments:
Generate randomized test cases.
Arguments:
Download generated test cases (do not use the generator).
Arguments:
Those methods look similarly to 'generate' methods. However, they return the 'Iterable
public Iterable<String> exportNWise(String method, TypeExport typeExport, Param.ParamsNWise config);
public Iterable<String> exportPairwise(String method, TypeExport typeExport, Param.ParamsPairwise config);
public Iterable<String> exportCartesian(String method, TypeExport typeExport, Param.ParamsCartesian config);
public Iterable<String> exportRandom(String method, TypeExport typeExport, Param.ParamsRandom config);
public Iterable<String> exportStatic(String method, TypeExport typeExport, Param.ParamsStatic config);
The following section describes helper methods.
Verifies if the connection settings (including the keystore) are correct. If something is wrong, an exception is thrown.
Gets the types of the method parameters in the on-line model.
Gets the names of the method parameters in the on-line model.