Effective Programmer's Tests with Java.pdf

abadongutierrez 14 views 83 slides Sep 01, 2025
Slide 1
Slide 1 of 83
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31
Slide 32
32
Slide 33
33
Slide 34
34
Slide 35
35
Slide 36
36
Slide 37
37
Slide 38
38
Slide 39
39
Slide 40
40
Slide 41
41
Slide 42
42
Slide 43
43
Slide 44
44
Slide 45
45
Slide 46
46
Slide 47
47
Slide 48
48
Slide 49
49
Slide 50
50
Slide 51
51
Slide 52
52
Slide 53
53
Slide 54
54
Slide 55
55
Slide 56
56
Slide 57
57
Slide 58
58
Slide 59
59
Slide 60
60
Slide 61
61
Slide 62
62
Slide 63
63
Slide 64
64
Slide 65
65
Slide 66
66
Slide 67
67
Slide 68
68
Slide 69
69
Slide 70
70
Slide 71
71
Slide 72
72
Slide 73
73
Slide 74
74
Slide 75
75
Slide 76
76
Slide 77
77
Slide 78
78
Slide 79
79
Slide 80
80
Slide 81
81
Slide 82
82
Slide 83
83

About This Presentation

Write effective tests


Slide Content

Rafael Gutiérrez, Software Engineer @ Encora
Encora Hacker House, May 2022
Effective Programmer's Tests with Java

•Should a Programmer tests?
•Types of Sofware Testing
•Value of having tests
•Java Testing Tools
•Concepts and Patterns
•Test Readability
•Test Maintainability
•Test Trustworthiness
•EOF
Agenda

Should a Programmer test?
•Testing is not only responsibility of QA
•Testing is not something that somebody else does
•We (programmers) must take responsibility
•We (programmers) must write tests for our code to make sure code is
working properly
•We (programmers) must write automated tests

Types of Software Testing
•Unit Tests
•Integration Tests
•End-to-End Tests
•Acceptance Tests
•Performance Tests
•Smoke Tests

Value of having tests
•Tests helps us catch mistakes
•Tests helps us shape the design
•When applying Test Driven Development (TDD)
•When refactoring
•Tests helps us avoid gold-platingby being explicit about the actual
behavior

Java Testing Tools (some)
•Unit Testing -> JUnit,TestNG,EasyMock, Mockito,Spock
•Integration Tests -> DBUnit
•End-to-End Testing ->Selenium WebDriver, Selenide, Geb, Cucumber
•Performance Test -> Apache JMeter
•Supporting Tools -> AssertJ, Hamcrest, Liquidbase, Flyway,
Testcontainers

Concepts and Patterns

Assertions
How do you know your tests worked correctly?
Write code that automate your judgmentabout
whether the code worked

Test Doubles
Generic term for any case where you replace a production object for
testing purposes.

Test Doubles
•Dummy –passed around, not really used. To fill parameter list
•Fake –working implementations but taking shortcuts. For example,
InMemoryTestDatabase
•Stubs –provide canned answers for the test, no responding to
everything outside the test
•Spies –Stubs to record information to be verified later (in asserts)
•Mocks –pre-programmed with expectations. They can throw
exceptions if a call was not expected, or the number of expected calls
is different

AAA Pattern
The AAA Pattern (3A Pattern) suggest to split each tests into three parts:
•Arrange
•Act
•Assert

Test Fixture
Code that is run to configure the system under test
Test data that needs to be set up as a precondition before a test is run—
often this means populating the database with some information,
creating the objects the tests is going to use, etc.

Test Readability

Primitive assertions
•Assertions should express an assumption or intent
•Primitiveassertions hidden the intent behind some meaningless
words or numbers
•Cognitive load for other developers

Primitive assertions -:( example

Primitive assertions -:D example

Primitive assertions –example 2
Or the famous case of "what the heck is this supposed to do?"

Hyperassertions
•Too scrupulous that become brittle and hides intent
•Overwhelming! Checking too many things
•Fragile, breaking frequently (flaky)
•Single Responsibility violation
A test should have only one reason to fail

Hyperassertions-example

Incidental Details
•Code is readable when it's intent, purpose, and meaning is clear
•Scan the code and say "Ah! This thing is doing …"
•Incidental =accompanying but not a major part of something

Incidental Details -:( example

Incidental Details -:D example

Split personality
•Atest should only check one thing and check it well
•If tests doing too many checks –split the test

Split personality -:( example

Split personality -:D example

Split logic
•Nobody likes long methods
•Use "chunking" to improve readability
•cognitive psychology
•Do not blindly extract smaller methods,
but rather do it mindfully

Split logic -:( example

Split logic -:D example

Magic Numbers
•Magic numbers are bad and should be avoided
•Magic numbers appear in assignments, method calls, and other
program statements
•They don’t reveal their meaning

Magic Numbers -:( example

Magic Numbers -:D example 1

Magic Numbers -:D example 2

Setup sermon
•Sometimes we have lot of code just to prepare everything for the
test (setup method)
•The same treatment that we apply to production code should be
applied to test code (at all levels –test methods, setup methods,
etc.)

Setup sermon -
:( example

Setup sermon -:D example

Overprotective tests
•NullPointerException(our old friend) have made Devs to be
overprotective in their code
•Bepragmatic, remove redundant asserts

Overprotective tests -:( example

Overprotective tests -:D example

Test Maintainability

Duplication
•Duplication
•Duplication
•Duplication
•(DRY) Don't repeat yourself!

Duplication -:( example

Duplication -:D example

Conditional Logic
•Loops and conditional statements can be essential tools in test
helpers
•Avoid conditional logic in test methods, they can be
verydistracting

Conditional Logic -:( example

Conditional Logic -:D example

Flaky Tests
•Tests are like our friends
•If some issue was introduced, we should trust our tests to alert us
about that
•Testing when non-deterministic behavior (time, random, etc.) is
involved can be tricky

Flaky Tests -:( example

Flaky Tests -:D example

Crippling file path
•"It runs in my machine!"
•Prevents your tests from running in anyone else machine
•Avoid hardcoded values

Crippling file path -:( example

Crippling file path -:D example

Persistent temp files
•Temporary file should be temporary
•Delete resources your tests create

Persistent temp files -:( example

Persistent temp files -:D example

Sleeping snail
•We should be able to get feedback quickly from our tests
•UsingI/O (Files) in our tests can make them slow
•Using Thread.sleep() will make them slower!
•Just as testing non-deterministic behavior can be tricky, same when
testing Threads

Sleeping snail -:( example

Sleeping snail -:D example

Parameterized mess
•You find yourself with duplicated methods where the test data and
the expected results is the only thing that vary?
•Remove duplication, use parameterized tests
•But use parameterized tests with care

Parameterized mess -:( example

Parameterized mess -:D example

Lack of cohesion in methods
•Simply put, cohesion means that a class represents a single thing, a
single abstraction
•Perfect cohesion means that every field of a class is used in every
method
•In tests classes, this means that every test method is using the
same test fixture

Lack of cohesion in methods -:( example

Lack of cohesion in methods -:D example

Test Trustworthiness

Commented-out tests

Misleading comments
•Comments that suggest something that is not true
•Comments are not executable (like code), they can go stale

Misleading comments -:( example

Misleading comments -:( example

Never-failing tests
•Never-failing tests are like Chuck Norris, they never fail!
•False sense of security

Never-failing tests -:( example

Never-failing tests -:D example

Emptypromises

Lowered expectations
•Lazy testing
•Vague assertions

Conditional tests
•Hiding secret conditionals
•Using conditionals for "assumptions" or preconditions for our tests

Conditional tests -:( example

Conditional tests -:D example

•Avoid complex private methods
•Avoid final methods
•Avoid static methods
•Use `new` with care
•Avoid logic in constructors
•Avoid singleton
•Favor composite over inheritance
•Wrap external libraries
•Avoid service lookups
•Favor dependency injection
Simple guidelines for
testable design

Want to learn more?
•Test Infected: Programmers love writing tests, Kent Beck and
ErichGamma (Article)
•Effective Unit Testing, Lasse Koskela, 2013 (Book)
•Growing Object-Oriented Software Guided by Tests,Steve Freeman
and Nat Pryce(Book)
•Test-Driven Development by Example, Kent Beck (Book)
•Unit Testing Principles, Practices and Patterns,Vladimir
Khorikov2020 (Book)

JVM MX
•Comunidadde Java Mexico
•Redes sociales:
•https://youtube.com/c/javamexico
•https://facebook.com/javamexico
•https://twitter.com/jvm_mx
•https://twitter.com/javamexico
•https://github.com/javamexico

Questions time!

Thank you!