Testy w Python
unittest
Przykład testowanego pliku calculator.py:
# calculator.py file
def add(a, b):
return a + b
def multiply(a, b):
return a * b
def subtract(a, b):
return a - b
def divide(x, y):
if y == 0:
raise ValueError('Can not divide by zero!')
return x / y
Plik z testami test_calculator.py:
# test_calculator.py file
import unittest
import calculator
class TestCalculator(unittest.TestCase): # a test case for the calculator.py module
def test_add(self):
# tests for the add() function
self.assertEqual(calculator.add(6, 4), 10, 'Error when adding two positive numbers')
self.assertEqual(calculator.add(6, -4), 2)
def test_divide(self):
# tests for the divide() function
self.assertRaises(ValueError, calculator.divide, 5, 0)
# or:
with self.assertRaises(ValueError):
calculator.divide(6, 0)
Możliwe metody testowania:
Metoda | Co sprawdza? |
---|---|
assertEqual(a, b) | a == b |
assertNotEqual(a, b) | a != b |
assertTrue(x) | bool(x) is True |
assertFalse(x) | bool(x) is False |
assertIsNone(x) | x is None |
assertIsNotNone(x) | x is not None |
assertGreater(a, b) | a > b |
assertLess(a, b) | a < b |
assertIsInstance(a, b) | isinstance(a, b) |
assertRaises(exception, function, arguments) | Czy funkcja zwraca wyjątek |
Wywołanie testów z poziomu konsoli:
python -m unittest test_calculator
Komunikat w przypadku błędu:
FAIL: test_add (test_calculator.TestCalculator)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_calculator.py", line 11, in test_add
self.assertEqual(calculator.add(6, -4), 3)
AssertionError: 2 != 3
----------------------------------------------------------------------
Ran 1 test in 0.000s
Gdy projekt nie ma płaskiej struktury
Powyższa instrukcja jest prawidłowa, gdy struktura projektu jest płaska jak Ziemia:
.
├── calculator.py
└── test_calculator.py
Zwykle jednak chemy wydzielić testy do osobnego folderu:
new_project
├── calculator
│ ├── __init__.py # make it a package
│ └── calculator.py
└── test
├── __init__.py # make it a package
└── test_calculator.py
Konieczne będzie wprowadzenie kilku zmian:
- calculator.py i test_calculator.py plik zastały przeniesione do osobnych folderów
- w każdym z folderów tworzymy pusty plik init.py
- modyfikujemy w pliku test_calculator.py* linię importu jak poniżej:
# import calculator
from calculator import calculator
Wywołanie testów:
cd new_project
python -m unittest test.test_calculator
Można też wywołać konkretną klasę testową:
python -m unittest test.test_calculator.TestCalculator
Wywołanie wszystkich testów (discover) z folderu test dla plików z przedrostkiem test_:
cd new_project
python -m unittest discover
pytest (TBD)
python -m pytest ptest.py -v