Оператор `assert` у чистому Python є мінімальним: якщо вираз хибний, він підіймає `AssertionError` без жодної корисної інформації:
```python
# чистий assert Python
assert result == expected
# → AssertionError (лише виняток, більше нічого)
```
pytest вирішує це за допомогою **перезапису тверджень**. Коли pytest імпортує ваш тестовий файл, він трансформує байт-код так, що кожен `assert` захоплює обидві сторони порівняння до обчислення. При провалі ви бачите, що саме відрізнялось:
```
# порівняння списків:
AssertionError: assert [1, 2, 3] == [1, 2, 4]
At index 2 diff: 3 != 4
# порівняння словників:
AssertionError: assert {'name': 'Alice', 'age': 31} == {'name': 'Alice', 'age': 30}
Differing items:
{'age': 31} != {'age': 30}
# порівняння рядків:
AssertionError: assert 'hello earth' == 'hello world'
At position 6 diff: 'e' != 'w'
```
Це робить провали само-діагностувальними. Ви бачите *що* відрізнялось, а не просто *те, що* щось відрізнялось.
**`==` vs `is`**
`==` перевіряє *рівність* (однакове значення). `is` перевіряє *ідентичність* (той самий об'єкт у пам'яті). Використовуйте `is` для булевих значень і `None`:
```python
assert result is True # result є булевим True
assert result == True # теж працює, але 1 == True теж True (менш суворо)
assert result is not None # чітко і ідіоматично
```
Для чисел, рядків і колекцій завжди використовуйте `==`. Перевірка `is` для рядків і цілих чисел може давати несподівані результати через інтернування об'єктів у Python.
**Заперечення:**
```python
assert x != y # не рівне
assert x not in lst # не в колекції
assert not condition # загальне заперечення
```
**Власне повідомлення при провалі:**
Додайте повідомлення після твердження -- pytest показує його разом з самим твердженням:
```python
assert score >= 50, f"Expected score >= 50, got {score}"
# → AssertionError: Expected score >= 50, got 42
# assert 42 >= 50
```
**Порівняння чисел з плаваючою точкою:**
`0.1 + 0.2` у Python не є рівно `0.3` через двійкове представлення дійсних чисел. Використовуйте `pytest.approx`:
```python
import pytest
assert 0.1 + 0.2 == pytest.approx(0.3) # за замовчуванням: відносна похибка 1e-6
assert result == pytest.approx(1.5, rel=1e-3) # у межах 0.1%
assert result == pytest.approx(0.0, abs=1e-9) # абсолютна похибка (краще поблизу нуля)
```
Використовуйте `rel` (відносна), коли величина велика; використовуйте `abs` (абсолютна), коли очікуване значення дорівнює нулю або близьке до нього (ділення на нуль у відносній перевірці було б проблемою).
```python
# Рівність / нерівність
assert x == y
assert x != y
# Впорядкування
assert x > y
assert x >= y
assert x < y
assert x <= y
# Належність
assert item in collection
assert item not in collection
# Тип
assert isinstance(obj, SomeClass) # також збігається з підкласами
assert type(obj) is int # лише точний тип
# Істинність
assert value # істинне (ненульове, непорожнє, не None)
assert not value # хибне
# Числа з плаваючою точкою
assert x == pytest.approx(y) # відносна похибка 1e-6 за замовчуванням
assert x == pytest.approx(y, rel=1e-3) # похибка 0.1%
assert x == pytest.approx(y, abs=0.01) # абсолютна похибка +-0.01
# Рядки
assert s.startswith('prefix')
assert s.endswith('suffix')
assert 'substring' in s
# Власне повідомлення при провалі
assert condition, f"Описове повідомлення: отримано {value}"
```
Напишіть тести для `to_celsius(f)`, яка конвертує градуси Фаренгейта в Цельсій за формулою `(f - 32) * 5 / 9`. Перевірте результат принаймні для трьох значень: 32F (0C), 212F (100C) і 98.6F (37C). Використовуйте `pytest.approx` для порівняння float.
Реалізуйте `circle_area(r)`, яка повертає `π * r²` з використанням `math.pi`. Напишіть тести, що перевіряють: площа при `r=3` приблизно дорівнює `28.274` (з допуском 0.1%), при `r=1` -- приблизно `3.14159`. Також перевірте `r=0`.
import math
import pytest
def circle_area(r):
pass # реалізуйте тут
def test_circle_area():
pass
Напишіть `top_scores(scores, n)`, яка повертає `n` найвищих балів зі списку, відсортованих у спадному порядку. Напишіть тести, що перевіряють: тип повернутого значення є списком, його довжина дорівнює `n`, конкретні значення присутні або відсутні.
def top_scores(scores, n):
pass # реалізуйте тут
def test_top_scores():
pass
Рішення
def top_scores(scores, n):
return sorted(scores, reverse=True)[:n]
def test_top_scores_returns_list():
result = top_scores([5, 1, 8, 3, 9], 3)
assert isinstance(result, list)
def test_top_scores_length():
result = top_scores([5, 1, 8, 3, 9], 3)
assert len(result) == 3
def test_top_scores_correct_values():
result = top_scores([5, 1, 8, 3, 9], 3)
assert 9 in result
assert 8 in result
assert 5 in result
assert 1 not in result
Напишіть `parse_user(s)`, яка парсить рядок виду `'name:Alice,age:30'` у словник. Напишіть тести, що перевіряють наявність конкретних ключів, правильність значень та відсутність неочікуваних ключів.
def parse_user(s):
result = {}
for pair in s.split(','):
key, value = pair.split(':')
result[key.strip()] = value.strip()
return result
def test_parse_user_name():
user = parse_user('name:Alice,age:30')
assert 'name' in user
assert user['name'] == 'Alice'
def test_parse_user_age():
user = parse_user('name:Alice,age:30')
assert 'age' in user
assert user['age'] == '30'
def test_parse_user_no_extra_keys():
user = parse_user('name:Alice,age:30')
assert 'email' not in user
assert len(user) == 2
Напишіть `format_greeting(name, title)`, яка повертає `'Dear {title}. {name},'`. Напишіть тести, що перевіряють: результат починається з 'Dear', закінчується на ',', містить ім'я і не має подвійних пробілів.
def format_greeting(name, title):
pass # реалізуйте тут
def test_format_greeting():
pass
Рішення
def format_greeting(name, title):
return f'Dear {title}. {name},'
def test_greeting_starts_with_dear():
result = format_greeting('Smith', 'Dr')
assert result.startswith('Dear')
def test_greeting_ends_with_comma():
result = format_greeting('Smith', 'Dr')
assert result.endswith(',')
def test_greeting_contains_name():
result = format_greeting('Smith', 'Dr')
assert 'Smith' in result
def test_greeting_no_double_spaces():
result = format_greeting('Smith', 'Dr')
assert ' ' not in result
No split tab
Налаштування cookies
Ми використовуємо необхідні 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 с
Щоб тренувати сліпий друк, не підглядайте на фізичну клавіатуру.