The document contains snippets of code and discussions around test-driven development (TDD) best practices. It discusses principles of TDD like writing tests first, keeping tests independent and self-contained, and refactoring code. It also provides examples of refactoring Java and Kotlin test code, including using custom assertions and organizing tests in arrange-act-assert blocks. Pair programming and software design principles like YAGNI, DRY and SOLID are also briefly mentioned.
26. public class GreeterTest {
@Test
public void should_say_hello() {
// Arrange
Greeter greeter = new Greeter("John Doe");
// Act
String greeting = greeter.sayHello();
// Assert
assertThat(greeting).isEqualTo("Hello, John Doe!");
}
}
public class GreeterTest {
@Test
public void should_say_hello() {
Greeter greeter = new Greeter("John Doe");
String greeting = greeter.sayHello();
assertThat(greeting).isEqualTo("Hello, John Doe!");
}
}
Paulo Clavijo @pclavijo
27. @Test
public void should_say_hello() {
// Arrange
Greeter greeter = new Greeter("John Doe");
// Act
String greeting = greeter.sayHello();
// Assert
assertThat(greeting).isEqualTo("Hello, John Doe!");
}
→
→
→
// Arrange
Greeter greeter = new Greeter("John Doe");
// Act
String greeting = greeter.sayHello();
Paulo Clavijo @pclavijo
28. @Test
fun `should not contain duplicated tags`() {
// Given
val post = Post()
post.addTag("Sport")
post.addTag("Travel")
post.addTag("Travel")
// When
val tasks = post.getTags()
// Then
assertThat(tasks).hasSize(2)
assertThat(tasks[0]).isEqualTo("Sport")
assertThat(tasks[1]).isEqualTo("Travel")
}
@Test
fun `should not contain duplicated tags`() {
// Given
val post = Post()
post.addTag("Sport")
post.addTag("Travel")
post.addTag("Travel")
// When
val tasks = post.getTags()
// Then
assertThat(tasks).containsExactly(
"Buy milk", "Clean car")
}
@Test
fun `should not contain duplicated tags`() {
// Given
val post = Post()
post.addTag("Sport")
post.addTag("Travel")
post.addTag("Travel")
// When
val tasks = post.getTags()
// Then
assertThat(tasks).doesNotHaveDuplicates()
}
Paulo Clavijo @pclavijo
29. class PersonTest {
@Test
fun using_custom_assertions() {
val person = Person(name = "Alice", age = 21)
assert(person).hasValidName()
assert(person).isAdult()
}
// AssertK Custom assertions
fun Assert<Person>.hasValidName() {
if (actual.name.isNotBlank()) return
expected("Name must not be blank")
}
fun Assert<Person>.isAdult() {
if (actual.age >= 18) return
expected("Age must not be below 18")
}
}
Paulo Clavijo @pclavijo
36. TDD good habits
Principles
● tests should test one thing only
● each test should be self-contained, including
data
● ensure tests are independent of each other
● don't refactor with a failing test
● organise your unit test projects to reflect
your production code
● keep your tests and production code
separate
● if your tests are difficult to write or maintain,
consider changing the design
Paulo Clavijo @pclavijo
37. TDD good habits
Red phase
● create more specific tests to drive a more
generic solution (Triangulate)
● give your tests meaningful names (behaviour
/ goal-oriented) that reflect your production
system
● organize your test in Arrange, Act and Assert
blocks
● write the assertion first and work backwards
● see the test fail for the right reason
● ensure you have meaningful feedback from
failing tests
Paulo Clavijo @pclavijo
38. TDD good habits
Green phase
● write the simplest code to pass the test
○ write any code that makes you get to
the refactor phase quicker
○ it is okay to write any code that you
might improve at a later stage
● consider using Transformation Priority
Premises to evolve your code
Paulo Clavijo @pclavijo
39. TDD good habits
Refactor phase
● refactor aggressively and constantly
● treat tests as first class code
● use the IDE to refactor quickly and safely
● refactor production and test code
independently (except changing public
interfaces)
● Use the Rule of 3 to tackle duplication
● Remember that duplication is cheaper than
the wrong abstractions
Paulo Clavijo @pclavijo
44. Desing Principles
YAGNI
“You Aren’t Gonna Need It”
DRY
“Don’t Repeat Yourself”
KISS
“Keep It Simple, Stupid”
SOLID
Tell-Don't-Ask
SoC
“Separation of Concerns”
Law of Demeter
4 Rules of
Simple Design
Paulo Clavijo @pclavijo