• 10 hours
  • Medium

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 8/30/22

Understand Test-Driven Development

Of course, we can add a feature and then test it by running a script with various arguments, then create a pull request on GitHub. Or we could test it manually.

But in this chapter, we’re going to do things a bit differently. We’re going to be guided by testing when we create the functionality.

But don’t tests just do what we ask them to do?

Tests check that our code returns what we request. We could actually understand our program just by reading the tests! The test sequence provides us with documentation, because we can see examples of how our program is used.

Test-Driven Development (TDD) is a development technique that recommends writing tests before writing the source code for a piece of software.

Kent Beck, creator of the Extreme Programming agile project methodology, developed this technique during the 2000s. It then became widespread throughout the world.

The technique consists of three complementary phases:

  • Red: write a unit test and then run it. Obviously, it will fail.

  • Green: write source code that will pass the test.

  • Refactor: improve the source code.

Test-Driven Development consists of 3 phases : RED, write a test that will fail ; GREEN, write source code that will pass the test ; REFACTOR, improve the source code.
Test-Driven Development

What are the advantages of TDD? Why would you restrict yourself to these rules and processes?

Uncle Bob, in this brilliant video, tells us about the main advantages of using the TDD process:

  • Reduced debugging time: you’ll spend less time debugging because your code is tested in detail.

  • Confidence: you’ll become more confident and flexible.

  • Documentation: your tests will become your documentation, making it easier for other developers to use it.

  • Design: your code is improved because it is more modular and easier to test.

Add a Feature Using TDD: Red/Green/Refactor

To illustrate this theory, we’re going to use the TDD method to deploy a feature that will divide one number by another.

How do we convert TDD phases into code?

Let’s find out right now!

Red: Write the Test

Let’s start the first TDD phase and create a test that checks the division of two numbers. We’re going to check that when we call thedivision function with arguments of 10 and 5 as the numerator and the denominator, respectively, the return value is 2. It should come as no surprise that 10 divided by 5 is equal to 2!

Create the division function in a file that you’ll calldivision.py .

def division(numerator, denominator):
    pass

Add the following code to a new test file called test_division.py.

from division import division

def test_should_make_division():
    numerator = 10
    denominator = 5
    expected_value = 2

    assert division(numerator, denominator) == expected_value

Let’s run the test… And yes, there’s an error.

Running the test shows there is an error, as expected, as the source code hasn't been written yet.
First phase of TDD

Surprise surprise! Thedivision function has noreturn instruction and sends the value:  None. The test has therefore failed. But this time, we’re quite happy to see red all over our test!

We now need to go to the second phase, which involves doing what’s needed to pass this test (and this test alone) without worrying about the rest of the application.

Green: Write the Code

The block of code within the division function doesn’t actually exist. We’re now going to create the code we need to divide the numerator by the denominator. It’s really simple, we just need a single line of code.

def division(numerator, denominator):
    return numerator / denominator

Let’s try again… The test is green! Great!

The test is green, showing the code is valid.
Second phase of TDD

Refactor: Refactor the Code

I’ve just realized that we haven’t catered for a divide by zero scenario. We need to add some code to prevent the code from crashing

We opted to change the behavior of the function and return the None value if the denominator equals 0.

Firstly, let’s add the test to check the error handling:

def test_should_return_none_with_zero_division():
    numerator = 10
    denominator = 0
    expected_value = None

    assert division(numerator, denominator) == expected_value

And now you can add the code that will check the sequence of tests.

def division(numerator, denominator):
    try:
        return numerator / denominator

    except ZeroDivisionError:
        return None

Let’s run the tests again!

Both tests are green, the refactoring has been successful.
Third and final phase of TDD

Well done! All of our tests are green!

Note that if you’d decided to write the function differently, e.g., as follows...:

def division(numerator, denominator):
    if denominator == 0:
        return None
    return numerator / denominator

... the refactoring wouldn’t have failed the tests because the code logic hasn’t changed. The tests would still have been green. And that’s the aim of refactoring. Changes to the code shouldn’t cause the test to fail, but should improve the logic.

We’ve completed the third phase of TDD. You should be proud of yourself! We’ve completed the entire TDD cycle

We can now move on to the next test. We’ll start seeing red again, but it’ll go green when we make our corrections.

Go ahead and watch the screencast below, which takes you through the phases of the TDD method again. You’ll become an expert in TDD.

Over to You!

Now it’s time to get to work. You need to implement your first test-driven class.

Your Mission:

Create a class calledBankAccount with the following attributes:

  • surname

  • account_number

  • account_balance

Next, add the following methods:

  • account_information(): returns a dictionary containing account information.

  • withdraw(value): deducts an amount from the account balance.

  • deposit(value): adds an amount to the account balance.

You can see the different phases of TDD using this GitHub directory.

Let’s Recap!

  • Test-Driven Development (TDD) is a software development practice that involves first creating a unit test before developing the functionality within the source code.

  • TDD is an iterative development process that follows the red-green-refactor methodology.

    • Red: write a unit test.

    • Green: write source code that will pass the test.

    • Refactor: improve the source code.

Right, this time I promise we’ve really reached the end! Well done for all your hard work throughout the course. And I’ll see you shortly in the final chapter, where we’ll review what you’ve learned and check your skills in the final quiz. I know you love doing quizzes…

Example of certificate of achievement
Example of certificate of achievement