Skip to content
This repository has been archived by the owner on May 31, 2024. It is now read-only.

Latest commit

 

History

History
153 lines (98 loc) · 3.62 KB

writing-unit-tests.md

File metadata and controls

153 lines (98 loc) · 3.62 KB
title description slideOptions
ESWN 2021 - Writing unit tests
Tutorial for 2021 ESWN PyGMT workshop
theme
solarized

Writing unit tests

Because tested code is code that you can trust

P.S. Slides are at https://hackmd.io/@pygmt/eswn-2021-writing-unit-tests


Why test?

Imagine choosing two vaccines 💉:

  • Vaccine 1 comes with the exact biochemical equations on how it works
  • How vaccine 2 works is a mystery, but it has been extensively tested on thousands of people, across diverse populations, with little side effects

Which one would you choose :thinking_face:?


Testing code helps to

  • Ensure functions work as expected 💚 (even if they seem like a black box)
  • Prevent bugs 🐛 from popping up over time
  • Give us confidence when refactoring ♻️ (i.e. rewriting) code to be more efficient, while keeping the same functionality

Structure of a unit test 🧪

Let's start with a simple Python function that adds two numbers:

def add(x, y):
    return x + y

Now let's check that this function works on two input numbers. We'll use a testing framework/library called pytest that allows us to easily check the output using assert statements.

def test_add():
    value = add(x=1.0, y=2.0)
    assert value == 3.0

Where do the tests go?

In a Python project using pytest, we usually structure our code in folders like so:

projectname/
  ├──__init__.py
  ├──src/
  │   └──calc.py (contains 'add' function)
  └──tests/
      ├──test_calc.py (contains 'test_add' function)
      └──__init__.py

The 'test_calc.py' file would contain:

from projectname.src.calc import add

def test_add():
    value = add(x=1.0, y=2.0)
    assert value == 3.0

Run tests using pytest

By default, pytest automatically searches for test_*.py files in the tests folder, and runs functions that start with a test_.

cd projectname/  # navigate to project folder
pytest           # run tests in tests/test_*.py files

will produce an output like so:

==================== test session starts =====================
platform linux -- Python 3.8.10, pytest-6.2.4
rootdir: /home/user/projectname
collected 1 item

tests/test_calc.py .                         [100%]

===================== 1 passed in 0.03s ======================

Run only specific tests 🎯

Projects can have >100 tests which take a long time to run. You can also run just one test file instead:

pytest projectname/tests/test_calc.py

Maybe that file has other functions like add/subtract/multiply/divide. You can be even more specific and run just the one that matches a keyword:

pytest -k add projectname/tests/test_calc.py

That's the basics of using pytest in a nutshell!


Useful resources 📖

PyGMT's testing guidelines

Basics of testing in Python

Test driven development


Thank you! 🐑