SlideShare a Scribd company logo
The Joy of Tes*ng
3-hours Deep Dive at
by Victor Rentea
Code is here: h+ps://github.com/victorrentea/unit-tes9ng.git branch: devoxx24
UT 3
- Evan Spiegel
Ever had a great
refactoring idea
but you were afraid
to do it?
UT 4
Prove it works today, including edge cases
Fast Feedback to preserve focus: Start Clicking => Stop Thinking🤤
Refactor without fear tomorrow, be crea7ve, if func'onal-tests(elseJ)
Up-to-date Spec running on CI, if func'onal tests
Clarify requirements, if test-early
Design feedback: Hard to test ≈> poor design, if test-early
For coverage%, to get my PR approved 👍; Trap: Coverage Rush⚠
Why Write Tests?
✅
🔄
🪓
📄
💬
✨
%
👋 I'm Victor Rentea 🇷🇴 Java Champion, PhD(CS)
👨💻 18 years in Java + most languages
👨🏫 10 years of Training / 150+ companies / 20+ countries:
- Architecture, Refactoring, Unit Tes2ng (today)
- Spring, JPA, Performance, ReacIve
European SoKware CraKers Community (on meetup.com)
YouTube.com/vrentea - events👆 + conference🎙
Life += 👰 + 👧 + 🙇 + 2*😸 victorrentea.ro
I'm drawing on screen with:
> ScreenBrush (Mac)
> ZoomIt (Win)
UT 9
🧠
Quali&es of a Unit Test
UT 10
§Sensible: detects changes in behavior
§Func7onal, not coupled to implementaEon (resilient to refactoring)
§Specific: fails for one clear reason
§Expressive: uses domain terms with a high signal/raEo raEo
§Automated: easy to run by anyone with no/minimal manual setup
§Repeatable: produces the same outcome if rerun
§Isolated vs other tests / external system state
§Minimal: includes only relevant stuff (#responsible copy-paste)
§Fast, total build Eme < 15-20 min
Quali0es of a Test
from the book "The Art of Unit Tes.ng" by Roy Osherove
UT 12
Coverage
UT 13
Coverage Rush
Management Goal: Coverage > xx%😤 vs 🥴Confused Developers or ☠Legacy
The more code in here,
the more untested code
can be in the project.
😱
Example of Cobra Effect
5000 lines
UT 14
Coverage %
Cost
Coverage%
100%
80% 90%
60%
= covrigi [RO]
cover critical code first
🤔 Higher goals for 'domain' package
Minimum Coverage%
UT 15
Line vs Branch Coverage
§Line Coverage = did my tests executed a line?
§Branch Coverage = did my tests exercised a path? 💖 💖 💖
- if (condition) è 50% = means condi4on was only true (or false) during tests
- condition ? expr1 : expr2
- a && b || c è 100% branch coverage = a, b, c were all false + true in tests
- Measured via a -javaagent: that
monitors code executed by tests
IntelliJ setup
UT 16
tl;dr
Use Branch Coverage
UT 17
Professionals use coverage analysis
to hunt for UNCOVERED code,
NOT to celebrate COVERED lines
UT 18
Talk is cheap
Show the me the code_
Code is here: h+ps://github.com/victorrentea/unit-tes9ng.git branch: devoxx24
UT 19
A new instance of the test class is created for each @Test.
So it's ok to leave dirty data in test class' instance fields.
#simplicity
#1 Basic People don't know about JUnit
🥇
UT 20
Muta%on Tes%ng
UT 21
All tests are green. 👏🥳
You break some behavior,
but all tests stay Green
🤨
Evergreen Tests
Imagine 95% coverage...
UT 22
Evergreen Tests
Coverage% = ?
Oups!!
100%
If all tested code is deleted,
the test remains GREEN 😱
Da-i asa! vs Basculanta🤣
lies to you
UT 23
§Prod coverage of class X.java = 87% 👍
§XTest.java = 2000-lines
§67 x @Mock
§200 x Mockito.when 😵💫
including when(aMock.getB()).thenReturn(bMock);
§0 x "assert" 😱
§0 x "verify" 😱
Cobra 🐍 Effect
UT 24
The only way to prove
a test is correct?
tl;dr
it FAILS if (and only if)
you BREAK the tested behavior
UT 25
Muta3on Tes3ng
You inten1onally
introduce a bug in
Produc@on Code You get a
MUTANT
Tests should FAIL 🎉
(proving they would catch that bug)
Run Tests
Don't forget⚠ to
Undo the bug
Correct tests fail <=> Produc@on Code is altered
The only way to prove
a test is correct?
UT 26
§Alters tested bytecode and checks tests fail
- Using a set of mutators, like "Negate Condi@onals"
§But⚠:
- Can report false posi@ves (non-issues)
- Takes long @me to run if applied on lots of code
§Use it:
- To learn
- On super-cri@cal code (target a single package)
Muta3on Tes3ng with pitest
UT 27
🦙💩
Ever generated a test with AI (LLM)?
🦄 Dream: Gen-AI tests (chaos) but then check them via muta@on-tes@ng (exact)
Lower entry-cost when tes@ng legacy 👍
UT 28
Check that every new test you write
fails for a bug in tested logic.
(hands-on if not obvious)
UT 30
Bug-Tests
UT 31
UT 32
Breakpoint
using step-into, inspect,
evaluate, watch variable...
✅ Use for a 1st explora4on
UT 33
Breakpoint-debugging an issue is an<social behavior
Others entering that code
tomorrow will suffer too.
requires deep focus 🧘 and
drains lots of brain energy 🧠
Breakpoint
UT 35
Fix a bug like a Pro
1. Reproduce the bug [twice]
2. Write a test for it è FAILS❌
(⚠can be very-very hard in complex, terrible legacy code)
3. log.debug("..{}", var) instead of breakpoint
4. Find the cause > Kill bug > Test è GREEN✅
Avoid vola1le
breakpoint sessions
You can later lower the log level in producIon without restart😎:
using: JMX, Spring Actuator, or Logback config auto-reload to inves9gate unreproducible bugs
UT 36
Why Bother?
Bugs S7ck Together
UT 37
refactoring + tes4ng merge
in "islands of safety"
Test Around Bugs
bug
unit-tests around it
Tes4ng another nearby bug
becomes easier tomorrow
Bugs S1ck Together
Unit-tes4ng legacy code
requires some prep-cleaning
UT 38 h+p://googletes9ng.blogspot.com
https://drive.google.com/open?id=1YQNHvc0NIzspxKHG4BU9mjdOqDQdks9z
UT 40
Bugs in Tests
UT 41
A Bug in a Test
assertEquals("Greetings" + name, logic.getGreetings(name));
production code
it's missing a " "!
The developer copied the logic from produc@on to tests😩
You want Explicit Tests
assertEquals("Greetings John", logic.getGreetings("John"));
Find the BUG !
UT 42
Tests should be Simple and Expressive,
NOT cryp4c, smarty, and hard to read
UT 43
Unmaintainable Tests
Can make developers :
Anger Zone
delete test
@Disable
// comment test
// @Test
delete asserts
flip asserts to pass
UT 45
Test Name
UT 47
Test Name
void givenAnInactiveCustomer_whenHePlacesAnOrder_itIsActivated()
void givenAProgramLinkedTo2Records_whenUpdated_2AuditsAreInserted()
Given Then
When
🥱
UT 48
AnInactiveCustomerShould
.beActivatedWhenHePlacesAnOrder()
Brain-Friendly Test Names
Fluent naming
hFps://codurance.com/2014/12/13/naming-test-classes-and-methods/
"Given"
the class name explains
the context shared by tests
Test
"Then"
start with the expected effect
to capture the reader a+en9on
"When"
... then describe in what condi9on it occurs
UT 49
AssertJ
UT 50
assertEquals
Anyone?
UT 51
assertEquals
Never use again
Use assertThat (from AssertJ)
UT 54
§A few fields
assertThat(x.getA()).isEqualTo(y.getA());
assertThat(x.getB()).isEqualTo(y.getB());
§Almost all fields
assertThat(x)
.usingReflective(ignoringFields("a")).isEqualTo(y);
§All fields
assertThat(toPrettyJson(x))
.isEqualTo(toPrettyJson(y));
How to compare data structures?
UT 58
Parameterized
Tests
UT 59
Parameterized Tests – Best Prac&ces
§Orthogonal parameters - best (low mul4collinearity)
Example (for 3 input params):
- Good: a={1,2,3}, b={7,8}, c={T,F} = 3x2x2 = 12 valid combina4ons with 3 params
- Bad if only 3 valid combina4ons: (1,7,true); (1,8,false); (2,8,true)
§Few parameters < 3-5
- More => group them in a class/record with named fields
- Complex input structure * many tests => consider file-based tests
§Avoid boolean-riddled test
- if (param1) excep4on was thrown
if (param2) when(mock)..
if (param3) verify(mock)..
UT 60
Tes0ng Styles Maintainability
§Output-Based
- Assert the returned value
- (enough when tested code has no side effects, pure func4on😍)
§State-Based
- Assert fields of tested stateful object
- Assert fields of collaborator objects (eg. passed as params🤨)
- Assert external state in DB/Files
§CommunicaEon-Based (mocks)
- Verify interac4on with collaborators
UT 61
Approval Tests
UT 63
When you can't an4cipate the impact of a change.
§Capture all output of a component in a human readable file
- csv, json, xml, txt
§Change the component behavior.
§Diff 👀 the new output with the old output saved in files
§If correct => save the new output in the old file = "approve"
Approval Tes3ng
UT 64
Tes2ng Legacy
UT 65
1000
lines of code
in a single file
00
UT 67
Characterization Tests
§Dark Techniques to write temporary, ugly tests
- Break encapsula4on of tested code (private -> public)
- Par4al mock (@Spy) internal methods
- Mock sta4cs & control global state
§Pre-tesEng refactoring (unguarded by tests)
- Exploratory refactoring (eg 30-minute > undo!): look for seams ("fracture planes")
- Tiny, safe baby-steps refactoring with IDE, pairing (2) or mobbing (N)
§Extract and test code with a clear role = maintainable tests💖
§CharacterizaEon Tests: capture input/output as a black-box
Legacy Code Tes&ng Prac&ces
UT 68
Characterization Tests
Some legacy code with no tests runs in production for many years.
Therefore, we can assume it is correct. = it became its own spec
But we need to refactor that code. 😱 😱 😱 😱
Our Goal = preserve its behaviour (correct or not), not to find bugs.
Step 1. Identify & capture the inputs/outputs of the prod code (HARD),
example IN= params, results of DB queries/API call, time/random/UUID!..
OUT= returned value, DB insert/update, API calls, sent messages!..
Step 2. Save {inputs + recorded outputs} to files.
Step 3. Identify many different inputs to cover all execution paths
Get line coverage close to 100%; ± manual mutation testing.
PRO😎: Record IN/OUT from production = "Golden Master" Technique
(also highlights dead☠ code)
Step 4. Refactor guarded by these tests. When done, remove tests?
UT 69
Shadow TesFng
Prod env
Staging env
Clients traffic
traffic
↓
↓
copy
↓
↓
↓
↓
compare
results
↑
↑
UT 74
BDD
Libraries:
Cucumber
JBehave
BeHat (php)
SpecFlow (C#)
...
Behavior-Driven-Development
(aka Acceptance-Test-Driven-Development)
UT 75
Have I understood correctly
what we need to build?
UT 76
Bridge the Gap
Make sure you implement the right thing
Gherkin Language can help
UT 78
Gherkin Language
PO
Business
// "glue" code can: configure mocks, DB, WireMock, set
fields, load files ...
@When("Player{int} scores {int} points")
public void playerScores (int player, int points) {
for (int i = 0; i < points; i++) {
tennisScore.addPoint(player);
}
}
@Then("Score is {string}")
public void score_is(String expected) throws Throwable {
assertThat(tennisScore.score()).isEqualTo(expected);
}
Cucumber
UT 80
Behavior-Driven Development
Before star;ng the development,
developers + testers + domain experts (BA/PO)
write together 💖 a series of .feature files that capture
(developer = typist, having sketched a few draV scenarios beforehand)
the acceptance criteria of the stories to develop.
When these .features go green✅ => develop = done🍺
Later, each change request starts with edi;ng .feature files
UT 81
🌈 Developers' Dream 🦄
Business people will maintain the .features
🚫 It never works.
✅ Works: Pair on them (Dev✍ + Biz💬)
✅ Works: Automa;on-tester
UT 82
When should you use a .feature?
✅ Hesita2ng/conflic2ng requirements (CYA principle)
✅ Complex rules, to beQer understand via more examples
✅ Business-cri2cal features to avoid expen$ive confusions
✅ Table-like test data (Excel-style) => scenario outline
❌ Business disengages: trivial or too technical features?
UT 83
Gherkin Best Prac0ces
§Use Ubiquitous Language understood by tech and !tech: PO, BA, QA
§Focus on behaviour (aka "FuncEonal Tests"), hide details behind steps
§Keep steps implementa7on simple; expose relevant parameters
§UI Scenarios (Selenium) can be fragile and slow⚠ => fire at API-level
§DRY: use shared steps, Background:, Scenario Outline, and @tags
§Mock external services for faster and more reliable tests
§Share state between step classes via dep. injecEon: Spring, Guice..
§Prevent state leak: cleanup test environment a]er each scenario
§Version control .features along code
§Runs on CI ⚠ (even if slow)
UT 84
WASTE
Maintaining .feature files
that no businessperson approves
UT 85
When only developers
work with Gherkin files
consider building a test DSL instead.
WriVen in the same language (java, C#...),
or in a denser one: kt, py, groovy
UT 86
Test Helpers
Tes<ng Framework
Test DSL
UT 88
Test Domain-Specific Language
= a fluent mini-tes@ng framework:
Click to see implementa9on
UT 89 http://spockframework.org/spock/docs/1.3/spock_primer.html
Spock tests (.groovy)
UT 90
Test DSL in Kotlin
https://medium.com/porterbuddy/simple-test-dsls-in-kotlin-c6393035a92
UT 91
Fine-Grained Tests
Complex Mocking
Fragile vs Refactoring
Focus on implementa;on
Longer Tests
Require Test Helpers
Robust
Close to spec
UT 92
JUnit4 Rules
JUnit 5 Extensions
Cucumber Tags
.py decorators
...
Test AOP
Invisible code runs before and aer your tests
🧙
UT 93
Hierarchical
Test Fixtures
UT 94
Not all long tests are like this
UT 95
Hierarchical Test Fixtures
Shared fixture for
all tests on this flow
Addi4onal fixture
for some branches
= context
@Nested classes
Test Subclasses
Test AOP
UT 96
An Inac4ve Customer
… with an order
… with no orders
Hierarchical Fixtures
(@Nested in JUnit5)
Nested Test Fixtures in JUnit5: https://junit.org/junit5/docs/current/user-guide/#writing-tests-nested
UT 97
An Inac4ve Customer
@Nested With an order
@Nested With no orders
An Inac4ve Customer
With an order
… with no orders
@Before
Hierarchical Fixtures
@Before
@Before
@Before
@Before
JUnit5 @Nested Extending a test class
UT 98
The Joy of Testing – key points
#1 section
- Why do we write Tests?
- Coverage% ▶ CustomerValidatorTest
- Test Names
- ObjectMother: in-mem vs parse.json
- Mutation Testing
- Bug-testing
- assertThat (AssertJ) ▶
- Test AOP with JUnit Extensions ▶
#2 section
- Parameterized Tests ▶ TennisScoreTest
- Approval Tests (by text inspection🧐) ▶
- Characterization Tests (for legacy code)
- Gherkin for Functional Tests ▶
- Hierarchical Test Fixtures ▶ CustomerFacade
- Test Qualities
UT 99
The Joy of Tes*ng
Please share with others
Code is here: h+ps://github.com/victorrentea/unit-tes9ng.git branch: devoxx24
Thank you!
UT 100
The Joy of Tes*ng
💡 Share your thoughts: stalk me or at victorrentea@gmail.com
📺 Test-Driven Design Insights, 3h Deep Dive at Devoxx 2023
📺 Tes1ng Microservices: Join the Revolu1on, at Devoxx 2023
📺 YouTube.com/vrentea
👨🏫 Private training ± consultancy: victorrentea.ro/catalog
What Next?
💬 Free monthly webinars: victorrentea.ro/community
Code is here: h+ps://github.com/victorrentea/unit-tes9ng.git branch: devoxx24

More Related Content

PDF
Code Refactoring
PPTX
openshift technical overview - Flow of openshift containerisatoin
PPTX
Vertical Slicing Architectures
PPTX
Clean Code: Chapter 3 Function
PPTX
HTML5 & CSS3
PPTX
The Art of Clean code
PDF
JavaScript guide 2020 Learn JavaScript
PPTX
Getting Started with API Security Testing
Code Refactoring
openshift technical overview - Flow of openshift containerisatoin
Vertical Slicing Architectures
Clean Code: Chapter 3 Function
HTML5 & CSS3
The Art of Clean code
JavaScript guide 2020 Learn JavaScript
Getting Started with API Security Testing

What's hot (20)

PDF
Linux kernel tracing
PDF
Deep Dive on ClickHouse Sharding and Replication-2202-09-22.pdf
PDF
Linux Profiling at Netflix
PDF
All about Zookeeper and ClickHouse Keeper.pdf
PDF
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
PPTX
Autoscaling Flink with Reactive Mode
PDF
[Outdated] Secrets of Performance Tuning Java on Kubernetes
PDF
Data warehouse on Kubernetes - gentle intro to Clickhouse Operator, by Robert...
PPTX
Apache Kafka Best Practices
PDF
Blazing Performance with Flame Graphs
PDF
Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안
PPTX
Rancher kubernetes storages
PDF
BPF: Tracing and more
PDF
Real-time, Exactly-once Data Ingestion from Kafka to ClickHouse at eBay
PPTX
So You Want to Write an Exporter
PDF
Cloud Native Java GraalVM 이상과 현실
PPTX
Understanding kube proxy in ipvs mode
PDF
DevConf 2014 Kernel Networking Walkthrough
PDF
Kubernetes Networking with Cilium - Deep Dive
PDF
Bulk Loading Data into Cassandra
Linux kernel tracing
Deep Dive on ClickHouse Sharding and Replication-2202-09-22.pdf
Linux Profiling at Netflix
All about Zookeeper and ClickHouse Keeper.pdf
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Autoscaling Flink with Reactive Mode
[Outdated] Secrets of Performance Tuning Java on Kubernetes
Data warehouse on Kubernetes - gentle intro to Clickhouse Operator, by Robert...
Apache Kafka Best Practices
Blazing Performance with Flame Graphs
Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안
Rancher kubernetes storages
BPF: Tracing and more
Real-time, Exactly-once Data Ingestion from Kafka to ClickHouse at eBay
So You Want to Write an Exporter
Cloud Native Java GraalVM 이상과 현실
Understanding kube proxy in ipvs mode
DevConf 2014 Kernel Networking Walkthrough
Kubernetes Networking with Cilium - Deep Dive
Bulk Loading Data into Cassandra
Ad

Similar to The Joy of Testing - Deep Dive @ Devoxx Belgium 2024 (20)

PDF
des mutants dans le code.pdf
PDF
Bdd and-testing
PDF
Behaviour Driven Development and Thinking About Testing
 
PPTX
Test-Driven Design Insights@DevoxxBE 2023.pptx
PDF
DSR Testing (Part 1)
PDF
TDD and Getting Paid
PPTX
Whitebox Testing,Types,Different techniques
PDF
Unit Testing like a Pro - The Circle of Purity
PPTX
Unit testing
PPT
Test Driven
PDF
Effective Unit Test Style Guide
PDF
SE2_Lec 21_ TDD and Junit
PDF
Software Testing - Invited Lecture at UNSW Sydney
PPTX
Unit Testing with JUnit4 by Ravikiran Janardhana
PPTX
클린 테스트
PDF
Tdd with python unittest for embedded c
PDF
The Art of Unit Testing - Towards a Testable Design
PPTX
SE2018_Lec 20_ Test-Driven Development (TDD)
PDF
ELECTRA_Pretraining Text Encoders as Discriminators rather than Generators
PDF
Unit testing - A&BP CC
des mutants dans le code.pdf
Bdd and-testing
Behaviour Driven Development and Thinking About Testing
 
Test-Driven Design Insights@DevoxxBE 2023.pptx
DSR Testing (Part 1)
TDD and Getting Paid
Whitebox Testing,Types,Different techniques
Unit Testing like a Pro - The Circle of Purity
Unit testing
Test Driven
Effective Unit Test Style Guide
SE2_Lec 21_ TDD and Junit
Software Testing - Invited Lecture at UNSW Sydney
Unit Testing with JUnit4 by Ravikiran Janardhana
클린 테스트
Tdd with python unittest for embedded c
The Art of Unit Testing - Towards a Testable Design
SE2018_Lec 20_ Test-Driven Development (TDD)
ELECTRA_Pretraining Text Encoders as Discriminators rather than Generators
Unit testing - A&BP CC
Ad

More from Victor Rentea (20)

PDF
Top REST API Desgin Pitfalls @ Devoxx 2024
PDF
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
PDF
Microservice Resilience Patterns @VoxxedCern'24
PDF
Distributed Consistency.pdf
PDF
Clean Code @Voxxed Days Cluj 2023 - opening Keynote
PDF
Testing Microservices @DevoxxBE 23.pdf
PPTX
From Web to Flux @DevoxxBE 2023.pptx
PDF
Profiling your Java Application
PPTX
OAuth in the Wild
PPTX
The tests are trying to tell you something@VoxxedBucharest.pptx
PDF
Software Craftsmanship @Code Camp Festival 2022.pdf
PDF
Unit testing - 9 design hints
PDF
Clean pragmatic architecture @ devflix
PPTX
Extreme Professionalism - Software Craftsmanship
PDF
Clean architecture - Protecting the Domain
PDF
Refactoring blockers and code smells @jNation 2021
PDF
Hibernate and Spring - Unleash the Magic
PDF
Integration testing with spring @JAX Mainz
PDF
The Proxy Fairy and the Magic of Spring @JAX Mainz 2021
PDF
Integration testing with spring @snow one
Top REST API Desgin Pitfalls @ Devoxx 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Microservice Resilience Patterns @VoxxedCern'24
Distributed Consistency.pdf
Clean Code @Voxxed Days Cluj 2023 - opening Keynote
Testing Microservices @DevoxxBE 23.pdf
From Web to Flux @DevoxxBE 2023.pptx
Profiling your Java Application
OAuth in the Wild
The tests are trying to tell you something@VoxxedBucharest.pptx
Software Craftsmanship @Code Camp Festival 2022.pdf
Unit testing - 9 design hints
Clean pragmatic architecture @ devflix
Extreme Professionalism - Software Craftsmanship
Clean architecture - Protecting the Domain
Refactoring blockers and code smells @jNation 2021
Hibernate and Spring - Unleash the Magic
Integration testing with spring @JAX Mainz
The Proxy Fairy and the Magic of Spring @JAX Mainz 2021
Integration testing with spring @snow one

Recently uploaded (20)

PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
KodekX | Application Modernization Development
PDF
Empathic Computing: Creating Shared Understanding
PPTX
sap open course for s4hana steps from ECC to s4
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PPT
Teaching material agriculture food technology
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Electronic commerce courselecture one. Pdf
PPTX
MYSQL Presentation for SQL database connectivity
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Reach Out and Touch Someone: Haptics and Empathic Computing
KodekX | Application Modernization Development
Empathic Computing: Creating Shared Understanding
sap open course for s4hana steps from ECC to s4
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Diabetes mellitus diagnosis method based random forest with bat algorithm
Chapter 3 Spatial Domain Image Processing.pdf
The Rise and Fall of 3GPP – Time for a Sabbatical?
MIND Revenue Release Quarter 2 2025 Press Release
Teaching material agriculture food technology
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
20250228 LYD VKU AI Blended-Learning.pptx
Electronic commerce courselecture one. Pdf
MYSQL Presentation for SQL database connectivity
Profit Center Accounting in SAP S/4HANA, S4F28 Col11

The Joy of Testing - Deep Dive @ Devoxx Belgium 2024

  • 1. The Joy of Tes*ng 3-hours Deep Dive at by Victor Rentea Code is here: h+ps://github.com/victorrentea/unit-tes9ng.git branch: devoxx24
  • 2. UT 3 - Evan Spiegel Ever had a great refactoring idea but you were afraid to do it?
  • 3. UT 4 Prove it works today, including edge cases Fast Feedback to preserve focus: Start Clicking => Stop Thinking🤤 Refactor without fear tomorrow, be crea7ve, if func'onal-tests(elseJ) Up-to-date Spec running on CI, if func'onal tests Clarify requirements, if test-early Design feedback: Hard to test ≈> poor design, if test-early For coverage%, to get my PR approved 👍; Trap: Coverage Rush⚠ Why Write Tests? ✅ 🔄 🪓 📄 💬 ✨ %
  • 4. 👋 I'm Victor Rentea 🇷🇴 Java Champion, PhD(CS) 👨💻 18 years in Java + most languages 👨🏫 10 years of Training / 150+ companies / 20+ countries: - Architecture, Refactoring, Unit Tes2ng (today) - Spring, JPA, Performance, ReacIve European SoKware CraKers Community (on meetup.com) YouTube.com/vrentea - events👆 + conference🎙 Life += 👰 + 👧 + 🙇 + 2*😸 victorrentea.ro I'm drawing on screen with: > ScreenBrush (Mac) > ZoomIt (Win)
  • 5. UT 9 🧠 Quali&es of a Unit Test
  • 6. UT 10 §Sensible: detects changes in behavior §Func7onal, not coupled to implementaEon (resilient to refactoring) §Specific: fails for one clear reason §Expressive: uses domain terms with a high signal/raEo raEo §Automated: easy to run by anyone with no/minimal manual setup §Repeatable: produces the same outcome if rerun §Isolated vs other tests / external system state §Minimal: includes only relevant stuff (#responsible copy-paste) §Fast, total build Eme < 15-20 min Quali0es of a Test from the book "The Art of Unit Tes.ng" by Roy Osherove
  • 8. UT 13 Coverage Rush Management Goal: Coverage > xx%😤 vs 🥴Confused Developers or ☠Legacy The more code in here, the more untested code can be in the project. 😱 Example of Cobra Effect 5000 lines
  • 9. UT 14 Coverage % Cost Coverage% 100% 80% 90% 60% = covrigi [RO] cover critical code first 🤔 Higher goals for 'domain' package Minimum Coverage%
  • 10. UT 15 Line vs Branch Coverage §Line Coverage = did my tests executed a line? §Branch Coverage = did my tests exercised a path? 💖 💖 💖 - if (condition) è 50% = means condi4on was only true (or false) during tests - condition ? expr1 : expr2 - a && b || c è 100% branch coverage = a, b, c were all false + true in tests - Measured via a -javaagent: that monitors code executed by tests IntelliJ setup
  • 12. UT 17 Professionals use coverage analysis to hunt for UNCOVERED code, NOT to celebrate COVERED lines
  • 13. UT 18 Talk is cheap Show the me the code_ Code is here: h+ps://github.com/victorrentea/unit-tes9ng.git branch: devoxx24
  • 14. UT 19 A new instance of the test class is created for each @Test. So it's ok to leave dirty data in test class' instance fields. #simplicity #1 Basic People don't know about JUnit 🥇
  • 16. UT 21 All tests are green. 👏🥳 You break some behavior, but all tests stay Green 🤨 Evergreen Tests Imagine 95% coverage...
  • 17. UT 22 Evergreen Tests Coverage% = ? Oups!! 100% If all tested code is deleted, the test remains GREEN 😱 Da-i asa! vs Basculanta🤣 lies to you
  • 18. UT 23 §Prod coverage of class X.java = 87% 👍 §XTest.java = 2000-lines §67 x @Mock §200 x Mockito.when 😵💫 including when(aMock.getB()).thenReturn(bMock); §0 x "assert" 😱 §0 x "verify" 😱 Cobra 🐍 Effect
  • 19. UT 24 The only way to prove a test is correct? tl;dr it FAILS if (and only if) you BREAK the tested behavior
  • 20. UT 25 Muta3on Tes3ng You inten1onally introduce a bug in Produc@on Code You get a MUTANT Tests should FAIL 🎉 (proving they would catch that bug) Run Tests Don't forget⚠ to Undo the bug Correct tests fail <=> Produc@on Code is altered The only way to prove a test is correct?
  • 21. UT 26 §Alters tested bytecode and checks tests fail - Using a set of mutators, like "Negate Condi@onals" §But⚠: - Can report false posi@ves (non-issues) - Takes long @me to run if applied on lots of code §Use it: - To learn - On super-cri@cal code (target a single package) Muta3on Tes3ng with pitest
  • 22. UT 27 🦙💩 Ever generated a test with AI (LLM)? 🦄 Dream: Gen-AI tests (chaos) but then check them via muta@on-tes@ng (exact) Lower entry-cost when tes@ng legacy 👍
  • 23. UT 28 Check that every new test you write fails for a bug in tested logic. (hands-on if not obvious)
  • 25. UT 31
  • 26. UT 32 Breakpoint using step-into, inspect, evaluate, watch variable... ✅ Use for a 1st explora4on
  • 27. UT 33 Breakpoint-debugging an issue is an<social behavior Others entering that code tomorrow will suffer too. requires deep focus 🧘 and drains lots of brain energy 🧠 Breakpoint
  • 28. UT 35 Fix a bug like a Pro 1. Reproduce the bug [twice] 2. Write a test for it è FAILS❌ (⚠can be very-very hard in complex, terrible legacy code) 3. log.debug("..{}", var) instead of breakpoint 4. Find the cause > Kill bug > Test è GREEN✅ Avoid vola1le breakpoint sessions You can later lower the log level in producIon without restart😎: using: JMX, Spring Actuator, or Logback config auto-reload to inves9gate unreproducible bugs
  • 29. UT 36 Why Bother? Bugs S7ck Together
  • 30. UT 37 refactoring + tes4ng merge in "islands of safety" Test Around Bugs bug unit-tests around it Tes4ng another nearby bug becomes easier tomorrow Bugs S1ck Together Unit-tes4ng legacy code requires some prep-cleaning
  • 32. UT 40 Bugs in Tests
  • 33. UT 41 A Bug in a Test assertEquals("Greetings" + name, logic.getGreetings(name)); production code it's missing a " "! The developer copied the logic from produc@on to tests😩 You want Explicit Tests assertEquals("Greetings John", logic.getGreetings("John")); Find the BUG !
  • 34. UT 42 Tests should be Simple and Expressive, NOT cryp4c, smarty, and hard to read
  • 35. UT 43 Unmaintainable Tests Can make developers : Anger Zone delete test @Disable // comment test // @Test delete asserts flip asserts to pass
  • 37. UT 47 Test Name void givenAnInactiveCustomer_whenHePlacesAnOrder_itIsActivated() void givenAProgramLinkedTo2Records_whenUpdated_2AuditsAreInserted() Given Then When 🥱
  • 38. UT 48 AnInactiveCustomerShould .beActivatedWhenHePlacesAnOrder() Brain-Friendly Test Names Fluent naming hFps://codurance.com/2014/12/13/naming-test-classes-and-methods/ "Given" the class name explains the context shared by tests Test "Then" start with the expected effect to capture the reader a+en9on "When" ... then describe in what condi9on it occurs
  • 41. UT 51 assertEquals Never use again Use assertThat (from AssertJ)
  • 42. UT 54 §A few fields assertThat(x.getA()).isEqualTo(y.getA()); assertThat(x.getB()).isEqualTo(y.getB()); §Almost all fields assertThat(x) .usingReflective(ignoringFields("a")).isEqualTo(y); §All fields assertThat(toPrettyJson(x)) .isEqualTo(toPrettyJson(y)); How to compare data structures?
  • 44. UT 59 Parameterized Tests – Best Prac&ces §Orthogonal parameters - best (low mul4collinearity) Example (for 3 input params): - Good: a={1,2,3}, b={7,8}, c={T,F} = 3x2x2 = 12 valid combina4ons with 3 params - Bad if only 3 valid combina4ons: (1,7,true); (1,8,false); (2,8,true) §Few parameters < 3-5 - More => group them in a class/record with named fields - Complex input structure * many tests => consider file-based tests §Avoid boolean-riddled test - if (param1) excep4on was thrown if (param2) when(mock).. if (param3) verify(mock)..
  • 45. UT 60 Tes0ng Styles Maintainability §Output-Based - Assert the returned value - (enough when tested code has no side effects, pure func4on😍) §State-Based - Assert fields of tested stateful object - Assert fields of collaborator objects (eg. passed as params🤨) - Assert external state in DB/Files §CommunicaEon-Based (mocks) - Verify interac4on with collaborators
  • 47. UT 63 When you can't an4cipate the impact of a change. §Capture all output of a component in a human readable file - csv, json, xml, txt §Change the component behavior. §Diff 👀 the new output with the old output saved in files §If correct => save the new output in the old file = "approve" Approval Tes3ng
  • 49. UT 65 1000 lines of code in a single file 00
  • 50. UT 67 Characterization Tests §Dark Techniques to write temporary, ugly tests - Break encapsula4on of tested code (private -> public) - Par4al mock (@Spy) internal methods - Mock sta4cs & control global state §Pre-tesEng refactoring (unguarded by tests) - Exploratory refactoring (eg 30-minute > undo!): look for seams ("fracture planes") - Tiny, safe baby-steps refactoring with IDE, pairing (2) or mobbing (N) §Extract and test code with a clear role = maintainable tests💖 §CharacterizaEon Tests: capture input/output as a black-box Legacy Code Tes&ng Prac&ces
  • 51. UT 68 Characterization Tests Some legacy code with no tests runs in production for many years. Therefore, we can assume it is correct. = it became its own spec But we need to refactor that code. 😱 😱 😱 😱 Our Goal = preserve its behaviour (correct or not), not to find bugs. Step 1. Identify & capture the inputs/outputs of the prod code (HARD), example IN= params, results of DB queries/API call, time/random/UUID!.. OUT= returned value, DB insert/update, API calls, sent messages!.. Step 2. Save {inputs + recorded outputs} to files. Step 3. Identify many different inputs to cover all execution paths Get line coverage close to 100%; ± manual mutation testing. PRO😎: Record IN/OUT from production = "Golden Master" Technique (also highlights dead☠ code) Step 4. Refactor guarded by these tests. When done, remove tests?
  • 52. UT 69 Shadow TesFng Prod env Staging env Clients traffic traffic ↓ ↓ copy ↓ ↓ ↓ ↓ compare results ↑ ↑
  • 53. UT 74 BDD Libraries: Cucumber JBehave BeHat (php) SpecFlow (C#) ... Behavior-Driven-Development (aka Acceptance-Test-Driven-Development)
  • 54. UT 75 Have I understood correctly what we need to build?
  • 55. UT 76 Bridge the Gap Make sure you implement the right thing Gherkin Language can help
  • 56. UT 78 Gherkin Language PO Business // "glue" code can: configure mocks, DB, WireMock, set fields, load files ... @When("Player{int} scores {int} points") public void playerScores (int player, int points) { for (int i = 0; i < points; i++) { tennisScore.addPoint(player); } } @Then("Score is {string}") public void score_is(String expected) throws Throwable { assertThat(tennisScore.score()).isEqualTo(expected); } Cucumber
  • 57. UT 80 Behavior-Driven Development Before star;ng the development, developers + testers + domain experts (BA/PO) write together 💖 a series of .feature files that capture (developer = typist, having sketched a few draV scenarios beforehand) the acceptance criteria of the stories to develop. When these .features go green✅ => develop = done🍺 Later, each change request starts with edi;ng .feature files
  • 58. UT 81 🌈 Developers' Dream 🦄 Business people will maintain the .features 🚫 It never works. ✅ Works: Pair on them (Dev✍ + Biz💬) ✅ Works: Automa;on-tester
  • 59. UT 82 When should you use a .feature? ✅ Hesita2ng/conflic2ng requirements (CYA principle) ✅ Complex rules, to beQer understand via more examples ✅ Business-cri2cal features to avoid expen$ive confusions ✅ Table-like test data (Excel-style) => scenario outline ❌ Business disengages: trivial or too technical features?
  • 60. UT 83 Gherkin Best Prac0ces §Use Ubiquitous Language understood by tech and !tech: PO, BA, QA §Focus on behaviour (aka "FuncEonal Tests"), hide details behind steps §Keep steps implementa7on simple; expose relevant parameters §UI Scenarios (Selenium) can be fragile and slow⚠ => fire at API-level §DRY: use shared steps, Background:, Scenario Outline, and @tags §Mock external services for faster and more reliable tests §Share state between step classes via dep. injecEon: Spring, Guice.. §Prevent state leak: cleanup test environment a]er each scenario §Version control .features along code §Runs on CI ⚠ (even if slow)
  • 61. UT 84 WASTE Maintaining .feature files that no businessperson approves
  • 62. UT 85 When only developers work with Gherkin files consider building a test DSL instead. WriVen in the same language (java, C#...), or in a denser one: kt, py, groovy
  • 63. UT 86 Test Helpers Tes<ng Framework Test DSL
  • 64. UT 88 Test Domain-Specific Language = a fluent mini-tes@ng framework: Click to see implementa9on
  • 66. UT 90 Test DSL in Kotlin https://medium.com/porterbuddy/simple-test-dsls-in-kotlin-c6393035a92
  • 67. UT 91 Fine-Grained Tests Complex Mocking Fragile vs Refactoring Focus on implementa;on Longer Tests Require Test Helpers Robust Close to spec
  • 68. UT 92 JUnit4 Rules JUnit 5 Extensions Cucumber Tags .py decorators ... Test AOP Invisible code runs before and aer your tests 🧙
  • 70. UT 94 Not all long tests are like this
  • 71. UT 95 Hierarchical Test Fixtures Shared fixture for all tests on this flow Addi4onal fixture for some branches = context @Nested classes Test Subclasses Test AOP
  • 72. UT 96 An Inac4ve Customer … with an order … with no orders Hierarchical Fixtures (@Nested in JUnit5) Nested Test Fixtures in JUnit5: https://junit.org/junit5/docs/current/user-guide/#writing-tests-nested
  • 73. UT 97 An Inac4ve Customer @Nested With an order @Nested With no orders An Inac4ve Customer With an order … with no orders @Before Hierarchical Fixtures @Before @Before @Before @Before JUnit5 @Nested Extending a test class
  • 74. UT 98 The Joy of Testing – key points #1 section - Why do we write Tests? - Coverage% ▶ CustomerValidatorTest - Test Names - ObjectMother: in-mem vs parse.json - Mutation Testing - Bug-testing - assertThat (AssertJ) ▶ - Test AOP with JUnit Extensions ▶ #2 section - Parameterized Tests ▶ TennisScoreTest - Approval Tests (by text inspection🧐) ▶ - Characterization Tests (for legacy code) - Gherkin for Functional Tests ▶ - Hierarchical Test Fixtures ▶ CustomerFacade - Test Qualities
  • 75. UT 99 The Joy of Tes*ng Please share with others Code is here: h+ps://github.com/victorrentea/unit-tes9ng.git branch: devoxx24 Thank you!
  • 76. UT 100 The Joy of Tes*ng 💡 Share your thoughts: stalk me or at victorrentea@gmail.com 📺 Test-Driven Design Insights, 3h Deep Dive at Devoxx 2023 📺 Tes1ng Microservices: Join the Revolu1on, at Devoxx 2023 📺 YouTube.com/vrentea 👨🏫 Private training ± consultancy: victorrentea.ro/catalog What Next? 💬 Free monthly webinars: victorrentea.ro/community Code is here: h+ps://github.com/victorrentea/unit-tes9ng.git branch: devoxx24