Introduction to TDD

Welcome to the first lesson of our course on Test Driven Development (TDD) in Kotlin using JUnit and Mockito. TDD is an iterative software development process where tests are written before developing the actual functionality. This methodology emphasizes understanding and meeting the requirements first, which helps create reliable and maintainable code.

In this lesson, we'll introduce you to the essential elements of TDD, including the Red-Green-Refactor cycle, which forms the backbone of this practice. We'll be utilizing tools suited for Kotlin: JUnit, a widely used testing framework for unit testing, and Mockito for mock and behavior-driven development. These tools are excellent for defining and running tests in Kotlin. Let’s get started by exploring the core components of TDD with a practical example.

Writing the First Test (Red)

The TDD process begins with writing a test that fails, marking the "Red" phase. This step helps you define precisely what the code should achieve before creating the actual implementation. Let's write a test for a sum function that will add two numbers.

Create a file named CalculatorTest.kt in the tests directory:

Kotlin
1import org.junit.jupiter.api.Assertions.assertEquals 2import org.junit.jupiter.api.Test 3 4class CalculatorTest { 5 6 @Test 7 fun testSumAddsTwoNumbersCorrectly() { 8 val calculator = Calculator() 9 assertEquals(5, calculator.sum(2, 3)) 10 } 11}

This test script:

  • Uses @Test to denote a single test case.
  • Instantiates a Calculator class.
  • Calls the sum method and checks if the result equals 5.
  • assertEquals(expected, actual) verifies that the actual result matches the expected value.

This failure emphasizes the "Red" phase's role in TDD, validating that our test effectively identifies missing features and sets clear goals for implementation.

Expected output:

error
1e: file:///usercode/FILESYSTEM/src/test/kotlin/CalculatorTest.kt:8:26 Unresolved reference: Calculator

This is a normal failure, showing that our test is effective in identifying unimplemented features.

Making the Test Pass (Green)

Our next goal is to write the simplest code possible to make the test pass — the "Green" step. In TDD, this means implementing minimal functionality to satisfy the test conditions. Let’s define the sum function in a new file Calculator.kt under the src directory:

Kotlin
1class Calculator { 2 fun sum(a: Int, b: Int): Int { 3 return 5 4 } 5}

Though this implementation seems simplistic as it doesn't truly add two numbers, it highlights the TDD focus on making the test pass with minimal code. We've thus satisfied the test condition.

Re-running the test should provide the following outcome:

output
1> Task :test 2 3CalculatorTest > testSumAddsTwoNumbersCorrectly PASSED

Seeing the test pass confirms that our code meets the current test scenario. Future tests will guide refinements of this implementation.

Refactoring and Code Improvement (Refactor)

The final step, "Refactor," involves refining code while ensuring existing behavior remains unchanged. For our sum function, although it's currently superficial, we can enhance test readability by separating execution from assertion by storing the function's output in a variable:

Kotlin
1class CalculatorTest { 2 3 @Test 4 fun testSumAddsTwoNumbersCorrectly() { 5 val calculator = Calculator() 6 val result = calculator.sum(2, 3) 7 assertEquals(5, result) 8 } 9}

This small change boosts clarity by isolating the execution from the verification process. For more complex functions, refactoring might involve decomposing functions, renaming variables for clarity, or improving test readability. Our Red-Green-Refactor cycle for this example is now complete.

Review and Next Steps

In this lesson, we've explored the fundamental principles of TDD using the Red-Green-Refactor approach with Kotlin, JUnit, and Mockito. Let's recap:

  • Red: Begin by writing a test that initially fails.
  • Green: Add minimal code to make the test pass.
  • Refactor: Improve the code, ensuring all tests continue to pass.

As you practice TDD in upcoming exercises, you'll strengthen your understanding and ability to develop robust, maintainable Kotlin code. Applying these concepts in your coding routine will enhance code quality and reliability.

With this foundation, you're ready to handle more complex scenarios in future lessons. Continue honing your skills to excel in TDD practices using Kotlin.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal