SlideShare une entreprise Scribd logo
1  sur  49
Télécharger pour lire hors ligne
Scott Leberknight
3/4/2021
JUnit Pioneer
“JUnit Pioneer is an extension pack for JUnit 5 or,
to be more precise, for the Jupiter engine”
Recap: JUnit Extensions
Provide a way to extend JUnit’s core features
Well-defined extension API and lifecycle
Simple Example
@ParameterizedTest
@RandomIntSource(min = 5, max = 10, count = 50)
void shouldDoSomethingWithRandomInts(int value) {
// test code...
}
Injecting method
parameters into
tests
Example from https://github.com/kiwiproject/kiwi-test/
@RegisterExtension
static final CuratorTestingServerExtension ZK_TEST_SERVER =
new CuratorTestingServerExtension();
Another Example
Start and stop a
ZooKeeper server before
& after tests
Example from https://github.com/kiwiproject/kiwi-test/
Pioneer Extensions
A collection of useful Jupiter extensions
Easy to integrate into your tests
Pioneer Extensions
Cartesian product
Locale & TimeZone
Environment Vars
Range sources
Issue Info
Disabling tests
Report entries
Stdin & Stdout
System props
Vintage tests
Stopwatch!
* as of 2021-03-04
*
System Properties
@SetSystemProperty(key = "user", value = "bob")
@SetSystemProperty(key = "id", value = "42")
class SystemPropertyTest {
@Test
@ClearSystemProperty(key = "user")
void testWithoutUserProperty() { ... }
@Test
@SetSystemProperty(key = "pwd", value = "12345")
void anotherTest() { ... }
}
Environment Variables
@SetEnvironmentVariable(key = "PWD", value="/tmp")
@ClearEnvironmentVariable(key = "PS1")
class EnvVarsTest {
@ClearEnvironmentVariable(key = "PWD")
void testWithoutWorkingDirEnvVar() { ... }
@SetEnvironmentVariable(key = "USER", value = "alice")
void testWithCustomUser() { ... }
}
Default TimeZone
@DefaultTimeZone("America/Mexico_City")
class DefaultTimeZoneTest {
@Test
void testInMexicoCity() {
assertThat(TimeZone.getDefault()).isEqualTo(
TimeZone.getTimeZone("America/Mexico_City"));
}
@Test
@DefaultTimeZone("Mexico/BajaSur")
void testInBajaSur() { ... }
}
Default Locale
@DefaultLocale("es")
class DefaultLocaleTest {
@Test
void testWithDefaultFromClass() {
assertThat(Locale.getDefault())
.isEqualTo(new Locale("es"));
}
@Test
@DefaultLocale(language = "nan", country = "TW",
variant = "Hant")
void testUsingAllAttributes() {
assertThat(Locale.getDefault()).isEqualTo(
new Locale("nan", "TW", "Hant"));
}
}
Having Issues?
public class SystemOutIssueProcessor
implements IssueProcessor {
@Override
public void processTestResults(List<IssueTestSuite> suites) {
// do something with each test suite
}
}
@Test
@Issue("JUPI-1234")
void shouldFix1234() {
// test code for issue JUPI-1234
}
#1 Annotate
#2 Define processor
#3 Register implementation
com.fortitudetec.junit.pioneering.SystemOutIssueProcessor
META-INF/services/org.junitpioneer.jupiter.IssueProcessor
I need those TPS reports...
class ReportEntriesTest {
@Test
@ReportEntry("I'm Going To Need Those TPS Reports ASAP")
void testWithReportEntry() { ... }
@Test
@ReportEntry(key = "result", value = "success",
when = PublishCondition.ON_SUCCESS)
@ReportEntry(key = "result", value = "failed",
when = ReportEntry.PublishCondition.ON_FAILURE)
void testWithConditionalEntries() { ... }
}
#1 Annotate
public class SimpleTestExecutionListener
implements TestExecutionListener { ... }
#2 Create a JUnit
TestExecutionListener
com.fortitudetec.junit.pioneering.SimpleTestExecutionListener
META-INF/services/org.junit.platform.launcher.TestExecutionListener
#3 Register implementation
Disabling on display name
Selectively disable parameterized tests
Specify substrings and/or regex to match...
...and disable any tests with a matching name
@DisableIfDisplayName(contains = "42")
@ParameterizedTest(name = "Test scenario {0}")
@ValueSource(ints = {1, 24, 42, 84, 168, 420, 4200, 4242, 17640})
void shouldDisableUsingStringContains(int value) {
if (String.valueOf(value).contains("42")) {
fail("Should not have received %s", value);
}
}
Using a substring to specify
disabling condition
matching
against the
generated
test name
@DisableIfDisplayName(matches = ".*d{3}-d{2}-d{4}.*")
@ParameterizedTest(name = "Test scenario {0}")
@ValueSource(strings = {
"42", "123-45-6789", "400", "234-56-7890", "888"
})
void shouldDisableUsingRegex(String value) {
failIfContainsAny(value, "123-45-6789", "234-56-7890");
}
Or use a regular
expression
@DisableIfDisplayName(contains = {"42", "84"},
matches = ".*d{3}-d{2}-d{4}.*")
@ParameterizedTest(name = "Test scenario {0}")
@ValueSource(strings = {
"24", "42", "123-45-6789", "400", "234-56-7890", "888"
})
void shouldDisableUsingContainsAndMatches(String value) {
failIfContainsAny(value, "42", "84", "123-45-6789", "234-56-7890");
}
or use both...
@DisableIfDisplayName(matches = ".*[0-9][3|5]")
@ParameterizedTest(name = "Product: FTCH-000-{0}")
@RandomIntSource(min = 0, max = 1_000, count = 500)
void shouldDisableWhenProductCodeEndsWith_X3_Or_X5(int code) {
var codeString = String.valueOf(code);
if (PRODUCT_NUMBER_PATTERN.matcher(codeString).matches()) {
fail("Should not have received %d", code);
}
}
Combine a regex
with randomized test input
@RandomIntSource from https://github.com/kiwiproject/kiwi-test/
Do, or do not, there is no try
class RetryingAnnotationTest {
@RetryingTest(2)
void shouldFail() {
flakyObject.failsFirstTwoTimes();
}
@RetryingTest(3)
void shouldPass() {
flakyObject.failsFirstTwoTimes();
}
}
Third time's
the charm eh?
Stdin
@Test
@StdIo({"foo", "bar", "baz"})
void shouldReadFromStandardInput() throws IOException {
var reader = new BufferedReader(new InputStreamReader(System.in));
assertThat(reader.readLine()).isEqualTo("foo");
assertThat(reader.readLine()).isEqualTo("bar");
assertThat(reader.readLine()).isEqualTo("baz");
}
@Test
@StdIo({"1", "2"})
void shouldCaptureStdIn(StdIn stdIn) throws IOException {
var reader = new BufferedReader(new InputStreamReader(System.in));
reader.readLine();
reader.readLine();
assertThat(stdIn.capturedLines()).containsExactly("1", "2");
}
& Stdout
@Test
@StdIo
void shouldInterceptStandardOutput(StdOut stdOut) {
System.out.println("The answer is 24");
System.out.println("No, the real answer is always 42");
assertThat(stdOut.capturedLines()).containsExactly(
"The answer is 24",
"No, the real answer is always 42"
);
}
How long did that take?
class StopwatchTest {
@RepeatedTest(value = 10)
@Stopwatch
void shouldReportElapsedTime() { ... }
}
Elapsed time will be published
via a TestReporter, so that a
TestExecutionListener can
receive it
Out on the range...
Create ranges of ints, longs, etc. as test input
Use with parameterized tests
Specify lower and upper bounds
Upper bound can be inclusive or exclusive
@ParameterizedTest
@IntRangeSource(from = 0, to = 10)
void shouldGenerateIntegers(int value) {
assertThat(value).isBetween(0, 9);
failIfSeeUpperBound(value, 10);
}
'from' is inclusive;
'to' is exclusive by default
@IntRangeSource(from = 0, to = 10)
@ParameterizedTest
@LongRangeSource(from = -100_000, to = 100_000, step = 5_000)
void shouldAllowChangingTheStep(long value) {
assertThat(value).isBetween(-100_000L, 95_000L);
failIfSeeUpperBound(value, 100_000);
}
change difference between
generated values using 'step'
@ParameterizedTest
@DoubleRangeSource(from = 0.0, to = 10.0, step = 0.5, closed = true)
void shouldAllowClosedRanges(double value) {
assertThat(value).isBetween(0.0, 10.0);
}
make a closed range
The best vintage?
Pioneer's vintage @Test replaces JUnit 4 @Test...
...but marks the method as a Jupiter test
Supports expected and timeout parameters
@CartesianProductTest
Generate cartesian product of all inputs
Use @CartesianProductTest instead of
Jupiter @Test annotations
Pioneer provides custom argument sources
You can also provide a custom @ArgumentsSource
@CartesianProductTest({"0", "1"})
void shouldProduceAllCombinationsOfThree(String x,
String y,
String z) {
List.of(x, y, z).forEach(this::assertIsZeroOrOne);
}
specify a String array
produces all input
combinations
(2 to the 3rd
power in this
example)
@CartesianProductTest
@CartesianValueSource(strings = {"A", "B", "C"})
@CartesianValueSource(ints = {1, 2, 3})
@CartesianEnumSource(value = Result.class,
names = {"SKIPPED"},
mode = CartesianEnumSource.Mode.EXCLUDE)
void shouldProduceAllCombinationsForCartesianValueSources(
String x, int y, Result z) {
assertThat(equalsAny(x, "A", "B", "C")).isTrue();
assertThat(Range.closed(1, 3).contains(y)).isTrue();
assertThat(z).isNotNull();
}
Analogous to Jupiter's
@ValueSource and
@EnumSource
Using @CartesianValueSource
and @CartesianEnumSource
Danger Will Robinson!
You must use Pioneer's @CartesianXyxSource
with @CartesianProductTest
Trying to use plain Jupiter sources like
@ValueSource will result in exceptions
@CartesianProductTest
@IntRangeSource(from = 1, to = 4, closed = true)
@LongRangeSource(from = 1000, to = 1005, closed = true)
void shouldWorkWithRangeSources(int x, long y) {
assertThat(Range.closed(1, 4).contains(x)).isTrue();
assertThat(Range.closed(1000L, 1005L).contains(y)).isTrue();
}
Also works with
Pioneer range
sources
Using several of Pioneer's
@XyzRangeSource annotations
with @CartesianProductTest
Can also create custom factory methods
Cartesian Argument Factories
Must be static & return CartesianProductTest.Sets
Use naming convention or factory parameter
in @CartesianProductTest
@CartesianProductTest(factory = "customProduct")
void shouldAllowCustomArgumentFactory(
String greek, Result result, int level) {
assertThat(equalsAny(greek, "Alpha", "Beta", "Gamma")).isTrue();
assertThat(result).isNotNull();
assertThat(Range.closedOpen(0, 5).contains(level)).isTrue();
}
static CartesianProductTest.Sets customProduct() {
return new CartesianProductTest.Sets()
.add("Alpha", "Beta", "Gamma")
.add((Object[]) Result.values())
.addAll(Stream.iterate(0, val -> val + 1).limit(5));
}
Instead, we could name the test
'customProduct' (but, I think using
factory is more understandable)
Using our custom
factory with
@CartesianProductTest
(there are 3 * 3 * 5 = 45 input combos)
Wrap Up
Pioneer has some cool things (fact)
Pioneer has some useful things (fact)
You should probably use them (opinion)
Example Code
https://github.com/sleberknight/junit-pioneering-presentation-code
References
JUnit Pioneer website
https://junit-pioneer.org
On GitHub
https://github.com/junit-pioneer/junit-pioneer
IETF BCP 47
https://tools.ietf.org/html/bcp47
IETF language tag (wikipedia)
https://en.wikipedia.org/wiki/IETF_language_tag
JDK 11 Locale
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Locale.html
Local Helper website
https://lh.2xlibre.net
Photos & Images
An artist's impression of a Pioneer spacecraft on its way to interstellar space
https://commons.wikimedia.org/wiki/File:An_artist%27s_impression_of_a_Pioneer_spacecraft_on_its_way_to_interstellar_space.jpg
One more thing...
https://www.flickr.com/photos/mathoov/4681491052
https://creativecommons.org/licenses/by-nc-nd/2.0/
My Info
sleberknight at
fortitudetec.com
www.fortitudetec.com
@sleberknight
scott.leberknight at
gmail

Contenu connexe

Tendances (20)

Junit and testNG
Junit and testNGJunit and testNG
Junit and testNG
 
Junit
JunitJunit
Junit
 
JUnit- A Unit Testing Framework
JUnit- A Unit Testing FrameworkJUnit- A Unit Testing Framework
JUnit- A Unit Testing Framework
 
Java Unit Testing
Java Unit TestingJava Unit Testing
Java Unit Testing
 
JUnit 5 - The Next Generation of JUnit - Ted's Tool Time
JUnit 5 - The Next Generation of JUnit - Ted's Tool TimeJUnit 5 - The Next Generation of JUnit - Ted's Tool Time
JUnit 5 - The Next Generation of JUnit - Ted's Tool Time
 
JUnit & Mockito, first steps
JUnit & Mockito, first stepsJUnit & Mockito, first steps
JUnit & Mockito, first steps
 
JUNit Presentation
JUNit PresentationJUNit Presentation
JUNit Presentation
 
Unit testing with JUnit
Unit testing with JUnitUnit testing with JUnit
Unit testing with JUnit
 
JUnit 4
JUnit 4JUnit 4
JUnit 4
 
Advanced junit and mockito
Advanced junit and mockitoAdvanced junit and mockito
Advanced junit and mockito
 
Introduction To J unit
Introduction To J unitIntroduction To J unit
Introduction To J unit
 
J Unit
J UnitJ Unit
J Unit
 
JUnit Presentation
JUnit PresentationJUnit Presentation
JUnit Presentation
 
Introduction to JUnit
Introduction to JUnitIntroduction to JUnit
Introduction to JUnit
 
Unit testing with JUnit
Unit testing with JUnitUnit testing with JUnit
Unit testing with JUnit
 
Unit Testing in Java
Unit Testing in JavaUnit Testing in Java
Unit Testing in Java
 
Test driven development - JUnit basics and best practices
Test driven development - JUnit basics and best practicesTest driven development - JUnit basics and best practices
Test driven development - JUnit basics and best practices
 
Unit testing with Junit
Unit testing with JunitUnit testing with Junit
Unit testing with Junit
 
Junit
JunitJunit
Junit
 
testng
testngtestng
testng
 

Similaire à JUnit Pioneer

Pragmatic unittestingwithj unit
Pragmatic unittestingwithj unitPragmatic unittestingwithj unit
Pragmatic unittestingwithj unitliminescence
 
Unittesting JavaScript with Evidence
Unittesting JavaScript with EvidenceUnittesting JavaScript with Evidence
Unittesting JavaScript with EvidenceTobie Langel
 
Testing Java Code Effectively
Testing Java Code EffectivelyTesting Java Code Effectively
Testing Java Code EffectivelyAndres Almiray
 
Js 单元测试框架介绍
Js 单元测试框架介绍Js 单元测试框架介绍
Js 单元测试框架介绍louieuser
 
Understanding JavaScript Testing
Understanding JavaScript TestingUnderstanding JavaScript Testing
Understanding JavaScript Testingjeresig
 
Introduction to nsubstitute
Introduction to nsubstituteIntroduction to nsubstitute
Introduction to nsubstituteSuresh Loganatha
 
Apex Testing and Best Practices
Apex Testing and Best PracticesApex Testing and Best Practices
Apex Testing and Best PracticesJitendra Zaa
 
Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4jeresig
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good TestsTomek Kaczanowski
 
Confitura 2012 Bad Tests, Good Tests
Confitura 2012 Bad Tests, Good TestsConfitura 2012 Bad Tests, Good Tests
Confitura 2012 Bad Tests, Good TestsTomek Kaczanowski
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good TestsTomek Kaczanowski
 
EVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMER
EVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMEREVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMER
EVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMERAndrey Karpov
 
STAMP Descartes Presentation
STAMP Descartes PresentationSTAMP Descartes Presentation
STAMP Descartes PresentationSTAMP Project
 
Unit & Automation Testing in Android - Stanislav Gatsev, Melon
Unit & Automation Testing in Android - Stanislav Gatsev, MelonUnit & Automation Testing in Android - Stanislav Gatsev, Melon
Unit & Automation Testing in Android - Stanislav Gatsev, MelonbeITconference
 
JUnit5 and TestContainers
JUnit5 and TestContainersJUnit5 and TestContainers
JUnit5 and TestContainersSunghyouk Bae
 
Test-driven Development for TYPO3
Test-driven Development for TYPO3Test-driven Development for TYPO3
Test-driven Development for TYPO3Oliver Klee
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotationjavatwo2011
 

Similaire à JUnit Pioneer (20)

Pragmatic unittestingwithj unit
Pragmatic unittestingwithj unitPragmatic unittestingwithj unit
Pragmatic unittestingwithj unit
 
Unittesting JavaScript with Evidence
Unittesting JavaScript with EvidenceUnittesting JavaScript with Evidence
Unittesting JavaScript with Evidence
 
Testing Java Code Effectively
Testing Java Code EffectivelyTesting Java Code Effectively
Testing Java Code Effectively
 
Junit_.pptx
Junit_.pptxJunit_.pptx
Junit_.pptx
 
Js 单元测试框架介绍
Js 单元测试框架介绍Js 单元测试框架介绍
Js 单元测试框架介绍
 
Understanding JavaScript Testing
Understanding JavaScript TestingUnderstanding JavaScript Testing
Understanding JavaScript Testing
 
Introduction to nsubstitute
Introduction to nsubstituteIntroduction to nsubstitute
Introduction to nsubstitute
 
Apex Testing and Best Practices
Apex Testing and Best PracticesApex Testing and Best Practices
Apex Testing and Best Practices
 
Google guava
Google guavaGoogle guava
Google guava
 
Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4Testing, Performance Analysis, and jQuery 1.4
Testing, Performance Analysis, and jQuery 1.4
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
 
Confitura 2012 Bad Tests, Good Tests
Confitura 2012 Bad Tests, Good TestsConfitura 2012 Bad Tests, Good Tests
Confitura 2012 Bad Tests, Good Tests
 
Junit 5 - Maior e melhor
Junit 5 - Maior e melhorJunit 5 - Maior e melhor
Junit 5 - Maior e melhor
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
 
EVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMER
EVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMEREVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMER
EVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMER
 
STAMP Descartes Presentation
STAMP Descartes PresentationSTAMP Descartes Presentation
STAMP Descartes Presentation
 
Unit & Automation Testing in Android - Stanislav Gatsev, Melon
Unit & Automation Testing in Android - Stanislav Gatsev, MelonUnit & Automation Testing in Android - Stanislav Gatsev, Melon
Unit & Automation Testing in Android - Stanislav Gatsev, Melon
 
JUnit5 and TestContainers
JUnit5 and TestContainersJUnit5 and TestContainers
JUnit5 and TestContainers
 
Test-driven Development for TYPO3
Test-driven Development for TYPO3Test-driven Development for TYPO3
Test-driven Development for TYPO3
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 

Plus de Scott Leberknight (20)

JShell & ki
JShell & kiJShell & ki
JShell & ki
 
JDKs 10 to 14 (and beyond)
JDKs 10 to 14 (and beyond)JDKs 10 to 14 (and beyond)
JDKs 10 to 14 (and beyond)
 
Unit Testing
Unit TestingUnit Testing
Unit Testing
 
SDKMAN!
SDKMAN!SDKMAN!
SDKMAN!
 
AWS Lambda
AWS LambdaAWS Lambda
AWS Lambda
 
Dropwizard
DropwizardDropwizard
Dropwizard
 
RESTful Web Services with Jersey
RESTful Web Services with JerseyRESTful Web Services with Jersey
RESTful Web Services with Jersey
 
httpie
httpiehttpie
httpie
 
jps & jvmtop
jps & jvmtopjps & jvmtop
jps & jvmtop
 
Cloudera Impala, updated for v1.0
Cloudera Impala, updated for v1.0Cloudera Impala, updated for v1.0
Cloudera Impala, updated for v1.0
 
Java 8 Lambda Expressions
Java 8 Lambda ExpressionsJava 8 Lambda Expressions
Java 8 Lambda Expressions
 
Google Guava
Google GuavaGoogle Guava
Google Guava
 
Cloudera Impala
Cloudera ImpalaCloudera Impala
Cloudera Impala
 
iOS
iOSiOS
iOS
 
Apache ZooKeeper
Apache ZooKeeperApache ZooKeeper
Apache ZooKeeper
 
HBase Lightning Talk
HBase Lightning TalkHBase Lightning Talk
HBase Lightning Talk
 
Hadoop
HadoopHadoop
Hadoop
 
wtf is in Java/JDK/wtf7?
wtf is in Java/JDK/wtf7?wtf is in Java/JDK/wtf7?
wtf is in Java/JDK/wtf7?
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScript
 
Polyglot Persistence
Polyglot PersistencePolyglot Persistence
Polyglot Persistence
 

Dernier

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 

Dernier (20)

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 

JUnit Pioneer

  • 2. “JUnit Pioneer is an extension pack for JUnit 5 or, to be more precise, for the Jupiter engine”
  • 3. Recap: JUnit Extensions Provide a way to extend JUnit’s core features Well-defined extension API and lifecycle
  • 4. Simple Example @ParameterizedTest @RandomIntSource(min = 5, max = 10, count = 50) void shouldDoSomethingWithRandomInts(int value) { // test code... } Injecting method parameters into tests Example from https://github.com/kiwiproject/kiwi-test/
  • 5. @RegisterExtension static final CuratorTestingServerExtension ZK_TEST_SERVER = new CuratorTestingServerExtension(); Another Example Start and stop a ZooKeeper server before & after tests Example from https://github.com/kiwiproject/kiwi-test/
  • 6. Pioneer Extensions A collection of useful Jupiter extensions Easy to integrate into your tests
  • 7. Pioneer Extensions Cartesian product Locale & TimeZone Environment Vars Range sources Issue Info Disabling tests Report entries Stdin & Stdout System props Vintage tests Stopwatch! * as of 2021-03-04 *
  • 8. System Properties @SetSystemProperty(key = "user", value = "bob") @SetSystemProperty(key = "id", value = "42") class SystemPropertyTest { @Test @ClearSystemProperty(key = "user") void testWithoutUserProperty() { ... } @Test @SetSystemProperty(key = "pwd", value = "12345") void anotherTest() { ... } }
  • 9. Environment Variables @SetEnvironmentVariable(key = "PWD", value="/tmp") @ClearEnvironmentVariable(key = "PS1") class EnvVarsTest { @ClearEnvironmentVariable(key = "PWD") void testWithoutWorkingDirEnvVar() { ... } @SetEnvironmentVariable(key = "USER", value = "alice") void testWithCustomUser() { ... } }
  • 10. Default TimeZone @DefaultTimeZone("America/Mexico_City") class DefaultTimeZoneTest { @Test void testInMexicoCity() { assertThat(TimeZone.getDefault()).isEqualTo( TimeZone.getTimeZone("America/Mexico_City")); } @Test @DefaultTimeZone("Mexico/BajaSur") void testInBajaSur() { ... } }
  • 11. Default Locale @DefaultLocale("es") class DefaultLocaleTest { @Test void testWithDefaultFromClass() { assertThat(Locale.getDefault()) .isEqualTo(new Locale("es")); } @Test @DefaultLocale(language = "nan", country = "TW", variant = "Hant") void testUsingAllAttributes() { assertThat(Locale.getDefault()).isEqualTo( new Locale("nan", "TW", "Hant")); } }
  • 12. Having Issues? public class SystemOutIssueProcessor implements IssueProcessor { @Override public void processTestResults(List<IssueTestSuite> suites) { // do something with each test suite } } @Test @Issue("JUPI-1234") void shouldFix1234() { // test code for issue JUPI-1234 } #1 Annotate #2 Define processor
  • 14. I need those TPS reports... class ReportEntriesTest { @Test @ReportEntry("I'm Going To Need Those TPS Reports ASAP") void testWithReportEntry() { ... } @Test @ReportEntry(key = "result", value = "success", when = PublishCondition.ON_SUCCESS) @ReportEntry(key = "result", value = "failed", when = ReportEntry.PublishCondition.ON_FAILURE) void testWithConditionalEntries() { ... } } #1 Annotate
  • 15. public class SimpleTestExecutionListener implements TestExecutionListener { ... } #2 Create a JUnit TestExecutionListener com.fortitudetec.junit.pioneering.SimpleTestExecutionListener META-INF/services/org.junit.platform.launcher.TestExecutionListener #3 Register implementation
  • 16. Disabling on display name Selectively disable parameterized tests Specify substrings and/or regex to match... ...and disable any tests with a matching name
  • 17. @DisableIfDisplayName(contains = "42") @ParameterizedTest(name = "Test scenario {0}") @ValueSource(ints = {1, 24, 42, 84, 168, 420, 4200, 4242, 17640}) void shouldDisableUsingStringContains(int value) { if (String.valueOf(value).contains("42")) { fail("Should not have received %s", value); } } Using a substring to specify disabling condition matching against the generated test name
  • 18. @DisableIfDisplayName(matches = ".*d{3}-d{2}-d{4}.*") @ParameterizedTest(name = "Test scenario {0}") @ValueSource(strings = { "42", "123-45-6789", "400", "234-56-7890", "888" }) void shouldDisableUsingRegex(String value) { failIfContainsAny(value, "123-45-6789", "234-56-7890"); } Or use a regular expression
  • 19. @DisableIfDisplayName(contains = {"42", "84"}, matches = ".*d{3}-d{2}-d{4}.*") @ParameterizedTest(name = "Test scenario {0}") @ValueSource(strings = { "24", "42", "123-45-6789", "400", "234-56-7890", "888" }) void shouldDisableUsingContainsAndMatches(String value) { failIfContainsAny(value, "42", "84", "123-45-6789", "234-56-7890"); } or use both...
  • 20. @DisableIfDisplayName(matches = ".*[0-9][3|5]") @ParameterizedTest(name = "Product: FTCH-000-{0}") @RandomIntSource(min = 0, max = 1_000, count = 500) void shouldDisableWhenProductCodeEndsWith_X3_Or_X5(int code) { var codeString = String.valueOf(code); if (PRODUCT_NUMBER_PATTERN.matcher(codeString).matches()) { fail("Should not have received %d", code); } } Combine a regex with randomized test input @RandomIntSource from https://github.com/kiwiproject/kiwi-test/
  • 21.
  • 22. Do, or do not, there is no try class RetryingAnnotationTest { @RetryingTest(2) void shouldFail() { flakyObject.failsFirstTwoTimes(); } @RetryingTest(3) void shouldPass() { flakyObject.failsFirstTwoTimes(); } }
  • 24. Stdin @Test @StdIo({"foo", "bar", "baz"}) void shouldReadFromStandardInput() throws IOException { var reader = new BufferedReader(new InputStreamReader(System.in)); assertThat(reader.readLine()).isEqualTo("foo"); assertThat(reader.readLine()).isEqualTo("bar"); assertThat(reader.readLine()).isEqualTo("baz"); } @Test @StdIo({"1", "2"}) void shouldCaptureStdIn(StdIn stdIn) throws IOException { var reader = new BufferedReader(new InputStreamReader(System.in)); reader.readLine(); reader.readLine(); assertThat(stdIn.capturedLines()).containsExactly("1", "2"); }
  • 25. & Stdout @Test @StdIo void shouldInterceptStandardOutput(StdOut stdOut) { System.out.println("The answer is 24"); System.out.println("No, the real answer is always 42"); assertThat(stdOut.capturedLines()).containsExactly( "The answer is 24", "No, the real answer is always 42" ); }
  • 26. How long did that take? class StopwatchTest { @RepeatedTest(value = 10) @Stopwatch void shouldReportElapsedTime() { ... } } Elapsed time will be published via a TestReporter, so that a TestExecutionListener can receive it
  • 27. Out on the range... Create ranges of ints, longs, etc. as test input Use with parameterized tests Specify lower and upper bounds Upper bound can be inclusive or exclusive
  • 28. @ParameterizedTest @IntRangeSource(from = 0, to = 10) void shouldGenerateIntegers(int value) { assertThat(value).isBetween(0, 9); failIfSeeUpperBound(value, 10); } 'from' is inclusive; 'to' is exclusive by default
  • 30. @ParameterizedTest @LongRangeSource(from = -100_000, to = 100_000, step = 5_000) void shouldAllowChangingTheStep(long value) { assertThat(value).isBetween(-100_000L, 95_000L); failIfSeeUpperBound(value, 100_000); } change difference between generated values using 'step'
  • 31. @ParameterizedTest @DoubleRangeSource(from = 0.0, to = 10.0, step = 0.5, closed = true) void shouldAllowClosedRanges(double value) { assertThat(value).isBetween(0.0, 10.0); } make a closed range
  • 32. The best vintage? Pioneer's vintage @Test replaces JUnit 4 @Test... ...but marks the method as a Jupiter test Supports expected and timeout parameters
  • 33.
  • 35. Generate cartesian product of all inputs Use @CartesianProductTest instead of Jupiter @Test annotations Pioneer provides custom argument sources You can also provide a custom @ArgumentsSource
  • 36. @CartesianProductTest({"0", "1"}) void shouldProduceAllCombinationsOfThree(String x, String y, String z) { List.of(x, y, z).forEach(this::assertIsZeroOrOne); } specify a String array produces all input combinations (2 to the 3rd power in this example)
  • 37. @CartesianProductTest @CartesianValueSource(strings = {"A", "B", "C"}) @CartesianValueSource(ints = {1, 2, 3}) @CartesianEnumSource(value = Result.class, names = {"SKIPPED"}, mode = CartesianEnumSource.Mode.EXCLUDE) void shouldProduceAllCombinationsForCartesianValueSources( String x, int y, Result z) { assertThat(equalsAny(x, "A", "B", "C")).isTrue(); assertThat(Range.closed(1, 3).contains(y)).isTrue(); assertThat(z).isNotNull(); } Analogous to Jupiter's @ValueSource and @EnumSource
  • 39. Danger Will Robinson! You must use Pioneer's @CartesianXyxSource with @CartesianProductTest Trying to use plain Jupiter sources like @ValueSource will result in exceptions
  • 40. @CartesianProductTest @IntRangeSource(from = 1, to = 4, closed = true) @LongRangeSource(from = 1000, to = 1005, closed = true) void shouldWorkWithRangeSources(int x, long y) { assertThat(Range.closed(1, 4).contains(x)).isTrue(); assertThat(Range.closed(1000L, 1005L).contains(y)).isTrue(); } Also works with Pioneer range sources
  • 41. Using several of Pioneer's @XyzRangeSource annotations with @CartesianProductTest
  • 42. Can also create custom factory methods Cartesian Argument Factories Must be static & return CartesianProductTest.Sets Use naming convention or factory parameter in @CartesianProductTest
  • 43. @CartesianProductTest(factory = "customProduct") void shouldAllowCustomArgumentFactory( String greek, Result result, int level) { assertThat(equalsAny(greek, "Alpha", "Beta", "Gamma")).isTrue(); assertThat(result).isNotNull(); assertThat(Range.closedOpen(0, 5).contains(level)).isTrue(); } static CartesianProductTest.Sets customProduct() { return new CartesianProductTest.Sets() .add("Alpha", "Beta", "Gamma") .add((Object[]) Result.values()) .addAll(Stream.iterate(0, val -> val + 1).limit(5)); } Instead, we could name the test 'customProduct' (but, I think using factory is more understandable)
  • 44. Using our custom factory with @CartesianProductTest (there are 3 * 3 * 5 = 45 input combos)
  • 45. Wrap Up Pioneer has some cool things (fact) Pioneer has some useful things (fact) You should probably use them (opinion)
  • 47. References JUnit Pioneer website https://junit-pioneer.org On GitHub https://github.com/junit-pioneer/junit-pioneer IETF BCP 47 https://tools.ietf.org/html/bcp47 IETF language tag (wikipedia) https://en.wikipedia.org/wiki/IETF_language_tag JDK 11 Locale https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Locale.html Local Helper website https://lh.2xlibre.net
  • 48. Photos & Images An artist's impression of a Pioneer spacecraft on its way to interstellar space https://commons.wikimedia.org/wiki/File:An_artist%27s_impression_of_a_Pioneer_spacecraft_on_its_way_to_interstellar_space.jpg One more thing... https://www.flickr.com/photos/mathoov/4681491052 https://creativecommons.org/licenses/by-nc-nd/2.0/