SlideShare a Scribd company logo
1 of 24
Test Time Bombs
lightning talk
Wojciech Bulaty
18 Aug 2015
Me (Wojtek)
9 years of software development
5+ years of TDD, pair programming, etc.
Problem
● Problem
– One failing test and the build is red
– Long running builds? Harder to notice new failing tests!
– Test failing for a long time (temporary integration issues?)
● Possible solutions
– Suppress a failing test for a day? (green build again)
– Set a reminder to look at a test next time somebody sees it? (red
for a month)
Specific example
● Integration test failing because of network
issues
Common solutions
● Supress the test by @Ignore
– Who will un-ignore it?
– When?
● //TODO comments never get actioned
● Card on the board
● JIRA ticket
● Mute tests in TeamCity (local build remain red,
cannot check in)
Proposed solution
● Test Time Bomb
● Blows up the test on a specified day
package wb;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Clock;
import java.util.Date;
import static java.lang.String.format;
public class Timebomb {
private final Clock clock;
Timebomb(Clock
public static Tim
ebomb timebomb() {
return new Timebomb(Clock.systemUTC());
}
public boolean blowUpAfter(int year, int month, int dayOfMonth, String explanation) {
try {
blowUpAfter(new SimpleDateFormat("yyyy-MM-dd").parse(format("%s-%s-%s", year, month, dayOfMonth)), explanation);
} catch (ParseException e) {
throw new RuntimeException(e);
}
return true;
}
public boolean blowUpAfter(Date dateToBlowUp, String explanation) {
Date now = new Date(clock.millis());
if(now.compareTo(dateToBlowUp)>0) {
throw new AssertionError("Requested timebomb, "+ explanation);
}
return true;
}
package wb;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Clock;
import java.util.Date;
import static java.lang.String.format;
public class Timebomb {
private final Clock clock;
Timebolock = clock;
}
public static Timebomb timebomb() {
return new Timebomb(Clock.systemUTC());
}
public boolean blowUpAfter(int year, int month, int dayOfMonth, String explanation) {
try {
blowUpAfter(new SimpleDateFormat("yyyy-MM-dd").parse(format("%s-%s-%s", year, month, dayOfMonth)), explanation);
} catch (ParseException e) {
throw new RuntimeException(e);
}
return true;
}
public boolean blowUpAfter(Date dateToBlowUp, String explanation) {
Date now = new Date(clock.millis());
if(now.compareTo(dateToBlowUp)>0) {
throw new AssertionError("Requested timebomb, "+ explanation);
}
return true;
}
package wb;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Clock;
import java.util.Date;
import static java.lang.String.format;
public class Timebomb {
private final Clock clock;
Timebomb(Clock clock) {
this.clock
public static Timebomb timebomb() {
return n
ew Timebomb(Clock.systemUTC());
}
public boolean blowUpAfter(int year, int month, int dayOfMonth, String explanation) {
try {
blowUpAfter(new SimpleDateFormat("yyyy-MM-dd").parse(format("%s-%s-%s", year, month, dayOfMonth)), explanation);
} catch (ParseException e) {
throw new RuntimeException(e);
}
return true;
}
public boolean blowUpAfter(Date dateToBlowUp, String explanation) {
Date now = new Date(clock.millis());
if(now.compareTo(dateToBlowUp)>0) {
throw new AssertionError("Requested timebomb, "+ explanation);
}
return false;
}
package wb;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Clock;
import java.util.Date;
import static java.lang.String.format;
public class Timebomb {
private final Clock clock;
Timebo
m
public static Tim
ebomb timebomb() {
return new Timebomb(Clock.systemUTC());
}
public boolean blowUpAfter(int year, int month, int dayOfMonth, String explanation) {
try { explanation
);
} catch (ParseException e) {
throw new RuntimeException(e);
}
return true;
}
public boolean blowUpAfter(Date dateToBlowUp, String explanation) {
Date now = new Date(clock.millis());
if(now.compareTo(dateToBlowUp)>0) {
throw new AssertionError("Requested timebomb, "+ explanation);
}
return false;
package wb;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Clock;
import java.util.Date;
import static java.lang.String.format;
public class Timebomb {
private final Clock clock;
Timebomb(Clock clock) {
this.cl
}
public static Timebomb timebomb() {
return new Timebomb(Clock.systemUTC());
}
public boolean blowUpAfter(int year, int month, int dayOfMonth, String explanation) {
try {
return blowUpAfter(new SimpleDateFormat("yyyy-MM-dd").parse(format("%s-%s-%s", year, month, dayOfMonth)), explanation);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
public boolean blowUpAfter(Date dateToBlowUp, String explanation) {
Date now = new Date(clock.millis());
if(now.compareTo(dateToBlowUp)>0) {
throw new AssertionError("Requested timebomb, "+ explanation);
}
return false;
}
package wb;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Clock;
import java.util.Date;
import static java.lang.String.format;
public class Timebomb {
private final Clock clock;
Timebomb(Clock clock) {
this.clock = clock;
}
public static Timebomb timebomb() {
return new Timebomb(Clock.systemUTC());
}
public boolean blowUpAfter(int year, int month, int dayOfMonth, String explanation) {
try {
return blowUpAfter(new SimpleDateFormat("yyyy-MM-dd").parse(format("%s-%s-%s", year, month, dayOfMonth)), explanation);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
public boolean blowUpAfter(Date dateToBlowUp, String explanation) {
Date now = new Date(clock.millis());
if(now.compareTo(dateToBlowUp)>0) {
throw new AssertionError("Requested timebomb, "+ explanation);
}
return false;
}
import org.junit.Test;
import wb.TestData;
import java.nio.file.Path;
import java.nio.file.Paths;
import static wb.Timebomb.timebomb;
public class SftpClientIntegrationTest {
private Path localPath = Paths.get("/testing/testFile1");
private Path remotePath = Paths.get("/testing/testFile1");
private String hostname = "aHost.mycompany.com";
@Test
public void downloadsAFile() throws Exception {
if(timebomb().blowUpAfter(2015, 8, 7, "chase with Paul from operations the network connectivity")) {
new SftpClient(hostname).download(remotePath, localPath);
}
}
@Test
public void supportsAllSftpServers() throws Exception {
String onlyWorkingTestSite = "testEnvUK";
timebomb().blowUpAfter(2015, 9, 1, "chase with Mike from SA team about the test environments other than " +
onlyWorkingTestSite);
TestData.allSftpServers()
.stream().filter(hostname -> hostname.startsWith(onlyWorkingTestSite))
.forEach(hostname -> new SftpClient(hostname).listDirectory(remotePath));
}
import org.junit.Test;
import wb.TestData;
import java.nio.file.Path;
import java.nio.file.Paths;
import static wb.Timebomb.timebomb;
public class SftpClientIntegrationTest {
private Path localPath = Paths.get("/testing/testFile1");
private Path remotePath = Paths.get("/testing/testFile1");
private String hostname = "aHost.mycompany.com";
@Test
public void downloadsAFile() throws Exception {
if(timebomb().blowUpAfter(2015, 8, 7, "chase with Paul from operations the network connectivity")) {
new SftpClient(hostname).download(remotePath, localPath);
}
}
@Test
public void supportsAllSftpServers() throws Exception {
String onlyWorkingTestSite = "testEnvUK";
timebomb().blowUpAfter(2015, 9, 1, "chase with Mike from SA team about the test environments other than " +
onlyWorkingTestSite);
TestData.allSftpServers()
.stream().filter(hostname -> hostname.startsWith(onlyWorkingTestSite))
.forEach(hostname -> new SftpClient(hostname).listDirectory(remotePath));
}
import org.junit.Test;
import wb.TestData;
import java.nio.file.Path;
import java.nio.file.Paths;
import static wb.Timebomb.timebomb;
public class SftpClientIntegrationTest {
private Path localPath = Paths.get("/testing/testFile1");
private Path remotePath = Paths.get("/testing/testFile1");
private String hostname = "aHost.mycompany.com";
@Test
public void downloadsAFile() throws Exception {
if(timebomb().blowUpAfter(2015, 8, 7, "chase with Paul from operations the network connectivity")) {
new SftpClient(hostname).download(remotePath, localPath);
}
}
@Test
public void supportsAllSftpServers() throws Exception {
String onlyWorkingTestSite = "testEnvUK";
timebomb().blowUpAfter(2015, 9, 1, "chase with Mike from SA team about the test environments other than " +
onlyWorkingTestSite);
TestData.allSftpServers()
.stream().filter(hostname -> hostname.startsWith(onlyWorkingTestSite))
.forEach(hostname -> new SftpClient(hostname).listDirectory(remotePath));
}
import org.junit.Test;
import wb.TestData;
import java.nio.file.Path;
import java.nio.file.Paths;
import static wb.Timebomb.timebomb;
public class SftpClientIntegrationTest {
private Path localPath = Paths.get("/testing/testFile1");
private Path remotePath = Paths.get("/testing/testFile1");
private String hostname = "aHost.mycompany.com";
@Test
public void downloadsAFile() throws Exception {
if(timebomb().blowUpAfter(2015, 8, 7, "chase with Paul from operations the network connectivity")) {
new SftpClient(hostname).download(remotePath, localPath);
}
}
@Test
public void supportsAllSftpServers() throws Exception {
String onlyWorkingTestSite = "testEnvUK";
timebomb().blowUpAfter(2015, 9, 1, "chase with Mike from SA team about the test environments other than " +
onlyWorkingTestSite);
TestData.allSftpServers()
.stream().filter(hostname -> hostname.startsWith(onlyWorkingTestSite))
.forEach(hostname -> new SftpClient(hostname).listDirectory(remotePath));
}
import org.junit.Test;
import wb.TestData;
import java.nio.file.Path;
import java.nio.file.Paths;
import static wb.Timebomb.timebomb;
public class SftpClientIntegrationTest {
private Path localPath = Paths.get("/testing/testFile1");
private Path remotePath = Paths.get("/testing/testFile1");
private String hostname = "aHost.mycompany.com";
@Test
public void downloadsAFile() throws Exception {
if(timebomb().blowUpAfter(2015, 8, 7, "chase with Paul from operations the network connectivity")) {
new SftpClient(hostname).download(remotePath, localPath);
}
}
@Test
public void supportsAllSftpServers() throws Exception {
String onlyWorkingTestSite = "testEnvUK";
timebomb().blowUpAfter(2015, 9, 1, "chase with Mike from SA team about the test environments other than " +
onlyWorkingTestSite);
TestData.allSftpServers()
.stream().filter(hostname -> hostname.startsWith(onlyWorkingTestSite))
.forEach(hostname -> new SftpClient(hostname).listDirectory(remotePath));
}
import org.junit.Test;
import wb.TestData;
import java.nio.file.Path;
import java.nio.file.Paths;
import static wb.Timebomb.timebomb;
public class SftpClientIntegrationTest {
private Path localPath = Paths.get("/testing/testFile1");
private Path remotePath = Paths.get("/testing/testFile1");
private String hostname = "aHost.mycompany.com";
@Test
public void downloadsAFile() throws Exception {
if(timebomb().blowUpAfter(2015, 8, 7, "chase with Paul from operations the network connectivity")) {
new SftpClient(hostname).download(remotePath, localPath);
}
}
@Test
public void supportsAllSftpServers() throws Exception {
String onlyWorkingTestSite = "testEnvUK";
timebomb().blowUpAfter(2015, 9, 1, "chase with Mike from SA team about the test environments other than " +
onlyWorkingTestSite);
TestData.allSftpServers()
.stream().filter(hostname -> hostname.startsWith(onlyWorkingTestSite))
.forEach(hostname -> new SftpClient(hostname).listDirectory(remotePath));
}
import org.junit.Test;
import wb.TestData;
import java.nio.file.Path;
import java.nio.file.Paths;
import static wb.Timebomb.timebomb;
public class SftpClientIntegrationTest {
private Path localPath = Paths.get("/testing/testFile1");
private Path remotePath = Paths.get("/testing/testFile1");
private String hostname = "aHost.mycompany.com";
@Test
public void downloadsAFile() throws Exception {
if(timebomb().blowUpAfter(2015, 8, 7, "chase with Paul from operations the network connectivity")) {
new SftpClient(hostname).download(remotePath, localPath);
}
}
@Test
public void supportsAllSftpServers() throws Exception {
String onlyWorkingTestSite = "testEnvUK";
timebomb().blowUpAfter(2015, 9, 1, "chase with Mike from SA team about the test environments other than " +
onlyWorkingTestSite);
TestData.allSftpServers()
.stream().filter(hostname -> hostname.startsWith(onlyWorkingTestSite))
.forEach(hostname -> new SftpClient(hostname).listDirectory(remotePath));
}
import org.junit.Test;
import wb.TestData;
import java.nio.file.Path;
import java.nio.file.Paths;
import static wb.Timebomb.timebomb;
public class SftpClientIntegrationTest {
private Path localPath = Paths.get("/testing/testFile1");
private Path remotePath = Paths.get("/testing/testFile1");
private String hostname = "aHost.mycompany.com";
@Test
public void downloadsAFile() throws Exception {
if(timebomb().blowUpAfter(2015, 8, 7, "chase with Paul from operations the network connectivity")) {
new SftpClient(hostname).download(remotePath, localPath);
}
}
@Test
public void supportsAllSftpServers() throws Exception {
String onlyWorkingTestSite = "testEnvUK";
timebomb().blowUpAfter(2015, 9, 1, "chase with Mike from SA team about the test environments other than " +
onlyWorkingTestSite);
TestData.allSftpServers()
.stream().filter(hostname -> hostname.startsWith(onlyWorkingTestSite))
.forEach(hostname -> new SftpClient(hostname).listDirectory(remotePath));
}
import org.junit.Test;
import wb.TestData;
import java.nio.file.Path;
import java.nio.file.Paths;
import static wb.Timebomb.timebomb;
public class SftpClientIntegrationTest {
private Path localPath = Paths.get("/testing/testFile1");
private Path remotePath = Paths.get("/testing/testFile1");
private String hostname = "aHost.mycompany.com";
@Test
public void downloadsAFile() throws Exception {
if(timebomb().blowUpAfter(2015, 8, 7, "chase with Paul from operations the network connectivity")) {
new SftpClient(hostname).download(remotePath, localPath);
}
}
@Test
public void supportsAllSftpServers() throws Exception {
String onlyWorkingTestSite = "testEnvUK";
timebomb().blowUpAfter(2015, 9, 1, "chase with Mike from SA team about the test environments other than " +
onlyWorkingTestSite);
TestData.allSftpServers()
.stream().filter(hostname -> hostname.startsWith(onlyWorkingTestSite))
.forEach(hostname -> new SftpClient(hostname).listDirectory(remotePath));
}
Tradeoffs
● Will not see if the test is flaky for the period of
time.
● If application is not build/test not run for a long
time, the timebomb will not go off.
Credits & Thanks
● Not my idea
● Common practice within a team I used to work
with in the past
Feedback?
Questions?
http://test-driven-development.com/

More Related Content

What's hot

Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleThierry Wasylczenko
 
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)Danny Preussler
 
Testing basics for developers
Testing basics for developersTesting basics for developers
Testing basics for developersAnton Udovychenko
 
Gradle For Beginners (Serbian Developer Conference 2013 english)
Gradle For Beginners (Serbian Developer Conference 2013 english)Gradle For Beginners (Serbian Developer Conference 2013 english)
Gradle For Beginners (Serbian Developer Conference 2013 english)Joachim Baumann
 
TDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving TestingTDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving TestingDavid Rodenas
 
Spock: A Highly Logical Way To Test
Spock: A Highly Logical Way To TestSpock: A Highly Logical Way To Test
Spock: A Highly Logical Way To TestHoward Lewis Ship
 
Quickly Testing Qt Desktop Applications
Quickly Testing Qt Desktop ApplicationsQuickly Testing Qt Desktop Applications
Quickly Testing Qt Desktop ApplicationsClare Macrae
 
Introduction to ParSeq: to make asynchronous java easier
Introduction to ParSeq: to make asynchronous java easierIntroduction to ParSeq: to make asynchronous java easier
Introduction to ParSeq: to make asynchronous java easierJunchuan Wang
 
Unit testing with Qt test
Unit testing with Qt testUnit testing with Qt test
Unit testing with Qt testDavide Coppola
 
Google C++ Testing Framework in Visual Studio 2008
Google C++ Testing Framework in Visual Studio 2008Google C++ Testing Framework in Visual Studio 2008
Google C++ Testing Framework in Visual Studio 2008Andrea Francia
 
Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxDavid Rodenas
 
The Ring programming language version 1.8 book - Part 95 of 202
The Ring programming language version 1.8 book - Part 95 of 202The Ring programming language version 1.8 book - Part 95 of 202
The Ring programming language version 1.8 book - Part 95 of 202Mahmoud Samir Fayed
 

What's hot (20)

Android TDD & CI
Android TDD & CIAndroid TDD & CI
Android TDD & CI
 
Introduzione al TDD
Introduzione al TDDIntroduzione al TDD
Introduzione al TDD
 
Testing in-groovy
Testing in-groovyTesting in-groovy
Testing in-groovy
 
Easy Button
Easy ButtonEasy Button
Easy Button
 
#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
15 tips to improve your unit tests (Droidcon Berlin 2016 Barcamp)
 
Testing basics for developers
Testing basics for developersTesting basics for developers
Testing basics for developers
 
Gradle For Beginners (Serbian Developer Conference 2013 english)
Gradle For Beginners (Serbian Developer Conference 2013 english)Gradle For Beginners (Serbian Developer Conference 2013 english)
Gradle For Beginners (Serbian Developer Conference 2013 english)
 
TDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving TestingTDD CrashCourse Part4: Improving Testing
TDD CrashCourse Part4: Improving Testing
 
Testing with PostgreSQL
Testing with PostgreSQLTesting with PostgreSQL
Testing with PostgreSQL
 
Bab3of
Bab3ofBab3of
Bab3of
 
Spock: A Highly Logical Way To Test
Spock: A Highly Logical Way To TestSpock: A Highly Logical Way To Test
Spock: A Highly Logical Way To Test
 
Testing Spring Applications
Testing Spring ApplicationsTesting Spring Applications
Testing Spring Applications
 
Quickly Testing Qt Desktop Applications
Quickly Testing Qt Desktop ApplicationsQuickly Testing Qt Desktop Applications
Quickly Testing Qt Desktop Applications
 
Introduction to ParSeq: to make asynchronous java easier
Introduction to ParSeq: to make asynchronous java easierIntroduction to ParSeq: to make asynchronous java easier
Introduction to ParSeq: to make asynchronous java easier
 
Unit testing with Qt test
Unit testing with Qt testUnit testing with Qt test
Unit testing with Qt test
 
Google C++ Testing Framework in Visual Studio 2008
Google C++ Testing Framework in Visual Studio 2008Google C++ Testing Framework in Visual Studio 2008
Google C++ Testing Framework in Visual Studio 2008
 
Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicox
 
The Ring programming language version 1.8 book - Part 95 of 202
The Ring programming language version 1.8 book - Part 95 of 202The Ring programming language version 1.8 book - Part 95 of 202
The Ring programming language version 1.8 book - Part 95 of 202
 

Viewers also liked

A demographic timebomb
A demographic timebombA demographic timebomb
A demographic timebombblessedkkr
 
A demographic timebomb correction
A demographic timebomb correctionA demographic timebomb correction
A demographic timebomb correctionblessedkkr
 
Negative externalities
Negative externalitiesNegative externalities
Negative externalitiesmattbentley34
 
The Human Population Challenge: From “Population Bomb” to “Demographic Crisis”
The Human Population Challenge: From “Population Bomb” to “Demographic Crisis”The Human Population Challenge: From “Population Bomb” to “Demographic Crisis”
The Human Population Challenge: From “Population Bomb” to “Demographic Crisis”Toni Menninger
 
AS Micro Revision on Externalities
AS Micro Revision on ExternalitiesAS Micro Revision on Externalities
AS Micro Revision on ExternalitiesEton College
 
Ridge regression, lasso and elastic net
Ridge regression, lasso and elastic netRidge regression, lasso and elastic net
Ridge regression, lasso and elastic netVivian S. Zhang
 
Externalities Graphs How i understand them
Externalities Graphs  How i understand themExternalities Graphs  How i understand them
Externalities Graphs How i understand themvicarick
 
Externalities
ExternalitiesExternalities
ExternalitiesKevin A
 
Tutor2u - Market Failure – Public Goods
Tutor2u - Market Failure – Public GoodsTutor2u - Market Failure – Public Goods
Tutor2u - Market Failure – Public Goodstutor2u
 
Market Failure diagrams&definitions
Market Failure diagrams&definitionsMarket Failure diagrams&definitions
Market Failure diagrams&definitions12jostma
 

Viewers also liked (11)

A demographic timebomb
A demographic timebombA demographic timebomb
A demographic timebomb
 
A demographic timebomb correction
A demographic timebomb correctionA demographic timebomb correction
A demographic timebomb correction
 
Negative externalities
Negative externalitiesNegative externalities
Negative externalities
 
The Human Population Challenge: From “Population Bomb” to “Demographic Crisis”
The Human Population Challenge: From “Population Bomb” to “Demographic Crisis”The Human Population Challenge: From “Population Bomb” to “Demographic Crisis”
The Human Population Challenge: From “Population Bomb” to “Demographic Crisis”
 
AS Micro Revision on Externalities
AS Micro Revision on ExternalitiesAS Micro Revision on Externalities
AS Micro Revision on Externalities
 
Ridge regression, lasso and elastic net
Ridge regression, lasso and elastic netRidge regression, lasso and elastic net
Ridge regression, lasso and elastic net
 
Externalities Graphs How i understand them
Externalities Graphs  How i understand themExternalities Graphs  How i understand them
Externalities Graphs How i understand them
 
Externalities
ExternalitiesExternalities
Externalities
 
2.4 Market Failure
2.4 Market Failure2.4 Market Failure
2.4 Market Failure
 
Tutor2u - Market Failure – Public Goods
Tutor2u - Market Failure – Public GoodsTutor2u - Market Failure – Public Goods
Tutor2u - Market Failure – Public Goods
 
Market Failure diagrams&definitions
Market Failure diagrams&definitionsMarket Failure diagrams&definitions
Market Failure diagrams&definitions
 

Similar to Test Time Bombs

Android testing
Android testingAndroid testing
Android testingSean Tsai
 
Javaone2008 Bof 5101 Groovytesting
Javaone2008 Bof 5101 GroovytestingJavaone2008 Bof 5101 Groovytesting
Javaone2008 Bof 5101 GroovytestingAndres Almiray
 
Boosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with GroovyBoosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with GroovyJames Williams
 
Confitura 2012 Bad Tests, Good Tests
Confitura 2012 Bad Tests, Good TestsConfitura 2012 Bad Tests, Good Tests
Confitura 2012 Bad Tests, Good TestsTomek Kaczanowski
 
Java programs
Java programsJava programs
Java programsjojeph
 
WINSEM2020-21_STS3105_SS_VL2020210500169_Reference_Material_I_04-Feb-2021_L2_...
WINSEM2020-21_STS3105_SS_VL2020210500169_Reference_Material_I_04-Feb-2021_L2_...WINSEM2020-21_STS3105_SS_VL2020210500169_Reference_Material_I_04-Feb-2021_L2_...
WINSEM2020-21_STS3105_SS_VL2020210500169_Reference_Material_I_04-Feb-2021_L2_...MaruMengesha
 
Introduction to TDD with FlexUnit
Introduction to TDD with FlexUnitIntroduction to TDD with FlexUnit
Introduction to TDD with FlexUnitAnupom Syam
 
Understanding JavaScript Testing
Understanding JavaScript TestingUnderstanding JavaScript Testing
Understanding JavaScript Testingjeresig
 
GeeCON 2012 Bad Tests, Good Tests
GeeCON 2012 Bad Tests, Good TestsGeeCON 2012 Bad Tests, Good Tests
GeeCON 2012 Bad Tests, Good TestsTomek Kaczanowski
 
Turbinando o compilador do Java 8
Turbinando o compilador do Java 8Turbinando o compilador do Java 8
Turbinando o compilador do Java 8Marcelo de Castro
 
Description (Part A) In this lab you will write a Queue implementati.pdf
Description (Part A) In this lab you will write a Queue implementati.pdfDescription (Part A) In this lab you will write a Queue implementati.pdf
Description (Part A) In this lab you will write a Queue implementati.pdfrishabjain5053
 
Whitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applicationsWhitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applicationsYura Nosenko
 
So how do I test my Sling application?
 So how do I test my Sling application? So how do I test my Sling application?
So how do I test my Sling application?Robert Munteanu
 

Similar to Test Time Bombs (20)

Junit 5 - Maior e melhor
Junit 5 - Maior e melhorJunit 5 - Maior e melhor
Junit 5 - Maior e melhor
 
Android testing
Android testingAndroid testing
Android testing
 
Javaone2008 Bof 5101 Groovytesting
Javaone2008 Bof 5101 GroovytestingJavaone2008 Bof 5101 Groovytesting
Javaone2008 Bof 5101 Groovytesting
 
Boosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with GroovyBoosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with Groovy
 
Confitura 2012 Bad Tests, Good Tests
Confitura 2012 Bad Tests, Good TestsConfitura 2012 Bad Tests, Good Tests
Confitura 2012 Bad Tests, Good Tests
 
Java programs
Java programsJava programs
Java programs
 
WINSEM2020-21_STS3105_SS_VL2020210500169_Reference_Material_I_04-Feb-2021_L2_...
WINSEM2020-21_STS3105_SS_VL2020210500169_Reference_Material_I_04-Feb-2021_L2_...WINSEM2020-21_STS3105_SS_VL2020210500169_Reference_Material_I_04-Feb-2021_L2_...
WINSEM2020-21_STS3105_SS_VL2020210500169_Reference_Material_I_04-Feb-2021_L2_...
 
Introduction to TDD with FlexUnit
Introduction to TDD with FlexUnitIntroduction to TDD with FlexUnit
Introduction to TDD with FlexUnit
 
Java Concurrency
Java ConcurrencyJava Concurrency
Java Concurrency
 
Understanding JavaScript Testing
Understanding JavaScript TestingUnderstanding JavaScript Testing
Understanding JavaScript Testing
 
GeeCON 2012 Bad Tests, Good Tests
GeeCON 2012 Bad Tests, Good TestsGeeCON 2012 Bad Tests, Good Tests
GeeCON 2012 Bad Tests, Good Tests
 
Turbinando o compilador do Java 8
Turbinando o compilador do Java 8Turbinando o compilador do Java 8
Turbinando o compilador do Java 8
 
Java Day-7
Java Day-7Java Day-7
Java Day-7
 
Junit and testNG
Junit and testNGJunit and testNG
Junit and testNG
 
Description (Part A) In this lab you will write a Queue implementati.pdf
Description (Part A) In this lab you will write a Queue implementati.pdfDescription (Part A) In this lab you will write a Queue implementati.pdf
Description (Part A) In this lab you will write a Queue implementati.pdf
 
Whitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applicationsWhitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applications
 
JUnit 5
JUnit 5JUnit 5
JUnit 5
 
3 j unit
3 j unit3 j unit
3 j unit
 
So how do I test my Sling application?
 So how do I test my Sling application? So how do I test my Sling application?
So how do I test my Sling application?
 
jUnit
jUnitjUnit
jUnit
 

Recently uploaded

WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate AgentsRyan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate AgentsRyan Mahoney
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 

Recently uploaded (20)

WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate AgentsRyan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
Ryan Mahoney - Will Artificial Intelligence Replace Real Estate Agents
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 

Test Time Bombs

  • 1. Test Time Bombs lightning talk Wojciech Bulaty 18 Aug 2015
  • 2. Me (Wojtek) 9 years of software development 5+ years of TDD, pair programming, etc.
  • 3. Problem ● Problem – One failing test and the build is red – Long running builds? Harder to notice new failing tests! – Test failing for a long time (temporary integration issues?) ● Possible solutions – Suppress a failing test for a day? (green build again) – Set a reminder to look at a test next time somebody sees it? (red for a month)
  • 4. Specific example ● Integration test failing because of network issues
  • 5. Common solutions ● Supress the test by @Ignore – Who will un-ignore it? – When? ● //TODO comments never get actioned ● Card on the board ● JIRA ticket ● Mute tests in TeamCity (local build remain red, cannot check in)
  • 6. Proposed solution ● Test Time Bomb ● Blows up the test on a specified day
  • 7. package wb; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Clock; import java.util.Date; import static java.lang.String.format; public class Timebomb { private final Clock clock; Timebomb(Clock public static Tim ebomb timebomb() { return new Timebomb(Clock.systemUTC()); } public boolean blowUpAfter(int year, int month, int dayOfMonth, String explanation) { try { blowUpAfter(new SimpleDateFormat("yyyy-MM-dd").parse(format("%s-%s-%s", year, month, dayOfMonth)), explanation); } catch (ParseException e) { throw new RuntimeException(e); } return true; } public boolean blowUpAfter(Date dateToBlowUp, String explanation) { Date now = new Date(clock.millis()); if(now.compareTo(dateToBlowUp)>0) { throw new AssertionError("Requested timebomb, "+ explanation); } return true; }
  • 8. package wb; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Clock; import java.util.Date; import static java.lang.String.format; public class Timebomb { private final Clock clock; Timebolock = clock; } public static Timebomb timebomb() { return new Timebomb(Clock.systemUTC()); } public boolean blowUpAfter(int year, int month, int dayOfMonth, String explanation) { try { blowUpAfter(new SimpleDateFormat("yyyy-MM-dd").parse(format("%s-%s-%s", year, month, dayOfMonth)), explanation); } catch (ParseException e) { throw new RuntimeException(e); } return true; } public boolean blowUpAfter(Date dateToBlowUp, String explanation) { Date now = new Date(clock.millis()); if(now.compareTo(dateToBlowUp)>0) { throw new AssertionError("Requested timebomb, "+ explanation); } return true; }
  • 9. package wb; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Clock; import java.util.Date; import static java.lang.String.format; public class Timebomb { private final Clock clock; Timebomb(Clock clock) { this.clock public static Timebomb timebomb() { return n ew Timebomb(Clock.systemUTC()); } public boolean blowUpAfter(int year, int month, int dayOfMonth, String explanation) { try { blowUpAfter(new SimpleDateFormat("yyyy-MM-dd").parse(format("%s-%s-%s", year, month, dayOfMonth)), explanation); } catch (ParseException e) { throw new RuntimeException(e); } return true; } public boolean blowUpAfter(Date dateToBlowUp, String explanation) { Date now = new Date(clock.millis()); if(now.compareTo(dateToBlowUp)>0) { throw new AssertionError("Requested timebomb, "+ explanation); } return false; }
  • 10. package wb; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Clock; import java.util.Date; import static java.lang.String.format; public class Timebomb { private final Clock clock; Timebo m public static Tim ebomb timebomb() { return new Timebomb(Clock.systemUTC()); } public boolean blowUpAfter(int year, int month, int dayOfMonth, String explanation) { try { explanation ); } catch (ParseException e) { throw new RuntimeException(e); } return true; } public boolean blowUpAfter(Date dateToBlowUp, String explanation) { Date now = new Date(clock.millis()); if(now.compareTo(dateToBlowUp)>0) { throw new AssertionError("Requested timebomb, "+ explanation); } return false;
  • 11. package wb; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Clock; import java.util.Date; import static java.lang.String.format; public class Timebomb { private final Clock clock; Timebomb(Clock clock) { this.cl } public static Timebomb timebomb() { return new Timebomb(Clock.systemUTC()); } public boolean blowUpAfter(int year, int month, int dayOfMonth, String explanation) { try { return blowUpAfter(new SimpleDateFormat("yyyy-MM-dd").parse(format("%s-%s-%s", year, month, dayOfMonth)), explanation); } catch (ParseException e) { throw new RuntimeException(e); } } public boolean blowUpAfter(Date dateToBlowUp, String explanation) { Date now = new Date(clock.millis()); if(now.compareTo(dateToBlowUp)>0) { throw new AssertionError("Requested timebomb, "+ explanation); } return false; }
  • 12. package wb; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.Clock; import java.util.Date; import static java.lang.String.format; public class Timebomb { private final Clock clock; Timebomb(Clock clock) { this.clock = clock; } public static Timebomb timebomb() { return new Timebomb(Clock.systemUTC()); } public boolean blowUpAfter(int year, int month, int dayOfMonth, String explanation) { try { return blowUpAfter(new SimpleDateFormat("yyyy-MM-dd").parse(format("%s-%s-%s", year, month, dayOfMonth)), explanation); } catch (ParseException e) { throw new RuntimeException(e); } } public boolean blowUpAfter(Date dateToBlowUp, String explanation) { Date now = new Date(clock.millis()); if(now.compareTo(dateToBlowUp)>0) { throw new AssertionError("Requested timebomb, "+ explanation); } return false; }
  • 13. import org.junit.Test; import wb.TestData; import java.nio.file.Path; import java.nio.file.Paths; import static wb.Timebomb.timebomb; public class SftpClientIntegrationTest { private Path localPath = Paths.get("/testing/testFile1"); private Path remotePath = Paths.get("/testing/testFile1"); private String hostname = "aHost.mycompany.com"; @Test public void downloadsAFile() throws Exception { if(timebomb().blowUpAfter(2015, 8, 7, "chase with Paul from operations the network connectivity")) { new SftpClient(hostname).download(remotePath, localPath); } } @Test public void supportsAllSftpServers() throws Exception { String onlyWorkingTestSite = "testEnvUK"; timebomb().blowUpAfter(2015, 9, 1, "chase with Mike from SA team about the test environments other than " + onlyWorkingTestSite); TestData.allSftpServers() .stream().filter(hostname -> hostname.startsWith(onlyWorkingTestSite)) .forEach(hostname -> new SftpClient(hostname).listDirectory(remotePath)); }
  • 14. import org.junit.Test; import wb.TestData; import java.nio.file.Path; import java.nio.file.Paths; import static wb.Timebomb.timebomb; public class SftpClientIntegrationTest { private Path localPath = Paths.get("/testing/testFile1"); private Path remotePath = Paths.get("/testing/testFile1"); private String hostname = "aHost.mycompany.com"; @Test public void downloadsAFile() throws Exception { if(timebomb().blowUpAfter(2015, 8, 7, "chase with Paul from operations the network connectivity")) { new SftpClient(hostname).download(remotePath, localPath); } } @Test public void supportsAllSftpServers() throws Exception { String onlyWorkingTestSite = "testEnvUK"; timebomb().blowUpAfter(2015, 9, 1, "chase with Mike from SA team about the test environments other than " + onlyWorkingTestSite); TestData.allSftpServers() .stream().filter(hostname -> hostname.startsWith(onlyWorkingTestSite)) .forEach(hostname -> new SftpClient(hostname).listDirectory(remotePath)); }
  • 15. import org.junit.Test; import wb.TestData; import java.nio.file.Path; import java.nio.file.Paths; import static wb.Timebomb.timebomb; public class SftpClientIntegrationTest { private Path localPath = Paths.get("/testing/testFile1"); private Path remotePath = Paths.get("/testing/testFile1"); private String hostname = "aHost.mycompany.com"; @Test public void downloadsAFile() throws Exception { if(timebomb().blowUpAfter(2015, 8, 7, "chase with Paul from operations the network connectivity")) { new SftpClient(hostname).download(remotePath, localPath); } } @Test public void supportsAllSftpServers() throws Exception { String onlyWorkingTestSite = "testEnvUK"; timebomb().blowUpAfter(2015, 9, 1, "chase with Mike from SA team about the test environments other than " + onlyWorkingTestSite); TestData.allSftpServers() .stream().filter(hostname -> hostname.startsWith(onlyWorkingTestSite)) .forEach(hostname -> new SftpClient(hostname).listDirectory(remotePath)); }
  • 16. import org.junit.Test; import wb.TestData; import java.nio.file.Path; import java.nio.file.Paths; import static wb.Timebomb.timebomb; public class SftpClientIntegrationTest { private Path localPath = Paths.get("/testing/testFile1"); private Path remotePath = Paths.get("/testing/testFile1"); private String hostname = "aHost.mycompany.com"; @Test public void downloadsAFile() throws Exception { if(timebomb().blowUpAfter(2015, 8, 7, "chase with Paul from operations the network connectivity")) { new SftpClient(hostname).download(remotePath, localPath); } } @Test public void supportsAllSftpServers() throws Exception { String onlyWorkingTestSite = "testEnvUK"; timebomb().blowUpAfter(2015, 9, 1, "chase with Mike from SA team about the test environments other than " + onlyWorkingTestSite); TestData.allSftpServers() .stream().filter(hostname -> hostname.startsWith(onlyWorkingTestSite)) .forEach(hostname -> new SftpClient(hostname).listDirectory(remotePath)); }
  • 17. import org.junit.Test; import wb.TestData; import java.nio.file.Path; import java.nio.file.Paths; import static wb.Timebomb.timebomb; public class SftpClientIntegrationTest { private Path localPath = Paths.get("/testing/testFile1"); private Path remotePath = Paths.get("/testing/testFile1"); private String hostname = "aHost.mycompany.com"; @Test public void downloadsAFile() throws Exception { if(timebomb().blowUpAfter(2015, 8, 7, "chase with Paul from operations the network connectivity")) { new SftpClient(hostname).download(remotePath, localPath); } } @Test public void supportsAllSftpServers() throws Exception { String onlyWorkingTestSite = "testEnvUK"; timebomb().blowUpAfter(2015, 9, 1, "chase with Mike from SA team about the test environments other than " + onlyWorkingTestSite); TestData.allSftpServers() .stream().filter(hostname -> hostname.startsWith(onlyWorkingTestSite)) .forEach(hostname -> new SftpClient(hostname).listDirectory(remotePath)); }
  • 18. import org.junit.Test; import wb.TestData; import java.nio.file.Path; import java.nio.file.Paths; import static wb.Timebomb.timebomb; public class SftpClientIntegrationTest { private Path localPath = Paths.get("/testing/testFile1"); private Path remotePath = Paths.get("/testing/testFile1"); private String hostname = "aHost.mycompany.com"; @Test public void downloadsAFile() throws Exception { if(timebomb().blowUpAfter(2015, 8, 7, "chase with Paul from operations the network connectivity")) { new SftpClient(hostname).download(remotePath, localPath); } } @Test public void supportsAllSftpServers() throws Exception { String onlyWorkingTestSite = "testEnvUK"; timebomb().blowUpAfter(2015, 9, 1, "chase with Mike from SA team about the test environments other than " + onlyWorkingTestSite); TestData.allSftpServers() .stream().filter(hostname -> hostname.startsWith(onlyWorkingTestSite)) .forEach(hostname -> new SftpClient(hostname).listDirectory(remotePath)); }
  • 19. import org.junit.Test; import wb.TestData; import java.nio.file.Path; import java.nio.file.Paths; import static wb.Timebomb.timebomb; public class SftpClientIntegrationTest { private Path localPath = Paths.get("/testing/testFile1"); private Path remotePath = Paths.get("/testing/testFile1"); private String hostname = "aHost.mycompany.com"; @Test public void downloadsAFile() throws Exception { if(timebomb().blowUpAfter(2015, 8, 7, "chase with Paul from operations the network connectivity")) { new SftpClient(hostname).download(remotePath, localPath); } } @Test public void supportsAllSftpServers() throws Exception { String onlyWorkingTestSite = "testEnvUK"; timebomb().blowUpAfter(2015, 9, 1, "chase with Mike from SA team about the test environments other than " + onlyWorkingTestSite); TestData.allSftpServers() .stream().filter(hostname -> hostname.startsWith(onlyWorkingTestSite)) .forEach(hostname -> new SftpClient(hostname).listDirectory(remotePath)); }
  • 20. import org.junit.Test; import wb.TestData; import java.nio.file.Path; import java.nio.file.Paths; import static wb.Timebomb.timebomb; public class SftpClientIntegrationTest { private Path localPath = Paths.get("/testing/testFile1"); private Path remotePath = Paths.get("/testing/testFile1"); private String hostname = "aHost.mycompany.com"; @Test public void downloadsAFile() throws Exception { if(timebomb().blowUpAfter(2015, 8, 7, "chase with Paul from operations the network connectivity")) { new SftpClient(hostname).download(remotePath, localPath); } } @Test public void supportsAllSftpServers() throws Exception { String onlyWorkingTestSite = "testEnvUK"; timebomb().blowUpAfter(2015, 9, 1, "chase with Mike from SA team about the test environments other than " + onlyWorkingTestSite); TestData.allSftpServers() .stream().filter(hostname -> hostname.startsWith(onlyWorkingTestSite)) .forEach(hostname -> new SftpClient(hostname).listDirectory(remotePath)); }
  • 21. import org.junit.Test; import wb.TestData; import java.nio.file.Path; import java.nio.file.Paths; import static wb.Timebomb.timebomb; public class SftpClientIntegrationTest { private Path localPath = Paths.get("/testing/testFile1"); private Path remotePath = Paths.get("/testing/testFile1"); private String hostname = "aHost.mycompany.com"; @Test public void downloadsAFile() throws Exception { if(timebomb().blowUpAfter(2015, 8, 7, "chase with Paul from operations the network connectivity")) { new SftpClient(hostname).download(remotePath, localPath); } } @Test public void supportsAllSftpServers() throws Exception { String onlyWorkingTestSite = "testEnvUK"; timebomb().blowUpAfter(2015, 9, 1, "chase with Mike from SA team about the test environments other than " + onlyWorkingTestSite); TestData.allSftpServers() .stream().filter(hostname -> hostname.startsWith(onlyWorkingTestSite)) .forEach(hostname -> new SftpClient(hostname).listDirectory(remotePath)); }
  • 22. Tradeoffs ● Will not see if the test is flaky for the period of time. ● If application is not build/test not run for a long time, the timebomb will not go off.
  • 23. Credits & Thanks ● Not my idea ● Common practice within a team I used to work with in the past

Editor's Notes

  1. An integration test is failing, because the network is down. We cannot do anything about it. Is it supposed to be up in 3 days again, according to the networks team. That means our build will be red for the next 3 days, because of this test. If an other test starts failing we might not even notice it, because the build is already red.