✅ Решения заданий и ответы на вопросы самопроверки
Теоретические ответы
Ответ 1. Что такое Auto QA?
Auto QA — автоматизация тестирования: использование инструментов и скриптов для выполнения тестов с минимальным участием человека. Отличие от ручного тестирования: тесты запускаются автоматически при каждом коммите (CI/CD), выполняются быстро и воспроизводимо без участия человека.
Ответ 2. Пирамида тестирования
- Unit Tests — проверяют отдельные функции/методы в изоляции. Быстрые и дешёвые.
- Integration Tests — проверяют взаимодействие между компонентами. Медленнее и дороже.
- E2E Tests — проверяют систему целиком. Самые медленные и дорогие.
Unit-тестов больше, потому что они дёшевы, быстры и покрывают большую часть логики. E2E — дорогие и медленные, поэтому их используют только для критических сценариев.
Ответ 3. Тестирование ПО
Тестирование — не просто поиск багов, а проверка соответствия реального поведения программы ожидаемому. «Проверка ожиданий» означает: вы должны знать, что программа должна делать, и проверить, делает ли она именно это.
Ответ 4. Соглашения pytest
- Файлы: имена начинаются с
test_или заканчиваются на_test.py. - Функции: имена начинаются с
test_.
Если нарушить это правило — pytest не найдёт тест и не запустит его без ошибки (тест просто будет проигнорирован).
Ответ 5. Фикстура
@pytest.fixture позволяет создать ресурс один раз и передавать его в несколько тестов. Если создавать Calculator() в каждом тесте — код дублируется. С фикстурой — логика инициализации в одном месте, легко изменить.
Ответ 6. skip vs xfail
@pytest.mark.skip — тест полностью исключается из выполнения (ни запускается, ни проверяется). Используется, когда функциональность не готова. @pytest.mark.xfail — тест запускается, но ожидается его провал. Используется, когда известен баг или метод в разработке. Если xfail-тест вдруг пройдёт — pytest пометит его как xpass.
Ответ 7. Пользовательские маркеры
Регистрация в pytest.ini:
[pytest]
markers =
positive_test: Тесты для позитивных сценариев
Без регистрации pytest выдаст предупреждение PytestUnknownMarkWarning. Тесты всё равно запустятся, но в строгом режиме (--strict-markers) будет ошибка.
Ответ 8. pytest -k vs pytest -m
pytest -k "sum" — фильтрует по подстроке в имени теста. pytest -m positive_test — фильтрует по маркеру, заданному через декоратор. -k гибче для быстрого поиска, -m — для организованных категорий.
Решения практических заданий
Задание 1: Параметризация sub
# test_calculator.py
import pytest
from calculator import Calculator
@pytest.fixture
def calculator():
return Calculator()
@pytest.mark.parametrize('a, b, result', [
(10, 3, 7),
(-5, -3, -2),
(0, 5, -5)
])
def test_sub(a, b, result, calculator):
assert calculator.sub(a, b) == result
Задание 2: Маркировка negative_test
# pytest.ini
[pytest]
markers =
negative_test: Тесты для негативных сценариев
# test_calculator.py
@pytest.mark.negative_test
def test_division_by_zero(calculator):
with pytest.raises(ArithmeticError, match="На ноль делить нельзя"):
calculator.div(10, 0)
# Запуск
pytest -m negative_test
Задание 3: xfail
@pytest.mark.xfail(reason="Умышленная ошибка для демонстрации xfail")
def test_sum_wrong_expectation():
calculator = Calculator()
assert calculator.sum(1, 1) == 3 # Ожидаем 3, получим 2 -> xfail
Вывод pytest: XFAIL test_calculator.py::test_sum_wrong_expectation — тест провалился, как и ожидалось. Это нормальный статус, не ошибка.
Задание 4: SimpleMath с параметризацией
# test_simple_math_param.py
import pytest
from simple_math import SimpleMath
@pytest.fixture
def math():
return SimpleMath()
@pytest.mark.parametrize('n, result', [
(2, 4),
(-3, 9),
(0, 0),
(10, 100),
(-1, 1)
])
def test_square(n, result, math):
assert math.square(n) == result
@pytest.mark.parametrize('n, result', [
(3, 27),
(-2, -8),
(0, 0),
(1, 1),
(-1, -1)
])
def test_cube(n, result, math):
assert math.cube(n) == result