STAMP-project / dspot

Automatically detect and generate missing assertions for Junit test cases (also known as test amplification)
https://dspot-demo.stamp-project.eu/
GNU Lesser General Public License v3.0
114 stars 28 forks source link
coverage dspot h2020 hacktoberfest inria java junit test-amplification test-automation

DSpot DSpot CI codecov Maven Central

DSpot is a tool that generates missing assertions in JUnit tests. DSpot takes as input a Java project with an existing test suite. DSpot generates new test cases from existing ones and write them on disk. DSpot supports Java projects built with Maven and Gradle (see the --automatic-builder option)

DSpot ecosystem:

Getting started

Demo site

Meet our demonstration website at https://dspot-demo.stamp-project.eu/.

Prerequisites

You need Java and Maven. The environment variable JAVA_HOME must point to a valid JDK installation (and not a JRE). DSpot uses the environment variable MAVEN_HOME, ensure that this variable points to your maven installation. Example:

export MAVEN_HOME=path/to/maven/

Releases

We advise you to start by downloading the latest release, see https://github.com/STAMP-project/dspot/releases.

Usage

First Tutorial

After having downloaded DSpot (see the previous section), you can run the provided example by running eu.stamp_project.Main from your IDE, or with

java -jar target/dspot-LATEST-jar-with-dependencies.jar --example

replacing LATEST by the latest version of DSpot, e.g. 2.2.1 would give dspot-2.2.1-jar-with-dependencies.jar

Given a test case as input, with --amplifiers=None, DSpot only adds assertions in the test, for example:

@Test
void test() {
  Tacos tacos = new Tacos();
  Benjamin benjamin = new Benjamin();
  benjamin.eat(tacos);
  assertFalse(benjamin.isHungry());
+  assertTrue(benjamin.isHappy());  // new assertion
}

With some amplifiers, eg --amplifiers=AllAmplifiers, DSpot modifies the setup of the input test and adds assertions in your code, for example:

@Test
void test() {
  Tacos tacos = new Tacos();
  Benjamin benjamin = new Benjamin();
-  benjamin.eat(tacos); // removed method call
-  assertFalse(benjamin.isHungry());
+  assertTrue(benjamin.isHungry());
+  assertFalse(benjamin.isHappy()); // new assertion
}

The modified test is lastly given to a selector, eg --test-selector=PitMutantScoreSelector, that determines if it improves the test suite and should be kept.

The amplification process is illustrated in the figure below. Note that amplified tests are further modified by subsequent iterations determined by for example --iteration=10.

Application loop

When an amplification is successful, DSpot outputs the improvement on the console and the result of the amplification (the new tests) are written to the output folder specified by configuration property outputDirectory (default to ./target/dspot/output/).

Initial instruction coverage: 30 / 34
88.24%
Amplification results with 5 amplified tests.
Amplified instruction coverage: 34 / 34
100.00%

Want to know more? Read the full articles:

Command Line Usage

You can then execute DSpot by using:

java -jar /path/to/dspot-LATEST-jar-with-dependencies.jar --absolute-path-to-project-root <path>

Amplify a specific test class

java -jar /path/to/dspot-*-jar-with-dependencies.jar eu.stamp_project.Main --absolute-path-to-project-root <path> --test my.package.TestClass

Amplify specific test classes according to a regex

java -jar /path/to/dspot-LATEST-jar-with-dependencies.jar --absolute-path-to-project-root <path> --test my.package.*
java -jar /path/to/dspot-LATEST-jar-with-dependencies.jar --absolute-path-to-project-root <path> --test my.package.Example*

Amplify a specific test method from a specific test class

java -jar /path/to/dspot-LATEST-jar-with-dependencies.jar --absolute-path-to-project-root <path> --test my.package.TestClass --cases testMethod

Command line options

Full list of command line options ``` Usage: eu.stamp_project.Main [-hvV] [--allow-path-in-assertions] [--clean] [--dev-friendly] [--example] [--execute-test-parallel] [--generate-new-test-class] [--gregor-mode] [--keep-original-test-methods] [--only-input-amplification] [--restful] [--smtp-auth] [--target-one-test-class] [--use-maven-to-exe-test] [--use-working-directory] [--absolute-path-to-project-root=] [--absolute-path-to-second-version=] [--automatic-builder=] [--cache-size=] [--collector=] [--delta=] [--descartes-mutators=] [--descartes-version=] [--excluded-classes=] [--excluded-test-cases=] [--full-classpath=] [-i=] [--input-ampl-distributor=] [--jvm-args=] [--maven-home=] [--maven-pre-goals-test-execution=] [--max-test-amplified=] [--mongo-colname=] [--mongo-dbname=] [--mongo-url=] [--nb-parallel-exe-processors=] [--output-path=] [--path-pit-result=] [--path-to-additional-classpath-elements=] [--path-to-test-list-csv=] [--pit-filter-classes-to-keep=] [--pit-output-format=] [--pit-version=] [--random-seed=] [--relative-path-to-classes=] [--relative-path-to-source-code=] [--relative-path-to-test-classes=] [--relative-path-to-test-code=] [--repo-branch=] [--repo-slug=] [-s=] [--smtp-host=] [--smtp-password=] [--smtp-port=] [--smtp-tls=] [--smtp-username=] [--system-properties=] [--target-module=] [--time-out=] [--with-comment=] [-a=[,...]]... [-c=[,...]]... [-t=[,...]]... -a, --amplifiers=[,...] Specify the list of amplifiers to use. By default, DSpot does not use any amplifiers (None) and applies only assertion amplification. Valid values: MethodDuplicationAmplifier, MethodRemove, FastLiteralAmplifier, MethodAdderOnExistingObjectsAmplifier, ReturnValueAmplifier, StringLiteralAmplifier, NumberLiteralAmplifier, BooleanLiteralAmplifier, CharLiteralAmplifier, AllLiteralAmplifiers, NullifierAmplifier, ArrayAmplifier, None Default value: None --absolute-path-to-project-root= Specify the path to the root of the project. This path must be absolute.We consider as root of the project folder that contain the top-most parent in a multi-module project. --absolute-path-to-second-version= When using the ChangeDetectorSelector, you must specify this option. It should have for value the path to the root of the second version of the project. It is recommended to give an absolute path --allow-path-in-assertions If enabled, DSpot will generate assertions for values that seems like to be paths. Default value: false --automatic-builder= Specify the automatic builder to be used. Valid values: Maven, Gradle Default value: Maven -c, --cases, --test-cases, --test-methods=[,...] Specify the test cases to amplify.By default, DSpot selects all the tests methods. --cache-size= Specify the size of the memory cache in terms of the number of store entries Default value: 10000 --clean If enabled, DSpot will remove the out directory if exists, else it will append the results to the exist files. Default value: false --collector= Set a collector: MongodbCollector to send info to Mongodb at end process, NullCollector which does nothing.Valid values: NullCollector, MongodbCollector Default value: NullCollector --delta= Specify the delta value for the assertions of floating-point numbers. If DSpot generates assertions for float, it uses Assert.assertEquals(expected, actual, delta). It specifies the delta value. Default value: 0.1 --descartes-mutators= Specify the list of descartes mutators to be used separated by comma. Please refer to the descartes documentation for more details: https://github. com/STAMP-project/pitest-descartes --descartes-version= Specify the version of pit-descartes to use. Default value: 1.2.4 --dev-friendly Amplifies the test cases in a way that is easy for developers to read and understand. Default value: false --example Run the example of DSpot and leave. --excluded-classes= Specify the full qualified name of excluded test classes. Each qualified name must be separated by a comma ','. These classes won't be amplified, nor executed during the mutation analysis, if the PitMutantScoreSelector is used.This option can be valued by a regex. --excluded-test-cases= Specify the list of test cases to be excluded. Each is the name of a test case, separated by a comma ','. --execute-test-parallel If enabled, DSpot will execute the tests in parallel. For JUnit5 tests it will use the number of given processors (specify 0 to take the number of available core processors). For JUnit4 tests, it will use the number of available CPU processors (given number of processors is ignored). Default value: false --full-classpath= Specify the classpath of the project. If this option is used, DSpot won't use an AutomaticBuilder (e.g. Maven) to clean, compile and get the classpath of the project. Please ensure that your project is in a good shape, i.e. clean and correctly compiled, sources and test sources. --generate-new-test-class Enable the creation of a new test class. Default value: false --gregor-mode Enable the gregor engine for Pit Mutant Score Selector. Default value: false -h, --help Show this help message and exit. -i, --iteration= Specify the number of amplification iterations. A larger number may help to improve the test criterion (e.g. a larger number of iterations may help to kill more mutants). This has an impact on the execution time: the more iterations, the longer DSpot runs. Default value: 1 --input-ampl-distributor= Specify an input amplification distributor.Valid values: RandomInputAmplDistributor, TextualDistanceInputAmplDistributor, SimpleInputAmplDistributor Default value: RandomInputAmplDistributor --jvm-args= Specify JVM args to use when executing the test, PIT or other java process. This arguments should be a list, separated by a comma ',', e.g. jvmArgs=Xmx2048m,-Xms1024m',-Dis.admin. user=admin,-Dis.admin.passwd=$2pRSid# --keep-original-test-methods If enabled, DSpot keeps original test methods of the amplified test class. Default value: false --maven-home= Specify the maven home directory. If it is not specified DSpot will first look in both MAVEN_HOME and M2_HOME environment variables. If these variables are not set, DSpot will look for a maven home at default locations /usr/share/maven/, /usr/local/maven-3.3.9/ and /usr/share/maven3/. --maven-pre-goals-test-execution= Specify pre goals to run before executing test with maven.It will be used as follow: the elements, separated by a comma,must be valid maven goals and they will be placed just before the "test" goal, e.g.--maven-pre-goals-test-execution preGoal1,preGoal2 will give "mvn preGoal1 preGoal2 test" --max-test-amplified= Specify the maximum number of amplified tests that dspot keeps (before generating assertion). Default value: 200 --mongo-colname= If valid mongo-url and a mongo-dbname are provided, DSpot will submit result to the provided collection name.. Default value: AmpRecords --mongo-dbname= If a valid mongo-url is provided, DSpot will submit result to the database indicated by this name. Default value: Dspot --mongo-url= If valid url, DSpot will submit to Mongodb database. Default value: mongodb://localhost: 27017 --nb-parallel-exe-processors= Specify the number of processor to use for the parallel execution.0 will make DSpot use all processors available. Default value: 0 --only-input-amplification Only apply input amplification. Default value: false --output-path, --output-directory= specify a path folder for the output. Default value: target/dspot/output/ --path-pit-result= Specify the path to the .xml or .csv of the original result of Pit Test. If you use this option the selector will be forced to PitMutantScoreSelector. --path-to-additional-classpath-elements= Specify additional classpath elements (e.g. a jar files). Elements of this list must be separated by a comma ','. --path-to-test-list-csv= Enable the selection of the test to be amplified from a csv file. This parameter is a path that must point to a csv file that list test classes and their test methods in the following format: test-class-name;test-method-1;test-method-2;test-method-3;... If this parameter is used, DSpot will ignore the value used in the parameter test and cases It is recommended to use an absolute path. --pit-filter-classes-to-keep= Specify the filter of classes to keep used by PIT. This allow you restrict the scope of the mutation done by PIT. If this is not specified, DSpot will try to build on the fly a filter that takes into account the largest number of classes, e.g. the topest package. --pit-output-format= Specify the Pit output format.Valid values: XML, CSV Default value: XML --pit-version= Specify the version of PIT to use. Default value: 1.4.0 --random-seed= Specify a seed for the random object (used for all randomized operation). Default value: 23 --relative-path-to-classes= Specify the relative path from --absolute-path-to-project-root/--target-module command-line options that points to the folder that contains binaries of the source (. class). Default value: target/classes/ --relative-path-to-source-code= Specify the relative path from --absolute-path-to-project-root/--target-module command-line options that points to the folder that contains sources (.java). Default value: src/main/java/ --relative-path-to-test-classes= Specify the relative path from --absolute-path-to-project-root/--target-module command-line options that points to the folder that contains binaries of the test source (.class). Default value: target/test-classes/ --relative-path-to-test-code= Specify the relative path from --absolute-path-to-project-root/--target-module command-line options that points to the folder that contains test sources (.java). Default value: src/test/java/ --repo-branch= Branch name of the submitted repo, This is used by mongodb as a identifier for analyzed repo's submitted data. Default value: UnknownBranch --repo-slug= Slug of the repo for instance Stamp/Dspot. This is used by mongodb as a identifier for analyzed repo's submitted data. Default value: UnknownSlug --restful If true, DSpot will enable restful mode for web Interface. It will look for a pending document in Mongodb with the corresponding slug and branch provided instead of creating a completely new one. Default value: false -s, --test-selector, --test-criterion= Specify the test adequacy criterion to be maximized with amplification. Valid values: PitMutantScoreSelector, JacocoCoverageSelector, TakeAllSelector, ChangeDetectorSelector, ExtendedCoverageSelector Default value: PitMutantScoreSelector --smtp-auth Enable this if the smtp host server require auth. Default value: false --smtp-host= Host server name. Default value: smtp.gmail.com --smtp-password= Password for Gmail, used for submit email at end-process. Default value: Unknown --smtp-port= Host server port. Default value: 587 --smtp-tls= Enable this if the smtp host server require secure tls transport. Default value: false --smtp-username= Username for Gmail, used for submit email at end-process. Default value: Unknown@gmail.com --system-properties= Specify system properties. This value should be a list of couple property=value, separated by a comma ','. For example, systemProperties=admin=toto,passwd=tata. This defines two system properties. -t, --test=[,...] Fully qualified names of test classes to be amplified. If the value is all, DSpot will amplify the whole test suite. You can also use regex to describe a set of test classes. By default, DSpot selects all the tests classes. --target-module= Specify the module to be amplified. This value must be a relative path from value specified by --absolute-path-to-project-root command-line option. If your project is multi-module, you must use this property because DSpot works at module level. --target-one-test-class Enable this option will make DSpot computing the mutation score of only one test class (the first pass through --test command line option). Default value: false --time-out= Specify the timeout value of the degenerated tests in millisecond. Default value: 10000 --use-maven-to-exe-test If enabled, DSpot will use maven to execute the tests. Default value: false --use-working-directory Enable this option to change working directory with the root of the project. Default value: false -v, --verbose Enable verbose mode of DSpot. Default value: false -V, --version Print version information and exit. --with-comment= Enable comment on amplified test: details steps of the amplification. Valid values: All, Amplifier, Coverage, None. Default value: None ```

For options that take list, the used separator is a comma ,, whatever the platform you use.

Maven plugin usage

You can execute DSpot using the maven plugin. For more details, see the dedicated README.

Each command line options is translated into an option for the maven plugin. You must prefix each of them with -D. Examples:

* `--test my.package.MyTestClass1:my.package.MyTestClass2` gives `-Dtest=my.package.MyTestClass1,my.package.MyTestClass2`
* `--output-path output` gives `-Doutput-path=output` 

Configuration

Amplifiers (-a | --amplifiers)

By default, DSpot uses no amplifier because the simplest amplification that can be done is the generation of assertions on existing tests, i.e. it will improve the oracle and the potential of the test suite to capture bugs.

However, DSpot provide different kind of Amplifier:

If you only want to use these amplifiers and not generate assertions, use --only-input-amplification.

Test Selectors (-s | --test-selector | --test-criterion)

In DSpot, test selectors can be seen as a fitness: it measures the quality of amplified, and keeps only amplified tests that are worthy according to this selector.

The The default selector is PitMutantScoreSelector. This selector is based on PIT, which is a tool to computation mutation analysis. DSpot will keep only tests that increase the mutation score.

Following the list of available test selectors:

Input Ampl Distributor

In DSpot, the Input Ampl Distributor is a way to select the amplified test methods after the input amplification. It allows to keep interesting and discard unwanted amplified test method.

For now, there are three implementations of the Input Ampl Distributor:

Supported Test Frameworks

DSpot supports:

and

However, DSpot detects the used test framework at test class level.

Please, do not amplify test classes that mix test frameworks (test methods in JUnit4 and JUnit5 within the same test class.)

If you have such test class, please amplify the different test framework separately.

Supported JDKs & Build Tools

DSpot runs with the following Java versions:

It can amplify tests of projects built with:

Minimizing and Prettifying DSpot Amplified Test Cases

With the DSpot Prettifier you can remove redundant assertions from your amplified test cases & give them more expressive names with the help of code2vec and context2vec.

License and Contributions

DSpot is licensed under LGPLv3. Contributors and pull requests are welcome :-). For more information on development, see the dedicated README-developers.md

Acknowledgement

Dspot is funded by EU H2020 research project STAMP.