**Навіщо тести і чому pytest**
Тести — це виконуваня документація. Вони доводять що ваш код робить те що ви думаєте, і ловлять регресії при змінах. pytest — де-факто стандарт: менше шаблонного коду ніж `unittest`, потужний parametrize, величезна екосистема плагінів.
**Перший тест на pytest**
Будь-яка функція починається з `test_` у файлі починається з `test_` — автоматично виявляється:
```python
# test_math.py
def add(a, b):
return a + b
def test_add_integers():
assert add(2, 3) == 5
def test_add_floats():
assert add(0.1, 0.2) == pytest.approx(0.3)
```
**pytest assertions vs unittest**
pytest переписує `assert` щоб показувати детальні diff при невдачі:
```python
# стиль unittest:
self.assertEqual(result, [1, 2, 3])
self.assertRaises(ValueError, func, bad_arg)
# стиль pytest — чистий Python:
assert result == [1, 2, 3]
with pytest.raises(ValueError):
func(bad_arg)
```
**`@pytest.mark.parametrize` — тестування кількох вхідних даних**
```python
import pytest
@pytest.mark.parametrize('a, b, expected', [
(1, 2, 3),
(0, 0, 0),
(-1, 1, 0),
])
def test_add(a, b, expected):
assert add(a, b) == expected
```
**Тестування винятків**
```python
def test_divide_by_zero():
with pytest.raises(ZeroDivisionError, match='cannot divide'):
divide(10, 0)
def test_divide_by_zero_type():
with pytest.raises(ZeroDivisionError) as exc_info:
divide(10, 0)
assert 'zero' in str(exc_info.value)
```
Напишіть три тестові функції pytest для функції `add(a, b)`: `test_add_positive`, `test_add_negative` та `test_add_zero`. Кожна має викликати `add()` та перевіряти результат через `assert`.
Напишіть тести для функції `divide(a, b)`. Перевірте, що `divide(10, 2)` повертає `5.0`, і що `divide(10, 0)` викидає `ZeroDivisionError` за допомогою `pytest.raises`.
import pytest
def divide(a: float, b: float) -> float:
return a / b
def test_divide_normal():
pass
def test_divide_by_zero():
pass
Рішення
import pytest
def divide(a: float, b: float) -> float:
return a / b
def test_divide_normal():
assert divide(10, 2) == 5.0
def test_divide_by_zero():
with pytest.raises(ZeroDivisionError):
divide(10, 0)
Напишіть `@pytest.fixture` під назвою `sample_list`, що повертає `[3, 1, 4, 1, 5, 9]`. Напишіть два тести, що використовують її: `test_length` перевіряє `len == 6`, а `test_max` перевіряє `max == 9`.
Використайте `@pytest.mark.parametrize` для тестування `is_palindrome(s)` з п'ятьма випадками: `'racecar'` → True, `'hello'` → False, `'madam'` → True, `'a'` → True, `'ab'` → False. Запишіть всі п'ять як один параметризований тест.
Напишіть функцію `get_debug_mode() -> bool`, що читає змінну середовища `DEBUG` і повертає `True`, якщо вона дорівнює `'1'`, інакше `False`. Напишіть два тести з `monkeypatch.setenv`: `DEBUG=1` → True, `DEBUG=0` → False.
Функція `get_username()` викликає `os.getlogin()`, що може не працювати в CI. Використайте `monkeypatch.setattr`, щоб замінити `os.getlogin` лямбдою, що повертає `'testuser'`. Перевірте, що `get_username()` повертає `'testuser'`.
Напишіть фікстуру `temp_list`, що створює список `[1, 2, 3]`, повертає його через `yield`, потім очищає після тесту (teardown через `yield`). Напишіть тест `test_append`, що додає `4` і перевіряє `len == 4`.
import pytest
@pytest.fixture
def temp_list():
data = [1, 2, 3]
yield data
# teardown: очищення після тесту
pass
def test_append(temp_list):
temp_list.append(4)
assert len(temp_list) == 4
Рішення
import pytest
@pytest.fixture
def temp_list():
data = [1, 2, 3]
yield data
data.clear()
def test_append(temp_list):
temp_list.append(4)
assert len(temp_list) == 4
Напишіть функцію `write_and_read(path, text)`, що записує `text` до `path`, читає його назад та повертає вміст. Використайте вбудовану фікстуру `tmp_path` для тестування без реальної файлової системи.
from pathlib import Path
def write_and_read(path: Path, text: str) -> str:
path.write_text(text)
return path.read_text()
def test_write_and_read(tmp_path):
file = tmp_path / 'test.txt'
result = write_and_read(file, 'hello')
assert result == 'hello'
Рішення
from pathlib import Path
def write_and_read(path: Path, text: str) -> str:
path.write_text(text)
return path.read_text()
def test_write_and_read(tmp_path):
file = tmp_path / 'test.txt'
result = write_and_read(file, 'hello')
assert result == 'hello'
Маючи клас `Counter` з `increment()`, `decrement()` та властивістю `value`, напишіть фікстуру `counter`, що повертає свіжий `Counter()`. Напишіть тести: `test_initial_value` (value == 0), `test_increment` (value == 1), `test_decrement` (value == -1 після одного decrement).
Напишіть тести для функції `circle_area(r)` (повертає `math.pi * r ** 2`). Використайте `pytest.approx` для порівняння — звичайне `==` для float не спрацює. Тестуйте з `r=1` (~3.14159), `r=2` (~12.566) та `r=0` (0).
Ми використовуємо необхідні cookies для роботи сайту. З вашого дозволу ми також можемо зберігати налаштування сайту та використовувати аналітичні й рекламні cookies, щоб розуміти використання сайту й підтримувати розвиток проєкту.
* Ви завжди можете змінити свій вибір у налаштуваннях сайту.
Оберіть категорії cookies
Налаштування аналітики
Можна вимкнути аналітику використання платформи. Також можна надіслати в Google Analytics запит на видалення даних про використання цього сайту, пов'язаних із цим браузером.
Навчальний workspace
Навчайтеся, читаючи, запускаючи код і розв'язуючи задачі.
Практикуйте програмування з поясненнями тем, вправами, інструментами browser IDE, перевіркою regex і тренуванням друку коду в одному workspace.
Відкривайте інструменти у вкладках.Вправи, IDE-інструменти й тренажери залишаються доступними як вкладки сайту.
Перемикайтеся без втрати контексту.Переходьте між поясненнями, кодом та утилітами, зберігаючи своє місце.
Використовуйте sidebar як карту.Ліві панелі містять навігацію, налаштування, файли, libraries та керування інструментами.
PythonJavaScriptSQLite
Одна IDE, три практичні режими
Python у браузері.Запускайте невеликі скрипти, пробуйте бібліотеки й тренуйте API-запити без встановлення.
JavaScript для швидких експериментів.Перевіряйте код для браузера й порівнюйте ідеї поруч із навчальними матеріалами.
SQLite для практики з даними.Відкривайте оглядач бази даних, переглядайте таблиці, пишіть запити й вивчайте SQL локально.
ТемаIDE
Працюйте поруч у split tabs
Тримайте інструкції перед очима.Відкрийте вправу або довідкову сторінку поруч з IDE, замість постійних перемикань.
Порівнюйте інструменти під час навчання.Розміщуйте перевірки regex, пояснення та експерименти з кодом поруч, коли це потрібно для задачі.
Закрийте split, коли завершите.Workspace повернеться до однієї сфокусованої вкладки, а відкриті вкладки сайту залишаться доступними.
Тренажер друку коду
Або звичайного тексту
Тренажер розрахований на фізичну клавіатуру.Відкрийте цей розділ на ноутбуці або комп'ютері з широким екраном. На телефоні тренування друку не працюватиме коректно.
Швидкість: 0 зн/хв
0 слів/хв
Найкраща швидкість (60с): 0 зн/хв
0 слів/хв
Помилки: 0
Загальний час: 0.0 с
Щоб тренувати сліпий друк, не підглядайте на фізичну клавіатуру.