TDD Lab: Proof That Writing Tests First Works – Proven

Learn how to apply Test Driven Development (TDD) in Python by validating IPv4 addresses with unit tests in this hands-on Cisco DevNet Associate lab.


Cisco DevNet Associate course 009 Software Development and Design Test Driven Development TDD – Lab

Watch Full Demo on YouTube:

Introduction:

In this lab, we continue our deep dive into software development principles from the Cisco DevNet Associate course. Following our previous video where we explored the theory behind Test Driven Development (TDD), it’s time to get hands-on.

We’ll walk through a complete TDD cycle using a practical example: validating IPv4 addresses. This lab will demonstrate how to apply the Red-Green-Refactor loop step by step using Python, and you’ll see how TDD improves code reliability, clarity, and confidence.


🧠 What You’ll Learn

  • How to write test cases before writing the actual code.
  • How to follow the TDD life cycle: Write a Test → Watch it Fail → Write the Code → Watch it Pass → Clean it Up.
  • How to apply test automation using Python’s built-in unittest framework.
  • How to refactor code and implement input validation for end users.

🧪 Use Case: Validating IPv4 Addresses

Imagine you’re building a tool that validates user-provided IP addresses in a network automation script. This is a common need in DevNet projects where user input must be sanitized and checked before use.

  • Write tests that define what “valid” and “invalid” IP addresses look like.
  • Write just enough code to make those tests pass.
  • Clean up and optimize once we’re confident the functionality works.

Write just enough code to make those tests pass.


📁 Project Structure

We’ll work with three files:


009_tdd_lab/
├── ip_validator.py
├── main.py
└── test_ip_validator_class.py

🧪 Step 1 – Writing the Test Class

First, we create a file named test_ip_validator_class.py. This defines the behaviors we expect from our IP validation logic. We use the unittest module to set up our tests:


import unittest
from ip_validator import IPValidator

class TestIPValidator(unittest.TestCase):
    def setUp(self):
        self.validator = IPValidator()

    def test_valid_ipv4(self):
        self.assertTrue(self.validator.is_valid_ipv4("192.168.1.1"))

    def test_invalid_ipv4_letters(self):
        self.assertFalse(self.validator.is_valid_ipv4("192.abc.1.1"))

    def test_invalid_ipv4_out_of_range(self):
        self.assertFalse(self.validator.is_valid_ipv4("256.100.50.25"))

    def test_invalid_ipv4_too_few_octets(self):
        self.assertFalse(self.validator.is_valid_ipv4("10.10.10"))

    def test_invalid_ipv4_too_many_octets(self):
        self.assertFalse(self.validator.is_valid_ipv4("10.10.10.10.10"))

if __name__ == "__main__":
    unittest.main(verbosity=2)

We expect these tests to fail at first — that’s exactly what we want in the TDD cycle.

🔧 Step 2 – Writing the Minimum Code to Pass the Tests

Now, we create the ip_validator.py file. This is where we’ll define the actual logic for validating IPv4 addresses. Let’s start with the basic class structure:


class IPValidator:
    def is_valid_ipv4(self, ip):
        parts = ip.split(".")
        if len(parts) != 4:
            return False
        for part in parts:
            if not part.isdigit():
                return False
            num = int(part)
            if num < 0 or num > 255:
                return False
        return True

This logic:

  • Splits the input by . and checks for exactly 4 parts.
  • Ensures each part is numeric.
  • Converts each part to an integer and checks it’s between 0 and 255.

✅ Step 3 – Run Tests and Refactor

At this stage, running python3 test_ip_validator_class.py should show all tests passing. That means our logic is solid.


test_invalid_ipv4_letters ... ok
test_invalid_ipv4_out_of_range ... ok
test_invalid_ipv4_too_few_octets ... ok
test_invalid_ipv4_too_many_octets ... ok
test_valid_ipv4 ... ok

If needed, we can now refactor the code for readability without changing its behaviour.

👨‍💻 Step 4 – Allow User Interaction

Finally, let’s let end users interact with the IP validation logic. The main.py script provides a CLI where users can input IP addresses manually:


from ip_validator import IPValidator

def main():
    validator = IPValidator()
    
    while True:
        ip = input("Enter an IPv4 address to validate (or 'exit' to quit): ")
        if ip.lower() == "exit":
            print("Exiting the validator. Goodbye!")
            break
        if validator.is_valid_ipv4(ip):
            print(f"✅ '{ip}' is a valid IPv4 address.\n")
        else:
            print(f"❌ '{ip}' is NOT a valid IPv4 address.\n")

if __name__ == "__main__":
    main()

This script loops until the user types exit. For each input, it checks if the IP is valid using the same class we tested earlier.

🎯 Summary

With this TDD lab, you learned:

  • How to write automated unit tests first.
  • How to implement the actual logic second.
  • How to validate inputs interactively.

This method ensures your code is tested, maintainable, and trustworthy before being deployed or scaled.

📚 Want to Learn More?

This lab is part of the Cisco DevNet Associate 009 – Software Development and Design series. For the theoretical overview of TDD, check out the previous post or video:
👉 Think Before You Code: The Theory Behind TDD

🧾 Conclusion

By walking through this hands-on TDD lab, you’ve not only learned how to validate IPv4 addresses using Python, but you’ve also seen Test-Driven Development (TDD) in action—from writing your test cases first, to building the logic that makes them pass, and finally allowing real user input to validate IP addresses.

This is the core of TDD: writing tests before code, focusing on small, manageable steps, and building confidence that your code works as intended. It also ensures that future changes won’t silently break existing functionality.

As you continue your Cisco DevNet Associate journey, keep practicing this mindset. Whether you’re building automation scripts or full applications, TDD is a powerful tool that helps create clean, reliable, and maintainable code.

Ready for the next challenge? Try extending the script to validate IPv6 addresses or handle CIDR notation. The possibilities are endless when you build with tests in mind.

References:

DevNet Associate – Cisco

Cisco Certified DevNet Expert (v1.0) Equipment and Software List

DevNet Associate Exam Topics

TDD Theory


Discover more from IEE

Subscribe to get the latest posts sent to your email.


Discover more from IEE

Subscribe now to keep reading and get access to the full archive.

Continue reading