Testing is an important part of building software, but many developers, including me, sometimes skip it. In this post, I want to share how I added tests to my Python project, the tools I used, how I set them up, and what I learned along the way.
Tools I Chose for Testing
For my project, I decided to use pytest as my main testing framework and pytest-cov for code coverage because they are widely used, easy to set up, and provide clear feedback on test results and coverage.
- pytest: pytest is a popular Python testing framework. It’s easy to use, supports simple tests, and has many features like fixtures and parameterized tests.
- pytest-cov: This plugin works with pytest to show which parts of your code are covered by tests. It helps you find which lines are being missed.
I also used pytest-watch (ptw) to automatically run tests whenever I make changes. This makes development faster and helps catch problems immediately.
Setting Up Testing in My Project
- Install dependencies:
pip install pytest pytest-cov pytest-watch
- Project Organization
I kept the source code in src/ and tests in tests/. Each file in the source has a corresponding test file, e.g., file_processor.py has tests/test_file_processor.py.
- Writing Tests
I created test classes and methods for each function. For example:
class TestNormalizePath:
def setup_method(self):
self.processor = FileProcessor()
def test_normalize_path_basic(self):
path = Path("C:\\Users\\Example\\File.TXT")
result = self.processor._normalize_path(path)
assert result == "c:/users/example/file.txt"
- Running Tests
pytest -v # run all tests
pytest -v tests/test_file_processor.py # run a single test file
pytest -v tests/test_file_processor.py::TestNormalizePath::test_normalize_path_basic # run a single test
ptw # watch for changes and run tests automatically
- Check Code Coverage
pytest --cov=src/
I also made scripts (scripts/test.sh for Linux/macOS and scripts/test.bat for Windows) so anyone can run tests and see coverage easily.
What I Learned
- Think like a pessimist: Writing tests made me consider all edge cases, like empty inputs or file errors.
- Found hidden bugs: I found paths that didn’t normalize correctly on Windows and cases where the code failed if a file was outside the root directory.
- Small tests are better: Writing focused tests per function made debugging much easier.
My Takeaways
Before this project, I rarely wrote automated tests. I mostly ran scripts and checked results manually. Now, I see that:
- Tests prevent bugs when adding new features.
- Coverage reports show what needs more testing.
- Tests make the project easier for others to contribute to.
I plan to write tests for all my future Python projects. Adding code coverage and watch mode has improved my workflow and code quality a lot.
Top comments (0)