Logo

dev-resources.site

for different kinds of informations.

When does the TDD approach make sense?

Published at
10/17/2024
Categories
webdev
tdd
testing
Author
lukapeharda
Categories
3 categories in total
webdev
open
tdd
open
testing
open
Author
11 person written this
lukapeharda
open
When does the TDD approach make sense?

I don't like writing tests. But I like having tests. They give me a sense of security and confidence that my code works as expected.

I never bought into TDD practices.

I know the approach can be very useful and in the long run it can save you time and money. But there is always a time pressure when developing features and not enough time to write tests.

But I always start with TDD when I need to develop a feature that will require me to test a lot of different variants and edge cases, and especially when there are a lot of clicking and moving parts and especially when external platforms and APIs are involved.

Adding Order::nextPaymentAmount method

Let me give you an example from the project that I'm working on.

I had to add a method nextPaymentAmount to the Order class which would return the amount of the next recurring payment.

Payment can be a one-time, a subscription, or installment plan. It can have setup fees and trials. It can have discounts and coupons. Coupons can be applied only to the first payment or to all recurring payments as well. It can have taxes. It can have a lot of different scenarios.

A lot of unnecessary clicking to test all of these combinations manually.

TDD to the rescue

In scenarios like above, I always use TDD and it saves me incredible amounts of time.

I'm not strictly adhering to TDD practices. I skip steps.

First, I write down all test cases that I can think of.

class NextPaymentAmountTest extends TestCase
{
    ...

    public function testOneTimePaymentHasNoNextPayment(): void
    {}

    public function testSubscriptionHasNextPayment(): void
    {}

    public function testSubscriptionWithSetupFeeHasNextPaymentWithDifferentAmount(): void
    {}

    public function testSubcriptionWithBasicCouponHasNextPaymentWithoutDiscount(): void
    {}

    public function testSubscriptionWithRecurringCouponHasNextPaymentWithDiscount(): void
    {}

    ...
}
Enter fullscreen mode Exit fullscreen mode

Then I focus on a single case.

...

public function testOneTimePaymentHasNoNextPayment(): void
{
    // Arrange
    $pricingPlan = factory(PricingPlan::class)->create([
        'type' => 'one-time',
        'amount' => 100
    ]);

    $order = factory(Order::class)->create([
        'pricing_plan_id' => $pricingPlan->id,
        'member_id' => $this->member->id,
        'membership_id' => $this->membership->id
    ]);

    // Act
    $nextPaymentAmount = $order->nextPaymentAmount();

    // Assert
    $this->assertEquals(0, $nextPaymentAmount);
}

...
Enter fullscreen mode Exit fullscreen mode

At first, test fails because the function that I'm testing (Order::nextPaymentAmount) is not yet implemented. Then I implement it just so the test passes.

Each test case is a small step towards the final implementation and adds a bit of code or conditional.

Usually, as I go along these cases and write code to pass them, I find a lot more edge cases that need to be covered.


Using this iterative approach I'm positive that I've covered most of the possible scenarios. And more importantly, I wasn't overwhelmed with "loading" all edge cases in my head before implementing the feature.

TDD not only saved me a lot of time, but gave me confidence that the feature works as expected. And that it will work as we extend it in the future.

tdd Article's
30 articles in total
Favicon
Test in Isolation
Favicon
Why Test Driven Development
Favicon
How to start with test driven development (TDD)
Favicon
What we will test
Favicon
How Test-Driven Development (TDD) Enhances Code Refactoring and Maintains Software Quality
Favicon
Why should I care about Quality? I'm a developer!
Favicon
TDD with spring-boot: A struggle of an experienced developer
Favicon
Test with Spy and Mock
Favicon
Test-Driven Development (TDD) with Bun Test
Favicon
Test with Dummy and Stub
Favicon
Modern Test Pyramid
Favicon
Some Essential Coding Practices Every Experienced Developer Recommends
Favicon
Not everything is a Mock, let's explore Test Doubles
Favicon
When does the TDD approach make sense?
Favicon
Go-DOM - 1st major milestone
Favicon
Stop saying that Test-Driven Development is just a testing methodology!
Favicon
Minitest Advantages: Simple Testing for Rails Projects
Favicon
Comprehensive Testing in .NET 8: Using Moq and In-Memory Databases
Favicon
From PHPUnit to Go: Data-Driven Unit Testing for Go Developers
Favicon
YAGNI For Types
Favicon
Go-DOM - A headless browser written in Go.
Favicon
Test-Driven Development: A Comprehensive Guide
Favicon
There's no place for Test-Driven Development (TDD)
Favicon
EasyTdd 0.5.0: Streamlining Mocking with Incremental FluentMock
Favicon
Learn TDD with Ruby - Loops, Blocks and Strings
Favicon
Shaping the state of Test-Driven Development
Favicon
Test-Driven Development For Analytics Engineering
Favicon
Test Driven Api Development With Cypress
Favicon
Guide to Building a Complete Blog App with Django using TDD methodology and PostgreSQL database: Installation and Setup
Favicon
Mock server

Featured ones: