JUnit5 – Custom TestEngines
How to create your own TDD universe
Who is speaking?
• Sven Ruppert
• Developer Advocate – DevSecOps
• JFrog Inc
• Twitter: @SvenRuppert
• eMail: svenr@jfrog.com
THE AGENDA
The Junit5 Intro
JUnit5 – test your TestEngine
How to start your TestEngine
The basic structure of a TestEngine
How to define a Test
How to execute a TestPlan
Custom TestEngines – Ideas
The Junit5 Intro
Subject to test
Preparations
Clean Up
Subject to test
Preparations
Clean Up
Global Preparations
Global Clean Up
The Junit5 Intro
Subject to test
Preparations
Clean Up
Subject to test
Preparations
Clean Up
Global Preparations
Global Clean Up
context
context
Context
Preparations / Clean up must be fast
Easy if this is symmetric
How to deal with exceptions?
Different Tests -> different preparations / context
The Junit5 Intro
Subject to test
Preparations
Clean Up
Subject to test
Preparations
Clean Up
Global Preparations
Global Clean Up
context
context
Context
TestGroupI
TestGroupII
TestGroupIII
The Junit5 Intro
Subjecttotest
Preparations
CleanUp
Subjecttotest
Preparations
CleanUp
GlobalPreparations
GlobalCleanUp
context
context
Context
Test Group I
Subjecttotest
Preparations
CleanUp
Subjecttotest
Preparations
CleanUp
GlobalPreparations
GlobalCleanUp
context
context
Context
Test Group II
TestengineI
The Junit5 Intro
The Junit5 Intro
@Test
@ExtendWith
ExtensionContext
LifeCycle - Management
Subject to test
Preparations
Clean Up
Global Preparations
Global Clean Up
context
Context
TestGroupI
}
The Junit5 Intro
The Junit5 Intro
The Junit5 Intro
The Junit5 Intro
The Junit5 Intro
BeforeEach - ABeforeEach - B
BeforeAll - B BeforeAll - A
AfterEach - BAfterEach - A
AfterAll - A AfterAll - B
The Junit5 Intro
The Junit5 Intro
@Test
void test001(Demo demo){
Assertions.assertEquals("Hello World",
demo.value());
}
The Junit5 Intro
public static class DemoParameterResolver implements ParameterResolver {
@Override
public boolean supportsParameter(ParameterContext parameterContext,
ExtensionContext extensionContext)
throws ParameterResolutionException {
final Class<?> type = parameterContext.getParameter().getType();
return Demo.class.isAssignableFrom(type);
}
@Override
public Object resolveParameter(ParameterContext parameterContext,
ExtensionContext extensionContext)
throws ParameterResolutionException {
return new Demo(1, "Hello World");
}
}
The Junit5 Intro
@Test
@ExtendWith(DemoParameterResolver.class)
void test001(Demo demo){
Assertions.assertEquals("Hello World", demo.value());
}
The Junit5 Intro
JUnit5 – test your TestEngine
How to test a TestEngine?
We need a way to test a new TestEngine
As first exercise we will test an existing TestEngine
JUnit5 – test your TestEngine
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-testkit</artifactId>
<version>${junit5.version}</version>
<scope>test</scope>
</dependency>
JUnit5 – test your TestEngine
Two tests are started / one test is disabled
One test is failing
JUnit5 – test your TestEngine
Two tests started
One Test positive
One Test skipped
One Test failed
JUnit5 – test your TestEngine
How to start your TestEngine
Discovery the Tests
prepare the Launcher
create the TestPlan
register Listeners
execute Launcher
consume the Result
How to start your TestEngine
The basic structure of a Testengine
Basic Structure to build a Custom TestEngine
No real Test-Discovery in the first run
Production code - the Test-Engine
Test code - the Test-Engine-Tests
Test the custom Test-Engine with the Jupiter-Engine
The basic structure of a TestEngine
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-engine</artifactId>
<version>${junit.platform.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
<version>${junit.platform.version}</version>
<scope>compile</scope>
</dependency>
The basic structure of a TestEngine
<!-- needed for writing integration tests-->
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>${junit.platform.version}</version>
<scope>compile</scope>
</dependency>
The basic structure of a TestEngine
[ 1 containers found ]
[ 0 containers skipped ]
[ 1 containers started ]
[ 0 containers aborted ]
[ 1 containers successful ]
[ 0 containers failed ]
[ 0 tests found ]
[ 0 tests skipped ]
[ 0 tests started ]
[ 0 tests aborted ]
[ 0 tests successful ]
[ 0 tests failed ]
The basic structure of a TestEngine
How to define a Test
Find all tests with the Annotation @NanoTest
Execute all discovered tests
IDE should be able to execute the test
Maven should be able to execute the test
How to define a Test
How to define a Test
How to define a Test
How to define a Test
How to define a Test
How to define a Test
How to define a TestPlan
How to define a TestPlan
How to define a TestPlan
How to define a TestPlan
A TestDescriptor is a Node inside the TestPlan
A Node can be a Container or a Test
A Test is a leaf from this tree
A Descriptor can be a Container and a Test at the same time
A good start is the AbstractTestDescriptor
How to define a TestPlan
How to define a TestPlan
How to execute a TestPlan
How to execute a TestPlan
How to execute a TestPlan
How to execute a TestPlan
How to execute a TestPlan
How to execute a TestPlan
@NanoTestClass
public class FirstNanoTest {
@NanoTest
void test001_A() { }
}
Custom TestEngines - Ideas
Add a Lic Check for your commercial product
Store runtime metrics
Authentication / Authorisation
Domain – Specific – Testdefinition
Complex Infrastructure Lifecycle Management
Dynamic Testinput from external sources
Testtechniques – like MutationTesting
Persistent Immutable Testplans
Testexecution Priorities
Distributed TestPlan-Execution
IDE or maven
Testplan
TestClass
TestMethod
Execution-Nodes
JFrog - Artifactory
SecurityPayload Generator Injection
Store a TestPlan with the BuildInfo
Load binary data from Artifactory – Generic Repo
SecurityPayload Generator Injection
Store a TestResults with the BuildInfo
Repo
Testplan
Repo
SecurityPayload
TestResultRepo
Artifactory / XRay and how to use it
Internet
REST API / WebUI
RulePolicyWatch
Repo
Try it : OnPrem and/or Cloud
https://jfrog.com/platform/free-trial/
Just try it
THANK YOU!
• Sven Ruppert
• Developer Advocate – DevSecOps
• Jfrog Inc
• Twitter: @SvenRuppert
• eMail: svenr@jfrog.com

JUnit5 Custom TestEngines intro - version 2020-06

  • 1.
    JUnit5 – CustomTestEngines How to create your own TDD universe
  • 2.
    Who is speaking? •Sven Ruppert • Developer Advocate – DevSecOps • JFrog Inc • Twitter: @SvenRuppert • eMail: svenr@jfrog.com
  • 3.
    THE AGENDA The Junit5Intro JUnit5 – test your TestEngine How to start your TestEngine The basic structure of a TestEngine How to define a Test How to execute a TestPlan Custom TestEngines – Ideas
  • 4.
    The Junit5 Intro Subjectto test Preparations Clean Up Subject to test Preparations Clean Up Global Preparations Global Clean Up
  • 5.
    The Junit5 Intro Subjectto test Preparations Clean Up Subject to test Preparations Clean Up Global Preparations Global Clean Up context context Context Preparations / Clean up must be fast Easy if this is symmetric How to deal with exceptions? Different Tests -> different preparations / context
  • 6.
    The Junit5 Intro Subjectto test Preparations Clean Up Subject to test Preparations Clean Up Global Preparations Global Clean Up context context Context TestGroupI TestGroupII TestGroupIII
  • 7.
    The Junit5 Intro Subjecttotest Preparations CleanUp Subjecttotest Preparations CleanUp GlobalPreparations GlobalCleanUp context context Context TestGroup I Subjecttotest Preparations CleanUp Subjecttotest Preparations CleanUp GlobalPreparations GlobalCleanUp context context Context Test Group II TestengineI
  • 8.
  • 9.
    The Junit5 Intro @Test @ExtendWith ExtensionContext LifeCycle- Management Subject to test Preparations Clean Up Global Preparations Global Clean Up context Context TestGroupI }
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
    The Junit5 Intro BeforeEach- ABeforeEach - B BeforeAll - B BeforeAll - A AfterEach - BAfterEach - A AfterAll - A AfterAll - B
  • 15.
  • 16.
  • 17.
    @Test void test001(Demo demo){ Assertions.assertEquals("HelloWorld", demo.value()); } The Junit5 Intro
  • 18.
    public static classDemoParameterResolver implements ParameterResolver { @Override public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { final Class<?> type = parameterContext.getParameter().getType(); return Demo.class.isAssignableFrom(type); } @Override public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { return new Demo(1, "Hello World"); } } The Junit5 Intro
  • 19.
  • 20.
    JUnit5 – testyour TestEngine How to test a TestEngine? We need a way to test a new TestEngine As first exercise we will test an existing TestEngine
  • 21.
    JUnit5 – testyour TestEngine <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-testkit</artifactId> <version>${junit5.version}</version> <scope>test</scope> </dependency>
  • 22.
    JUnit5 – testyour TestEngine Two tests are started / one test is disabled One test is failing
  • 23.
    JUnit5 – testyour TestEngine Two tests started One Test positive One Test skipped One Test failed
  • 24.
    JUnit5 – testyour TestEngine
  • 25.
    How to startyour TestEngine Discovery the Tests prepare the Launcher create the TestPlan register Listeners execute Launcher consume the Result
  • 26.
    How to startyour TestEngine
  • 27.
    The basic structureof a Testengine Basic Structure to build a Custom TestEngine No real Test-Discovery in the first run Production code - the Test-Engine Test code - the Test-Engine-Tests Test the custom Test-Engine with the Jupiter-Engine
  • 28.
    The basic structureof a TestEngine <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-engine</artifactId> <version>${junit.platform.version}</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-commons</artifactId> <version>${junit.platform.version}</version> <scope>compile</scope> </dependency>
  • 29.
    The basic structureof a TestEngine <!-- needed for writing integration tests--> <dependency> <groupId>org.junit.platform</groupId> <artifactId>junit-platform-launcher</artifactId> <version>${junit.platform.version}</version> <scope>compile</scope> </dependency>
  • 30.
    The basic structureof a TestEngine
  • 31.
    [ 1 containersfound ] [ 0 containers skipped ] [ 1 containers started ] [ 0 containers aborted ] [ 1 containers successful ] [ 0 containers failed ] [ 0 tests found ] [ 0 tests skipped ] [ 0 tests started ] [ 0 tests aborted ] [ 0 tests successful ] [ 0 tests failed ] The basic structure of a TestEngine
  • 32.
    How to definea Test Find all tests with the Annotation @NanoTest Execute all discovered tests IDE should be able to execute the test Maven should be able to execute the test
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
    How to definea TestPlan
  • 40.
    How to definea TestPlan
  • 41.
    How to definea TestPlan
  • 42.
    How to definea TestPlan A TestDescriptor is a Node inside the TestPlan A Node can be a Container or a Test A Test is a leaf from this tree A Descriptor can be a Container and a Test at the same time A good start is the AbstractTestDescriptor
  • 43.
    How to definea TestPlan
  • 44.
    How to definea TestPlan
  • 45.
    How to executea TestPlan
  • 46.
    How to executea TestPlan
  • 47.
    How to executea TestPlan
  • 48.
    How to executea TestPlan
  • 49.
    How to executea TestPlan
  • 50.
    How to executea TestPlan @NanoTestClass public class FirstNanoTest { @NanoTest void test001_A() { } }
  • 51.
    Custom TestEngines -Ideas Add a Lic Check for your commercial product Store runtime metrics Authentication / Authorisation Domain – Specific – Testdefinition Complex Infrastructure Lifecycle Management Dynamic Testinput from external sources Testtechniques – like MutationTesting Persistent Immutable Testplans Testexecution Priorities
  • 52.
    Distributed TestPlan-Execution IDE ormaven Testplan TestClass TestMethod Execution-Nodes JFrog - Artifactory
  • 53.
    SecurityPayload Generator Injection Storea TestPlan with the BuildInfo Load binary data from Artifactory – Generic Repo SecurityPayload Generator Injection Store a TestResults with the BuildInfo Repo Testplan Repo SecurityPayload TestResultRepo
  • 54.
    Artifactory / XRayand how to use it Internet REST API / WebUI RulePolicyWatch Repo
  • 55.
    Try it :OnPrem and/or Cloud https://jfrog.com/platform/free-trial/ Just try it
  • 56.
    THANK YOU! • SvenRuppert • Developer Advocate – DevSecOps • Jfrog Inc • Twitter: @SvenRuppert • eMail: svenr@jfrog.com