Re: Декомпозиция юнит-тестов
От: Sinix  
Дата: 28.04.16 08:41
Оценка: 6 (1)
Здравствуйте, FrozenHeart, Вы писали:

FH>Приветствую.


FH>Скажите, пожалуйста, какие правила используете Вы / Ваша компания при выделении кода в отдельные классы и функции используемого Вами testing framework'а?


Ну обычно начинают с того, что именно проверяет тест — сценарий использования (последовательность вызовов), или отдельный api point (набор перегрузок / родственных методов).

Для первого, понятное дело, никто не пишет перебор всех возможных комбинаций — их слишком много. Вместо этого тестами покрывают ключевые сценарии, желательно с помощью bdd-фреймворка, чтоб придерживаться одного стиля. Эти тесты заодно работают как тех.документация к API.

Для второго — есть варианты, я предпочитаю использовать подходящий по обстоятельствам.
* можно написать один тест на один метод и запихнуть в него все варианты. Удобно, если вариантов мало.
* можно сделать пару тестов — первый проверяет все корректные вызовы, второй — все некорректные.
* можно в одном тесте объединять проверки "парных" методов, если они тривиальны. Например для операторов сравнения <, <=, >, >= отдельные тесты городить часто лень.

Два главных правила:
* не смешивать разнородные проверки в тестах
* не лепить в один класс тесты, проверяющие принципиально разные вещи.

FH>Как видите, внутри функций test_dict_join и test_split_first_n находится код, проверяющий одновременно как ожидаемые входные значения, так и "исключительные" (всякие None, -1, 0 и т.д.).

FH>Такой подход нормален?
Абсолютно. Чисто с прагматичной точки зрения в большинстве случаев нет никакого смысла лепить тесты на порядок большие по объёму, чем ммелкий хелпер.


FH>Другой пример. Имеется класс TCPSocket, являющийся обёрткой над socket из стандартной библиотеки Python (с поддержкой with-statement'ов, read_until и прочим). Для него я поступил схожим образом:

а в питоне setup вызывается для всего suite или для каждого теста в отдельности? Если второе — ок. Если первое — fail, легко в одном тесте спрятать побочные эффекты для другого.


FH>*Какой функционал выносите в отдельные функции test case'ов?

FH>*Тестируете ли одновременно несколько входных значений внутри одного такого метода?
FH>*Когда и в каких ситуациях объединяете test case'ы в test suite?
По обстоятельствам, да, по обстоятельствам соответственно.

Серьёзно, главная цель юнит-теста — отловить ситуацию "мой код поломался". Смысл заморачиваться с этими проверками настолько серьёзно, чтоб прям подводить под них методическую базу?

Обычный подход: сделали базовое соглашение по стилю, правим в местах, когда оно мешает — все щасливы. Зачем что-то ещё?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.