Mono-repo for all Skippy projects.
Skippy is a Test Impact Analysis & Predictive Test Selection framework for Java and the JVM. It cuts down on unnecessary testing and flakiness without compromising the integrity of your builds. You can run it from the command line, your favorite IDE and continuous integration server. Skippy supports Gradle, Maven, JUnit 4 and JUnit 5.
Skippy is specifically designed to prevent regressions in your codebase. It supports all types of tests where the tests and the code under test run in the same JVM. It is best suited for deterministic tests, even those prone to occasional flakiness. It provides the most value for test suites that are either slow or flaky (regardless of whether the test suite contains unit, integration, or functional tests).
Skippy is not designed for tests that assert the overall health of a system. Don't use it for tests you want to fail in response to misbehaving services, infrastructure issues, etc.
The best way to get started are the Introductory Tutorials. From there, a good next step is the Reference Documentation.
Let's take a whirlwind tour of Skippy, Gradle & JUnit 5. The concepts are similar for Maven & JUnit 4.
plugins {
+ id 'io.skippy' version '0.0.24'
}
dependencies {
+ testImplementation 'io.skippy:skippy-junit5:0.0.24'
}
Annotate the test you want to optimize with @PredictWithSkippy
:
+ import io.skippy.junit5.PredictWithSkippy;
+ @PredictWithSkippy
public class FooTest {
@Test
public void testFoo() {
assertEquals("foo", Foo.getFoo());
}
}
Run the tests:
./gradlew test
FooTest > testFoo() PASSED
BarTest > testBar() PASSED
Skippy performs a Test Impact Analysis every time you run a test. The result is stored in the .skippy folder:
ls -l .skippy
test-impact-analysis.json
This data allows Skippy to make intelligent skip-or-execute predictions. Let's see what happens when you run the tests again:
./gradlew test --rerun
FooTest > testFoo() SKIPPED
BarTest > testBar() SKIPPED
Skippy detects that nothing has changed and skips both tests.
Next, introduce a bug in class Foo
:
class Foo {
static String getFoo() {
- return "foo";
+ return null;
}
}
Re-run the tests:
./gradlew test
FooTest > testFoo() FAILED
org.opentest4j.AssertionFailedError: expected: <foo> but was: <null>
BarTest > testBar() SKIPPED
Skippy detects the change and executes FooTest
. The regression is caught quickly - BarTest
remains skipped.
Fix the bug and re-run the tests:
./gradlew test
FooTest > testFoo() PASSED
BarTest > testBar() SKIPPED
Skippy executes FooTest
and updates the data in the .skippy folder.
Both tests will be skipped when you run them again:
./gradlew test --rerun
FooTest > testFoo() SKIPPED
BarTest > testBar() SKIPPED
It's safe to add the .skippy folder to version control. This will automatically enable Skippy's Predictive Test Selection when your pipeline runs.
Contributions are always welcome! You can either
I would love to hear from you.
You need JDK 17 or upwards to build Skippy.
If you want to run the entire build including tests, use build
:
./gradlew build
If you want to publish all jars to your local Maven repository, use publishToMavenLocal
:
./gradlew publishToMavenLocal
This repo contains the following sub-projects: