Introduction and Overview

In this lesson, we'll deepen our understanding of the Test-Driven Development (TDD) mindset using Scala 3 and ScalaTest by focusing on the Red-Green-Refactor cycle. We'll work through a practical example centered on a calculateTotal function, guiding you through thinking with tests, prioritizing test writing, and leveraging TDD to enhance code clarity, reliability, and maintainability.

Using Scala and ScalaTest, we'll follow these steps:

  • Begin with the Red phase by identifying and writing failing tests for the calculateTotal function, which will compute the total price of items in a shopping cart.
  • Move to the Green phase to implement the minimal code required to pass each test, ensuring that the calculateTotal function behaves as expected.
  • Enter the Refactor phase to improve the code structure and readability of calculateTotal, employing Scala’s functional programming features for aggregation while keeping tests green.
  • Utilize ScalaTest as the testing framework to efficiently integrate the TDD approach within our Scala project.

By working through this example, you'll gain practical experience with TDD principles and develop the calculateTotal function in a way that showcases how TDD fosters code quality and robustness.

Example: 'calculateTotal' Function (Red Phase)

Let's begin by writing tests for a function named calculateTotal (from the Cart class, which we'll explore soon), designed to compute the total price of items in a shopping cart. This is where you engage with the Red phase: Write a failing test.

When crafting methods that operate over collections, it’s important to determine the interface first from a test perspective. Here's one way we might write this in Scala.

Scala
import org.scalatest.funsuite.AnyFunSuite

class CartFunSuite extends AnyFunSuite:

  test("calculateTotal should return zero for an empty cart"):
    val items = List.empty[CartItem]
    val cart = Cart()
    val total = cart.calculateTotal(items)

    assert(total == 0.0)
end CartFunSuite
  • We know we want a method called calculateTotal, so our test uses it.
  • For now, we know that we want an empty list as input to return 0, so we can write that test.
  • Using assert ensures clarity and simplicity in checking test results.

Upon running these tests, you’ll see they fail, marking the Red phase and defining the next steps for development.

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