Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
July 30, 2022 06:15 am GMT

Test-Driven Development with Python

Test-driven development (TDD) is an established technique for delivering better software more rapidly and sustainably over time. It is a standard practice in software engineering.

In this blog, I'll be explaining about test-driven development (TDD) and a how-to guide to TDD with python. In case you didn't even hear about it, also tag along.

What is Test-Driven Development & Why?

Test-driven development (TDD) is a software development process relying on software requirements being converted to test cases before software is fully developed, and tracking all software development by repeatedly testing the software against all test cases. In short, It is when you write tests before you write the code that's being tested.

It has number of benefits

  • Improved design of the system
  • Better code quality and flexibility
  • Good documentation as a byproduct
  • Lower development costs and increased developer productivity
  • Enhanced developer satisfaction
  • Easier to maintain

The Process

Image description

  • Write tests
  • Get the tests to pass
  • Optimize the design (Refactor)
  • Repeat the process

Now let's look at how do TDD in python

Prerequisites

There are several widely used libraries in python to write tests. In this guide, I am using a library called pytest. So make sure to install it first.

pip install -U pytest

Let's consider a small function to check whether a password is valid or invalid

Writing Tests

Let's say a valid password meets the following requirements.

  • length must be greater than 8
  • should contain a uppercase letter [A-Z]
  • should contain a lowercase letter [a-z]
  • should contain a digit [0-9]

So the first step is to write the tests for the function. I'll start by declaring an empty function.

validator.py

def pw_validator(password):    pass

Now you can start writing tests in the same file or a separate file. The second option improves the code readability. If you choose to store the tests in a separate file, it should start with test_ to make it recognizable by pytest

test_validator.py

from validator import pw_validator

A test is basically a function that uses assert() method to check our validator returns the correct output. This test function also should start with test_.

Below you can see how I implemented some test functions with several valid & invalid passwords with the expected output.

def test_case_1():    assert pw_validator("8c4XTH&Z4a5z1Cxo") == Truedef test_case_2():    assert pw_validator("m6oj4l*6r#s$") == False #doesn't contain any upper case letterdef test_case_3():    assert pw_validator("DU$8$256Q*W@V6!KSED@H") == False #doesn't contain any lower case letterdef test_case_4():    assert pw_validator("DO!OPhXnqCjBR&J") == False #doesn't contain any digitsdef test_case_5():    assert pw_validator("9s@X85") == False #length is lower than 8

Now you can simply type pytest in the console to run the tests.
Of course, the tests will fail first as we didn't implement the validator function yet.

Image description
Here each failed test is represented by a "F". Passes tests will be represented by a "."

When writing test functions you can include several assert methods in a single function. But the pytest understands each test by functions. So the best practice is to include assert methods in separate functions.

Implement the function to pass tests

After writing tests, we can start working on the validator function. You can check each required condition with an if else statement as below.

def pw_validator(password):    if len(password) >= 8:        if any(char.isdigit() for char in password):            if any(char.isupper() for char in password):                if any(char.islower() for char in password):                    return True                else:                    return False            else:                return False        else:            return False    else:        return False

Now you can see all the tests have passed after running pytest.
Image description
You might definitely not come up with the correct implementation at first. For example, say you forgot to add functionality to check whether the password length is greater than 8 characters. Then one of the tests will return as failed.

def pw_validator(password):        if any(char.isdigit() for char in password):            if any(char.isupper() for char in password):                if any(char.islower() for char in password):                    return True                else:                    return False            else:                return False        else:            return False

Image description
So your job is to improve the function until it passes all the tests.

Refactor

In this step, you'll make your code more readable, concise, and clean. In our case, you might notice the validator function seems a bit untidy with the if else tree. We can refactor it as below to improve quality.

def pw_validator(password):    return True if len(password) >= 8 and any(char.isdigit() for char in password) and any(char.isupper() for char in password) and any(char.islower() for char in password) else False

Now you can repeat the process by applying it to another function.

Conclusion

At this time, you might have a clear understanding of what TDD is and how to use it in your project. TDD is widely used in data science & machine learning as it involves lots of testing.

Image description


Original Link: https://dev.to/chamodperera/test-driven-development-with-python-2p5h

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To