Object-Oriented Flavor for JUnit Tests

/24@yegor256 1
Yegor Bugayenko
Object-Oriented Flavor for
JUnit Tests
/24@yegor256 2
F.I.R.S.T.:
Fast
Isolated/Independent
Repeatable
Self-validating
Thorough and Timely
— Robert Martin

Clean Code
/24@yegor256 3
There are books:
Kent Beck, Test-Driven Development by Example, 2000.
Johannes Link, Unit testing in Java, 2003.
Ted Husted and Vincent Massol, JUnit in Action, 2003.
Andy Hunt and David Thomas, Pragmatic Unit Testing in C# with NUnit, 2003.
Gerard Meszaros, XUnit Test Patterns: Refactoring Test Code, 2007.
Nat Pryce and Steve Freeman, Growing Object-Oriented Software: Guided by Tests, 2009.
Lasse Koskela, Effective Unit Testing: A Guide for Java Developers, 2013.
J. B. Rainsberger, JUnit recipes, 2014.
Sujoy Acharya, Mastering Unit Testing Using Mockito and JUnit, 2014.
/24@yegor256 4
Unit testing anti-patterns:
Happy Path Tests
Validation and Boundary
Easy Tests
The Giant
The Cuckoo
The Conjoined Twins
The Slow Poke
Anal Probe
Test It All
Line Hitter
Wait and See
The Silent Catcher
Chain Gang
The Mockery
The Free Ride
The Local Hero
Wet Floor
The Flickering Test
The Environmental Vandal
Second Class Citizens
The Secret Catcher
Logic in Tests
Code Matching
Misleading Tests
Not Asserting
Asserting on Not-Null
/24@yegor256 5
I believe that one anti-pattern

is still missing:
The algorithm
Provided we’re talking about OOP
/24@yegor256 6
xUnit test method is

basically a procedure.
/24@yegor256 7
class BookTest {
@Test
void testWorksAsExpected() {
Book book = new Book();
book.setLanguage(Locale.RUSSIAN);
book.setEncoding(“UTF-8”);
book.setTitle(“Дон Кихот”);
assertTrue(book.getURL().contains(“%D0%94%D0%BE%D0”));
}
}
1.Algorithm
2.Output
3.Assertion
/24@yegor256 8
A test method must have nothing
but a single statement:
assertThat()
Provided we’re talking about Java
/24@yegor256 9
class BookTest {
@Test
void testWorksAsExpected() {
// nothing goes here
assertThat(
new Book(“Дон Кихот”, “UTF-8”, Locale.RUSSIAN),
new HasURL(new StringContains(“%D0%94%D0%BE%D0”))
);
}
}
/24@yegor256 10
Assert that the book is similar
to a book that has a URL that
contains a string that is equal to
“%D0%94”.
assertThat(
new Book(“Дон Кихот”, “UTF-8”, Locale.RUSSIAN),
new HasURL(new StringContains(“%D0%94%”))
);
/24@yegor256 11
Hamcrest
By the way, this is the anagram for “matchers”.
/24@yegor256 12
Some of anti-patterns will just
disappear:
Happy Path Tests
Validation and Boundary
Easy Tests
The Giant
The Cuckoo
The Conjoined Twins
The Slow Poke
Anal Probe
Test It All
Line Hitter
Wait and See
The Silent Catcher
Chain Gang
The Mockery
The Free Ride
The Local Hero
Wet Floor
The Flickering Test
The Environmental Vandal
Second Class Citizens
The Secret Catcher
Logic in Tests
Code Matching
Misleading Tests
Not Asserting
Asserting on Not-Null
/24@yegor256 13
Obvious benefits:
Reduced complexity
Immutable objects
Shared “matchers”
Fake objects and no mocking
Better design (more object-oriented)
/24@yegor256
Reduced Complexity
14
void testWorksAsExpected() {
assertThat(
new Book(“Дон Кихот”, “UTF-8”, Locale.RUSSIAN),
new HasURL(new StringContains(“%D0%94%D0%BE%D0”))
);
}
No free ride
No multi asserts
No @Before/@After
/24@yegor256
Immutable Objects
15
void testWorksAsExpected() {
assertThat(
new Book(“Дон Кихот”, “UTF-8”, Locale.RUSSIAN),
new HasURL(new StringContains(“%D0%94%D0%BE%D0”))
);
}
No setters
No temporal coupling
No procedures
/24@yegor256
Shared Matchers
16
void testWorksAsExpected() {
assertThat(
new Book(“Дон Кихот”, “UTF-8”, Locale.RUSSIAN),
new HasURL(new StringContains(“%D0%94%D0%BE%D0”))
);
}
No private static methods
No duplication
Cleaner logs
/24@yegor256
No Mocking
17
void testWorksAsExpected() {
assertThat(
new Book(“Дон Кихот”, “UTF-8”, Locale.RUSSIAN),
new HasURL(new StringContains(“%D0%94%D0%BE%D0”))
);
}
No assumptions
No false positives
/24@yegor256 18
class BookTest {
@Test
void testWorksAsExpected() {
Book b = new Book(“Дон Кихот”, “UTF-8”, Locale.RUSSIAN);
Matcher m = new HasURL(new StringContains(“%D0%94%D0%BE%D0”));
assertThat(b, m);
}
}
1.Object
2.Matcher
3.Assertion
/24@yegor256 19
OpenJDK
RandomStreamTest.java
java.util.Random
for
/24@yegor256 20
@Test
public void testIntStream() {
final long seed = System.currentTimeMillis();
final Random r1 = new Random(seed);
final int[] a = new int[SIZE];
for (int i=0; i < SIZE; i++) {
a[i] = r1.nextInt();
}
final Random r2 = new Random(seed);
final int[] b = r2.ints().limit(SIZE).toArray();
assertEquals(a, b);
}
/24@yegor256 21
private static class ArrayFromRandom {
private final Random random;
ArrayFromRandom(Random r) {
this.random = r;
}
int[] toArray(int s) {
final int[] a = new int[s];
for (int i=0; i < s; i++) {
a[i] = this.random.nextInt();
}
return a;
}
}
@Test
public void testIntStream() {
final long seed = System.currentTimeMillis();
assertEquals(
new ArrayFromRandom(
new Random(seed)
).toArray(SIZE),
new Random(seed).ints().limit(SIZE).toArray()
);
}
/24@yegor256 22
@Test
public void testIntStream() {
assertEquals(
new ArrayFromRandom(
new Random(System.currentTimeMillis() as seed)
).toArray(SIZE),
new Random(seed).ints().limit(SIZE).toArray()
);
}
/24@yegor256 23
cactoos
www.cactoos.org
/24@yegor256 24
new Pipe(
new TextAsInput(“Hello, world!”),
new FileAsOutput(new File(“test.txt”))
).push();
/24@yegor256 25
@Test
public void canCopyTextToByteArray() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
new Pipe(
new TextAsInput(“Hello, world!”),
new OutputStreamAsOutput(baos)
).push();
assertThat(
new String(baos.toByteArray()),
Matchers.containsString(“Hello”)
);
}
/24@yegor256 26
Input input = new TeeInput(
new TextAsInput(“Hello, world!”),
new FileAsOutput(new File(“test.txt”))
);
input.read();
new LengthOfInput(input).asValue();
6168af9
/24@yegor256 27
@Test
public void canCopyTextToByteArray() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
assertThat(
new InputAsText(
new TeeInput(
new TextAsInput(“Hello, world!”),
new OutputStreamAsOutput(baos)
)
),
Matchers.allOf(
equalTo(new String(baos.toByteArray())),
containsString(“Hello”)
)
);
}
/24@yegor256 28
@Test
public void canCopyTextToByteArray() {
ByteArrayOutputStream baos;
assertThat(
new InputAsText(
new TeeInput(
new TextAsInput(“Hello, world!”),
new OutputStreamAsOutput(baos = new ByteArrayOutputStream())
)
),
Matchers.allOf(
equalTo(new String(baos.toByteArray())),
containsString(“Hello”)
)
);
}
/24@yegor256 29
@Test
public void canCopyTextToByteArray() {
assertThat(
new InputAsText(
new TeeInput(
new TextAsInput(“Hello, world!”),
new OutputStreamAsOutput(
new ByteArrayOutputStream() as baos
)
)
),
Matchers.allOf(
equalTo(new String(baos.toByteArray())),
containsString(“Hello”)
)
);
}
/30@yegor256 30
The article on the blog:
/30@yegor256 31
shop@yegor256.com
1 of 31

Recommended

.NET Fest 2018. Дмитрий Иванов. Иммутабельные структуры данных в .NET: зачем ... by
.NET Fest 2018. Дмитрий Иванов. Иммутабельные структуры данных в .NET: зачем ....NET Fest 2018. Дмитрий Иванов. Иммутабельные структуры данных в .NET: зачем ...
.NET Fest 2018. Дмитрий Иванов. Иммутабельные структуры данных в .NET: зачем ...NETFest
325 views46 slides
Object-Oriented JUnit Tests by
Object-Oriented JUnit TestsObject-Oriented JUnit Tests
Object-Oriented JUnit TestsYegor Bugayenko
717 views38 slides
Static analysis: Around Java in 60 minutes by
Static analysis: Around Java in 60 minutesStatic analysis: Around Java in 60 minutes
Static analysis: Around Java in 60 minutesAndrey Karpov
75 views37 slides
Using xUnit as a Swiss-Aarmy Testing Toolkit by
Using xUnit as a Swiss-Aarmy Testing ToolkitUsing xUnit as a Swiss-Aarmy Testing Toolkit
Using xUnit as a Swiss-Aarmy Testing ToolkitChris Oldwood
672 views31 slides
TDD? Sure, but What About My Legacy Code? by
TDD? Sure, but What About My Legacy Code?TDD? Sure, but What About My Legacy Code?
TDD? Sure, but What About My Legacy Code?Rob Myers
1.1K views31 slides
4java Basic Syntax by
4java Basic Syntax4java Basic Syntax
4java Basic SyntaxAdil Jafri
151 views42 slides

More Related Content

What's hot

Java → kotlin: Tests Made Simple by
Java → kotlin: Tests Made SimpleJava → kotlin: Tests Made Simple
Java → kotlin: Tests Made Simpleleonsabr
4.4K views122 slides
Appium TestNG Framework and Multi-Device Automation Execution by
Appium TestNG Framework and Multi-Device Automation ExecutionAppium TestNG Framework and Multi-Device Automation Execution
Appium TestNG Framework and Multi-Device Automation ExecutionpCloudy
201 views10 slides
EVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMER by
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
212 views34 slides
Java Programming - 04 object oriented in java by
Java Programming - 04 object oriented in javaJava Programming - 04 object oriented in java
Java Programming - 04 object oriented in javaDanairat Thanabodithammachari
926 views25 slides
Zhongl scala summary by
Zhongl scala summaryZhongl scala summary
Zhongl scala summarylunfu zhong
877 views26 slides
ObjectBox - The new Mobile Database by
ObjectBox - The new Mobile DatabaseObjectBox - The new Mobile Database
ObjectBox - The new Mobile Databasegreenrobot
1.6K views27 slides

What's hot(8)

Java → kotlin: Tests Made Simple by leonsabr
Java → kotlin: Tests Made SimpleJava → kotlin: Tests Made Simple
Java → kotlin: Tests Made Simple
leonsabr4.4K views
Appium TestNG Framework and Multi-Device Automation Execution by pCloudy
Appium TestNG Framework and Multi-Device Automation ExecutionAppium TestNG Framework and Multi-Device Automation Execution
Appium TestNG Framework and Multi-Device Automation Execution
pCloudy201 views
EVERYTHING ABOUT STATIC CODE ANALYSIS FOR A JAVA PROGRAMMER by Andrey Karpov
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
Andrey Karpov212 views
Zhongl scala summary by lunfu zhong
Zhongl scala summaryZhongl scala summary
Zhongl scala summary
lunfu zhong877 views
ObjectBox - The new Mobile Database by greenrobot
ObjectBox - The new Mobile DatabaseObjectBox - The new Mobile Database
ObjectBox - The new Mobile Database
greenrobot1.6K views
Cassandra drivers and libraries by Duyhai Doan
Cassandra drivers and librariesCassandra drivers and libraries
Cassandra drivers and libraries
Duyhai Doan2.3K views
Cassandra Drivers and Tools by Duyhai Doan
Cassandra Drivers and ToolsCassandra Drivers and Tools
Cassandra Drivers and Tools
Duyhai Doan1.3K views

Similar to Object-Oriented Flavor for JUnit Tests

GTAC 2014: What lurks in test suites? by
GTAC 2014: What lurks in test suites?GTAC 2014: What lurks in test suites?
GTAC 2014: What lurks in test suites?Patrick Lam
358 views55 slides
CS5393-Korat_Mittal_Akshay_ProjReport by
CS5393-Korat_Mittal_Akshay_ProjReportCS5393-Korat_Mittal_Akshay_ProjReport
CS5393-Korat_Mittal_Akshay_ProjReportAkshay Mittal
236 views16 slides
Not your father's tests by
Not your father's testsNot your father's tests
Not your father's testsSean P. Floyd
1.1K views91 slides
Pattern Matching in Java 14 by
Pattern Matching in Java 14Pattern Matching in Java 14
Pattern Matching in Java 14GlobalLogic Ukraine
926 views60 slides
Introduction to Julia by
Introduction to JuliaIntroduction to Julia
Introduction to Julia岳華 杜
169 views86 slides
IPA Fall Days 2019 by
 IPA Fall Days 2019 IPA Fall Days 2019
IPA Fall Days 2019Annibale Panichella
284 views45 slides

Similar to Object-Oriented Flavor for JUnit Tests(20)

GTAC 2014: What lurks in test suites? by Patrick Lam
GTAC 2014: What lurks in test suites?GTAC 2014: What lurks in test suites?
GTAC 2014: What lurks in test suites?
Patrick Lam358 views
CS5393-Korat_Mittal_Akshay_ProjReport by Akshay Mittal
CS5393-Korat_Mittal_Akshay_ProjReportCS5393-Korat_Mittal_Akshay_ProjReport
CS5393-Korat_Mittal_Akshay_ProjReport
Akshay Mittal236 views
Not your father's tests by Sean P. Floyd
Not your father's testsNot your father's tests
Not your father's tests
Sean P. Floyd1.1K views
Introduction to Julia by 岳華 杜
Introduction to JuliaIntroduction to Julia
Introduction to Julia
岳華 杜169 views
Shift-Left Testing: QA in a DevOps World by David Laulusa by QA or the Highway
Shift-Left Testing: QA in a DevOps World by David LaulusaShift-Left Testing: QA in a DevOps World by David Laulusa
Shift-Left Testing: QA in a DevOps World by David Laulusa
QA or the Highway257 views
Advances in Unit Testing: Theory and Practice by Tao Xie
Advances in Unit Testing: Theory and PracticeAdvances in Unit Testing: Theory and Practice
Advances in Unit Testing: Theory and Practice
Tao Xie1.3K views
Mutation Testing: Testing your tests by Stephen Leigh
Mutation Testing: Testing your testsMutation Testing: Testing your tests
Mutation Testing: Testing your tests
Stephen Leigh387 views
Immutability, and how to do it in JavaScripts by Anton Astashov
Immutability, and how to do it in JavaScriptsImmutability, and how to do it in JavaScripts
Immutability, and how to do it in JavaScripts
Anton Astashov113 views
JS Lab`16. Сергей Селецкий: "Ретроспектива тестирования JavaScript" by GeeksLab Odessa
JS Lab`16. Сергей Селецкий: "Ретроспектива тестирования JavaScript"JS Lab`16. Сергей Селецкий: "Ретроспектива тестирования JavaScript"
JS Lab`16. Сергей Селецкий: "Ретроспектива тестирования JavaScript"
GeeksLab Odessa298 views
LECTURE 2 MORE TYPES, METHODS, CONDITIONALS.pdf by ShashikantSathe3
LECTURE 2 MORE TYPES, METHODS, CONDITIONALS.pdfLECTURE 2 MORE TYPES, METHODS, CONDITIONALS.pdf
LECTURE 2 MORE TYPES, METHODS, CONDITIONALS.pdf
Unit 2-data types,Variables,Operators,Conitionals,loops and arrays by DevaKumari Vijay
Unit 2-data types,Variables,Operators,Conitionals,loops and arraysUnit 2-data types,Variables,Operators,Conitionals,loops and arrays
Unit 2-data types,Variables,Operators,Conitionals,loops and arrays
DevaKumari Vijay288 views
Homework2a.pdf1 Homework 2a Before attempting t.docx by adampcarr67227
Homework2a.pdf1  Homework 2a Before attempting t.docxHomework2a.pdf1  Homework 2a Before attempting t.docx
Homework2a.pdf1 Homework 2a Before attempting t.docx
adampcarr672272 views
DLint: dynamically checking bad coding practices in JavaScript (ISSTA'15 Slides) by Liang Gong
DLint: dynamically checking bad coding practices in JavaScript (ISSTA'15 Slides)DLint: dynamically checking bad coding practices in JavaScript (ISSTA'15 Slides)
DLint: dynamically checking bad coding practices in JavaScript (ISSTA'15 Slides)
Liang Gong1.1K views
Nighthawk: A Two-Level Genetic-Random Unit Test Data Generator by CS, NcState
Nighthawk: A Two-Level Genetic-Random Unit Test Data GeneratorNighthawk: A Two-Level Genetic-Random Unit Test Data Generator
Nighthawk: A Two-Level Genetic-Random Unit Test Data Generator
CS, NcState1K views
Finding bugs that matter with Findbugs by Carol McDonald
Finding bugs that matter with FindbugsFinding bugs that matter with Findbugs
Finding bugs that matter with Findbugs
Carol McDonald2.6K views

More from Yegor Bugayenko

Can Distributed Teams Deliver Quality? by
Can Distributed Teams Deliver Quality?Can Distributed Teams Deliver Quality?
Can Distributed Teams Deliver Quality?Yegor Bugayenko
269 views23 slides
Are You Sure You Are Not a Micromanager? by
Are You Sure You Are Not a Micromanager?Are You Sure You Are Not a Micromanager?
Are You Sure You Are Not a Micromanager?Yegor Bugayenko
245 views16 slides
On Requirements Management (Demotivate Them Right) by
On Requirements Management (Demotivate Them Right)On Requirements Management (Demotivate Them Right)
On Requirements Management (Demotivate Them Right)Yegor Bugayenko
220 views16 slides
My Experience of 1000 Interviews by
My Experience of 1000 InterviewsMy Experience of 1000 Interviews
My Experience of 1000 InterviewsYegor Bugayenko
218 views20 slides
Are you sure you are not a micromanager? by
Are you sure you are not a micromanager?Are you sure you are not a micromanager?
Are you sure you are not a micromanager?Yegor Bugayenko
251 views15 slides
Quality Assurance vs. Testing by
Quality Assurance vs. TestingQuality Assurance vs. Testing
Quality Assurance vs. TestingYegor Bugayenko
660 views25 slides

More from Yegor Bugayenko(20)

Can Distributed Teams Deliver Quality? by Yegor Bugayenko
Can Distributed Teams Deliver Quality?Can Distributed Teams Deliver Quality?
Can Distributed Teams Deliver Quality?
Yegor Bugayenko269 views
Are You Sure You Are Not a Micromanager? by Yegor Bugayenko
Are You Sure You Are Not a Micromanager?Are You Sure You Are Not a Micromanager?
Are You Sure You Are Not a Micromanager?
Yegor Bugayenko245 views
On Requirements Management (Demotivate Them Right) by Yegor Bugayenko
On Requirements Management (Demotivate Them Right)On Requirements Management (Demotivate Them Right)
On Requirements Management (Demotivate Them Right)
Yegor Bugayenko220 views
My Experience of 1000 Interviews by Yegor Bugayenko
My Experience of 1000 InterviewsMy Experience of 1000 Interviews
My Experience of 1000 Interviews
Yegor Bugayenko218 views
Are you sure you are not a micromanager? by Yegor Bugayenko
Are you sure you are not a micromanager?Are you sure you are not a micromanager?
Are you sure you are not a micromanager?
Yegor Bugayenko251 views
Zold: a cryptocurrency without Blockchain by Yegor Bugayenko
Zold: a cryptocurrency without BlockchainZold: a cryptocurrency without Blockchain
Zold: a cryptocurrency without Blockchain
Yegor Bugayenko282 views
How to Cut Corners and Stay Cool by Yegor Bugayenko
How to Cut Corners and Stay CoolHow to Cut Corners and Stay Cool
How to Cut Corners and Stay Cool
Yegor Bugayenko318 views

Recently uploaded

GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N... by
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...James Anderson
66 views32 slides
STPI OctaNE CoE Brochure.pdf by
STPI OctaNE CoE Brochure.pdfSTPI OctaNE CoE Brochure.pdf
STPI OctaNE CoE Brochure.pdfmadhurjyapb
13 views1 slide
Voice Logger - Telephony Integration Solution at Aegis by
Voice Logger - Telephony Integration Solution at AegisVoice Logger - Telephony Integration Solution at Aegis
Voice Logger - Telephony Integration Solution at AegisNirmal Sharma
31 views1 slide
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院 by
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院IttrainingIttraining
41 views8 slides
Microsoft Power Platform.pptx by
Microsoft Power Platform.pptxMicrosoft Power Platform.pptx
Microsoft Power Platform.pptxUni Systems S.M.S.A.
52 views38 slides
handbook for web 3 adoption.pdf by
handbook for web 3 adoption.pdfhandbook for web 3 adoption.pdf
handbook for web 3 adoption.pdfLiveplex
22 views16 slides

Recently uploaded(20)

GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N... by James Anderson
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...
GDG Cloud Southlake 28 Brad Taylor and Shawn Augenstein Old Problems in the N...
James Anderson66 views
STPI OctaNE CoE Brochure.pdf by madhurjyapb
STPI OctaNE CoE Brochure.pdfSTPI OctaNE CoE Brochure.pdf
STPI OctaNE CoE Brochure.pdf
madhurjyapb13 views
Voice Logger - Telephony Integration Solution at Aegis by Nirmal Sharma
Voice Logger - Telephony Integration Solution at AegisVoice Logger - Telephony Integration Solution at Aegis
Voice Logger - Telephony Integration Solution at Aegis
Nirmal Sharma31 views
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院 by IttrainingIttraining
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院
【USB韌體設計課程】精選講義節錄-USB的列舉過程_艾鍗學院
handbook for web 3 adoption.pdf by Liveplex
handbook for web 3 adoption.pdfhandbook for web 3 adoption.pdf
handbook for web 3 adoption.pdf
Liveplex22 views
Data Integrity for Banking and Financial Services by Precisely
Data Integrity for Banking and Financial ServicesData Integrity for Banking and Financial Services
Data Integrity for Banking and Financial Services
Precisely12 views
SAP Automation Using Bar Code and FIORI.pdf by Virendra Rai, PMP
SAP Automation Using Bar Code and FIORI.pdfSAP Automation Using Bar Code and FIORI.pdf
SAP Automation Using Bar Code and FIORI.pdf
Attacking IoT Devices from a Web Perspective - Linux Day by Simone Onofri
Attacking IoT Devices from a Web Perspective - Linux Day Attacking IoT Devices from a Web Perspective - Linux Day
Attacking IoT Devices from a Web Perspective - Linux Day
Simone Onofri15 views
Serverless computing with Google Cloud (2023-24) by wesley chun
Serverless computing with Google Cloud (2023-24)Serverless computing with Google Cloud (2023-24)
Serverless computing with Google Cloud (2023-24)
wesley chun10 views
Transcript: The Details of Description Techniques tips and tangents on altern... by BookNet Canada
Transcript: The Details of Description Techniques tips and tangents on altern...Transcript: The Details of Description Techniques tips and tangents on altern...
Transcript: The Details of Description Techniques tips and tangents on altern...
BookNet Canada135 views
TouchLog: Finger Micro Gesture Recognition Using Photo-Reflective Sensors by sugiuralab
TouchLog: Finger Micro Gesture Recognition  Using Photo-Reflective SensorsTouchLog: Finger Micro Gesture Recognition  Using Photo-Reflective Sensors
TouchLog: Finger Micro Gesture Recognition Using Photo-Reflective Sensors
sugiuralab19 views
Case Study Copenhagen Energy and Business Central.pdf by Aitana
Case Study Copenhagen Energy and Business Central.pdfCase Study Copenhagen Energy and Business Central.pdf
Case Study Copenhagen Energy and Business Central.pdf
Aitana16 views
Five Things You SHOULD Know About Postman by Postman
Five Things You SHOULD Know About PostmanFive Things You SHOULD Know About Postman
Five Things You SHOULD Know About Postman
Postman30 views

Object-Oriented Flavor for JUnit Tests

  • 3. /24@yegor256 3 There are books: Kent Beck, Test-Driven Development by Example, 2000. Johannes Link, Unit testing in Java, 2003. Ted Husted and Vincent Massol, JUnit in Action, 2003. Andy Hunt and David Thomas, Pragmatic Unit Testing in C# with NUnit, 2003. Gerard Meszaros, XUnit Test Patterns: Refactoring Test Code, 2007. Nat Pryce and Steve Freeman, Growing Object-Oriented Software: Guided by Tests, 2009. Lasse Koskela, Effective Unit Testing: A Guide for Java Developers, 2013. J. B. Rainsberger, JUnit recipes, 2014. Sujoy Acharya, Mastering Unit Testing Using Mockito and JUnit, 2014.
  • 4. /24@yegor256 4 Unit testing anti-patterns: Happy Path Tests Validation and Boundary Easy Tests The Giant The Cuckoo The Conjoined Twins The Slow Poke Anal Probe Test It All Line Hitter Wait and See The Silent Catcher Chain Gang The Mockery The Free Ride The Local Hero Wet Floor The Flickering Test The Environmental Vandal Second Class Citizens The Secret Catcher Logic in Tests Code Matching Misleading Tests Not Asserting Asserting on Not-Null
  • 5. /24@yegor256 5 I believe that one anti-pattern
 is still missing: The algorithm Provided we’re talking about OOP
  • 6. /24@yegor256 6 xUnit test method is
 basically a procedure.
  • 7. /24@yegor256 7 class BookTest { @Test void testWorksAsExpected() { Book book = new Book(); book.setLanguage(Locale.RUSSIAN); book.setEncoding(“UTF-8”); book.setTitle(“Дон Кихот”); assertTrue(book.getURL().contains(“%D0%94%D0%BE%D0”)); } } 1.Algorithm 2.Output 3.Assertion
  • 8. /24@yegor256 8 A test method must have nothing but a single statement: assertThat() Provided we’re talking about Java
  • 9. /24@yegor256 9 class BookTest { @Test void testWorksAsExpected() { // nothing goes here assertThat( new Book(“Дон Кихот”, “UTF-8”, Locale.RUSSIAN), new HasURL(new StringContains(“%D0%94%D0%BE%D0”)) ); } }
  • 10. /24@yegor256 10 Assert that the book is similar to a book that has a URL that contains a string that is equal to “%D0%94”. assertThat( new Book(“Дон Кихот”, “UTF-8”, Locale.RUSSIAN), new HasURL(new StringContains(“%D0%94%”)) );
  • 11. /24@yegor256 11 Hamcrest By the way, this is the anagram for “matchers”.
  • 12. /24@yegor256 12 Some of anti-patterns will just disappear: Happy Path Tests Validation and Boundary Easy Tests The Giant The Cuckoo The Conjoined Twins The Slow Poke Anal Probe Test It All Line Hitter Wait and See The Silent Catcher Chain Gang The Mockery The Free Ride The Local Hero Wet Floor The Flickering Test The Environmental Vandal Second Class Citizens The Secret Catcher Logic in Tests Code Matching Misleading Tests Not Asserting Asserting on Not-Null
  • 13. /24@yegor256 13 Obvious benefits: Reduced complexity Immutable objects Shared “matchers” Fake objects and no mocking Better design (more object-oriented)
  • 14. /24@yegor256 Reduced Complexity 14 void testWorksAsExpected() { assertThat( new Book(“Дон Кихот”, “UTF-8”, Locale.RUSSIAN), new HasURL(new StringContains(“%D0%94%D0%BE%D0”)) ); } No free ride No multi asserts No @Before/@After
  • 15. /24@yegor256 Immutable Objects 15 void testWorksAsExpected() { assertThat( new Book(“Дон Кихот”, “UTF-8”, Locale.RUSSIAN), new HasURL(new StringContains(“%D0%94%D0%BE%D0”)) ); } No setters No temporal coupling No procedures
  • 16. /24@yegor256 Shared Matchers 16 void testWorksAsExpected() { assertThat( new Book(“Дон Кихот”, “UTF-8”, Locale.RUSSIAN), new HasURL(new StringContains(“%D0%94%D0%BE%D0”)) ); } No private static methods No duplication Cleaner logs
  • 17. /24@yegor256 No Mocking 17 void testWorksAsExpected() { assertThat( new Book(“Дон Кихот”, “UTF-8”, Locale.RUSSIAN), new HasURL(new StringContains(“%D0%94%D0%BE%D0”)) ); } No assumptions No false positives
  • 18. /24@yegor256 18 class BookTest { @Test void testWorksAsExpected() { Book b = new Book(“Дон Кихот”, “UTF-8”, Locale.RUSSIAN); Matcher m = new HasURL(new StringContains(“%D0%94%D0%BE%D0”)); assertThat(b, m); } } 1.Object 2.Matcher 3.Assertion
  • 20. /24@yegor256 20 @Test public void testIntStream() { final long seed = System.currentTimeMillis(); final Random r1 = new Random(seed); final int[] a = new int[SIZE]; for (int i=0; i < SIZE; i++) { a[i] = r1.nextInt(); } final Random r2 = new Random(seed); final int[] b = r2.ints().limit(SIZE).toArray(); assertEquals(a, b); }
  • 21. /24@yegor256 21 private static class ArrayFromRandom { private final Random random; ArrayFromRandom(Random r) { this.random = r; } int[] toArray(int s) { final int[] a = new int[s]; for (int i=0; i < s; i++) { a[i] = this.random.nextInt(); } return a; } } @Test public void testIntStream() { final long seed = System.currentTimeMillis(); assertEquals( new ArrayFromRandom( new Random(seed) ).toArray(SIZE), new Random(seed).ints().limit(SIZE).toArray() ); }
  • 22. /24@yegor256 22 @Test public void testIntStream() { assertEquals( new ArrayFromRandom( new Random(System.currentTimeMillis() as seed) ).toArray(SIZE), new Random(seed).ints().limit(SIZE).toArray() ); }
  • 24. /24@yegor256 24 new Pipe( new TextAsInput(“Hello, world!”), new FileAsOutput(new File(“test.txt”)) ).push();
  • 25. /24@yegor256 25 @Test public void canCopyTextToByteArray() { ByteArrayOutputStream baos = new ByteArrayOutputStream(); new Pipe( new TextAsInput(“Hello, world!”), new OutputStreamAsOutput(baos) ).push(); assertThat( new String(baos.toByteArray()), Matchers.containsString(“Hello”) ); }
  • 26. /24@yegor256 26 Input input = new TeeInput( new TextAsInput(“Hello, world!”), new FileAsOutput(new File(“test.txt”)) ); input.read(); new LengthOfInput(input).asValue(); 6168af9
  • 27. /24@yegor256 27 @Test public void canCopyTextToByteArray() { ByteArrayOutputStream baos = new ByteArrayOutputStream(); assertThat( new InputAsText( new TeeInput( new TextAsInput(“Hello, world!”), new OutputStreamAsOutput(baos) ) ), Matchers.allOf( equalTo(new String(baos.toByteArray())), containsString(“Hello”) ) ); }
  • 28. /24@yegor256 28 @Test public void canCopyTextToByteArray() { ByteArrayOutputStream baos; assertThat( new InputAsText( new TeeInput( new TextAsInput(“Hello, world!”), new OutputStreamAsOutput(baos = new ByteArrayOutputStream()) ) ), Matchers.allOf( equalTo(new String(baos.toByteArray())), containsString(“Hello”) ) ); }
  • 29. /24@yegor256 29 @Test public void canCopyTextToByteArray() { assertThat( new InputAsText( new TeeInput( new TextAsInput(“Hello, world!”), new OutputStreamAsOutput( new ByteArrayOutputStream() as baos ) ) ), Matchers.allOf( equalTo(new String(baos.toByteArray())), containsString(“Hello”) ) ); }