Как проверяешь свою работу на наличие ошибок
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Как проверяешь свою работу на наличие ошибок
Качество собственной работы — это профессиональная ответственность каждого QA Engineer. Я использую комплексный подход, чтобы убедиться, что мои тесты надёжны, моя работа точна и не содержит критических ошибок.
1. Проверка качества автоматизированных тестов
Code Review собственного кода:
- Читаю тесты как будто их писал кто-то другой
- Проверяю читаемость и понятность
- Ищу дублирование кода (DRY принцип)
- Убеждаюсь, что имена переменных и функций описательные
Примеры проверок:
# ❌ Плохо
def test1():
b = get_data()
a = b[0]
assert a == 5
# ✅ Хорошо
def test_user_age_equals_five():
user_age = get_user_age()
assert user_age == 5
Anti-patterns в тестах:
- Несколько assertions в одном тесте (один тест = один сценарий)
- Зависимость между тестами (порядок выполнения)
- Hardcoded данные вместо fixtures
- Игнорирование edge cases
2. Запуск тестов в разных условиях
Локальное окружение:
- Запускаю тесты несколько раз подряд — должны быть всегда green
- Если тест flaky (иногда падает, иногда проходит) — это ошибка
- Включаю parallel execution — проверяю, нет ли race conditions
Проверка на flakiness:
# Запустить тесты 10 раз подряд
for i in {1..10}; do pytest tests/ || exit 1; done
Если тесты иногда падают на параллельном выполнении, это говорит о проблемах:
- Недостаточной изоляции тестов
- Использовании shared state
- Timing issues (слишком быстрая проверка результатов)
Чистое окружение:
- Перед запуском — очищаю данные (reset БД, очистить кэши)
- После запуска — удаляю тестовые данные
- Проверяю, что тесты не оставили побочных эффектов
3. Проверка покрытия функциональности
Code Coverage:
pytest --cov=app --cov-report=html tests/
Анализ отчёта:
- Минимум 80-90% покрытия (в зависимости от project требований)
- Ищу необработанные ветки:
if,try-except, условия - Проверяю, что критический код покрыт, необязательный может быть ниже
Пример анализа:
def validate_email(email: str) -> bool:
if not email: # Этот путь покрыт? Если нет — баг в тестах
return False
if "@" not in email: # Этот путь покрыт?
return False
return True
Метрики для отслеживания:
- Line coverage (количество строк кода)
- Branch coverage (все ветки условий)
- Function coverage (все функции вызваны)
4. Анализ результатов логов и отчётов
Логирование тестов:
- Каждый тест должен выводить информацию: что тестирует, что ожидает
- Лог должен быть достаточно подробным для диагностики
Пример хорошего лога:
[INFO] Тест: test_user_registration
[INFO] Шаг 1: Отправляем POST /api/users с данными {"email": "test@gmail.com"}
[INFO] Шаг 2: Ожидаем статус 201 Created
[DEBUG] Ответ: {"id": 123, "email": "test@gmail.com", "status": "active"}
[INFO] Шаг 3: Проверяем БД: SELECT * FROM users WHERE id=123
[DEBUG] БД результат: 1 запись найдена
[PASS] Тест пройден
Анализ отчётов:
- После запуска полного тест-сюита смотрю summary
- Проверяю failed tests — почему упали?
- Анализирую skipped tests — нужно ли их пропускать?
5. Проверка граничных случаев
Чек-лист граничных случаев:
- Нулевые и пустые значения
- Очень большие числа (Integer.MAX_VALUE)
- Очень длинные строки
- Null pointers / None
- Негативные числа
- Специальные символы в строках
Примеры:
def test_discount_calculations():
# Граница: 0%
assert calculate_price_with_discount(100, 0) == 100
# Граница: 100% скидка
assert calculate_price_with_discount(100, 100) == 0
# Некорректные данные
assert calculate_price_with_discount(100, -10) raises ValueError
assert calculate_price_with_discount(100, 101) raises ValueError
6. Тестирование собственных тестов
Mutation Testing — убить тест: Захожу в реальный код и специально вношу баг. Если тесты не упали — мне нужно улучшить тесты.
Пример:
# Оригинальный код
def is_adult(age: int) -> bool:
return age >= 18
# Мой тест
def test_is_adult():
assert is_adult(18) == True
# Я специально меняю code на age >= 19
if is_adult(18): # Тест должен упасть!
# Если не упал — мой тест слабый, нужно добавить граничный случай
7. Peer Review
Попрошу коллегу проверить:
- Логику тестов
- Качество кода
- Покрытие функциональности
- Понятность для других разработчиков
Что смотрит рецензент:
- Это тестирует именно то, что нужно?
- Есть ли лучший способ написать?
- Не забыл ли я граничные случаи?
- Будет ли этот тест нарушаться при нормальном refactoring кода?
8. Проверка на наличие технического долга
TODO и FIXME комментарии:
def test_payment_processing():
# TODO: добавить тест для cancelled платежей
pass
Передо мной не должно быть незавершённых todos.
Deprecated dependencies:
pip check # Проверить на устаревшие зависимости
Неиспользуемый код:
vulture tests/ # Найти неиспользуемые переменные и функции
9. Проверка регрессии
Запуск полного тест-сюита:
- После моих изменений запускаю ALL тесты, не только свои
- Проверяю, не сломал ли я что-то в других местах
- Убеждаюсь, что мои тесты не конфликтуют с существующими
10. Документация и комментарии
Самопроверка документации:
- Каждый тест должен иметь docstring, объясняющий что он тестирует
- Сложная логика должна быть задокументирована
- Примеры использования в README
def test_concurrent_user_updates():
"""
Тест проверяет race condition при одновременном обновлении профиля.
Сценарий:
- Пользователь 1 обновляет имя на "Alice"
- Одновременно пользователь 2 обновляет email
- Оба обновления должны сохраниться без конфликтов
"""
Инструменты для автоматической проверки
# Линтер — проверить стиль кода
pylint tests/
# Форматирование
black tests/ # Auto-format
# Type checking
mypy tests/ # Проверить типы
# Security issues
bandit tests/ # Найти уязвимости
# Все в одном
pre-commit run --all-files
Мой личный процесс перед commit-ом
- ✅ Запустить тесты локально 3 раза (проверка flakiness)
- ✅ Проверить code coverage — минимум 85%
- ✅ Запустить линтеры (pylint, mypy, black)
- ✅ Перечитать собственный код и найти ошибки
- ✅ Проверить граничные случаи
- ✅ Запустить ALL тесты (не только свои)
- ✅ Отправить на review коллеге
- ✅ Исправить замечания
- ✅ Final запуск тестов
- ✅ Commit с информативным сообщением
Это не просто перфекционизм — это профессионализм. Опытный QA знает, что качество своей работы отражается на качестве продукта.