Everyone starts out programming with a simple program. Typically, some variation of "Hello World!" That's where I started at least and at first you make simple systems that do simple things. For example, a program that helps keep track of your to-do list items. At this point the code is pretty simple to read and see what is going on. If there is a bug somewhere, you can easily track it down and fix it.
Over time, you build more and more features on to your app. For example, you add the ability to put tags on your to-do items or you add the ability to export them to CSV. You keep adding more and more features that you need to use. Each time you add something new the code tends to get more and more complicated.
At this point things start to break and it takes more and more time to track down the specific problem in the code since everything has become interconnected. On top of that, one of your users just emailed you to tell you that some of the basic functionality that was available in the first version of the app is now no longer working.
How can you easily add functionality without running the risk of breaking a feature that already exists? Each time you add something, are you going to have to manually test every little feature to make sure it works?
Enter Test-Driven Development (TDD)
Test-Driven Development, usually abbreviated as TDD, helps you catch and fix bugs early in the development process, improves the quality of your code, and keeps your code from regressing, (ie. another feature stops working when you add a new one). TDD can help provide a fast feedback loop that will spot bugs before you release it to new users. In mission critical systems, tests are essential to keeping your system from going down when it is needed the most.
On top of that, it can help you get a clear understanding of what you actually want your code to do with the inputs you are providing it. TDD helps you define the system specifics so that you and your team has a clear understanding of what you are trying to build.
Step by Step: How to Write Tests for Software Development
Identify the functionality to be added to your system or, if you have already written the code, the expected functionality you want to test.
Write a test case for the functionality. If it is a large multi-step process your piece of software has to go through you might want to write one test for the whole process and one for each critical step in the process so that you can quickly isolate an issue later.
Run the test. Obviously, if you haven't written any code this will fail. If you have written code and the test fails, you will want to go back and verify if you have written the test properly.
Write/Refactor the code. Write code to fulfill the functionality. This is where writing tests for each step of the process is useful, since you can write each step and test to see if it is valid before moving on.
Repeat 4 & 5 to clean up and refactor your code. If the tests pass, ask yourself if there is anything you can do to make the process more efficient or simpler.
Continue this process until all functionality is implemented.
Keep in mind that in the real world, we all have deadlines to meet and you might not be able to repeat steps 4 & 5 enough times to write good, clean code. You might have to simply settle for what works for now and move on. That's okay because you have written the test, and later, when you have time, you will be able to revisit the code and refactor it more. For now though, you know that it works.
How to Install Pytest and Get Started
- Install Pytest. If you are using a virtual environment, like virtualenv. Make sure you have it activated and simply type
pip install pytest
in your terminal. - Create a test directory. The industry standard is
\test
, but it could be anything. - Write tests. Write test functions in .py files within the test directory you created earlier. All test functions should start with the
test_
prefix. We will go over an example later. - Run pytest. If you run the command
pytest
all tests in the current directory and subdirectory will be ran. I personally run it with--tb=native
to receive tracebacks in native format as well as--verbose
so that each test function is explicitly listed out.
How do you Write a Test?
Tests are pretty straightforward. You have to first start by importing the module that you would like to test. Let's imagine we have a hello
module that has a world
class and we want to make sure it always returns the str
"Hello World!" when we call the greeting()
function. We can do that with the following code:
from hello import world
def test_greeting():
new_world = world()
result = new_world.greeting()
assert result == "Hello World!"
This is an obviously very simple test, but hopefully you can get the idea of how to get started with pytest
and make your code much more reliable. I'll be walking you through more and more complex examples over the next few weeks.
Top comments (0)