Я хотел бы начать больше тестирования модулей в своих приложениях, но мне кажется, что большая часть всего, что я делаю, просто не подходит для тестирования модулей. Я знаю, как модульные тесты должны работать в примерах учебников, но в реальных приложениях они мало чем полезны.
Некоторые приложения, которые я пишу, имеют очень простую логику и сложное взаимодействие с вещами, которые находятся вне моего контроля. Например, я хотел бы написать демона, который реагирует на сигналы, посылаемые некоторыми приложениями, и изменяет некоторые пользовательские настройки в ОС. Я вижу три трудности:
- сначала я должен иметь возможность говорить с приложениями и получать уведомления об их событиях;
- тогда мне нужно взаимодействовать с ОС всякий раз, когда я получаю сигнал, чтобы изменить соответствующие пользовательские настройки;
- Наконец, все это должно работать как демон.
Все эти вещи потенциально деликатные: мне придется просматривать, возможно, сложные API-интерфейсы, и я могу ввести ошибки, скажем, неверно истолковывая некоторые параметры. Что может сделать для меня тестирование? Я могу высмеять как внешнее приложение, так и ОС, и проверить, что с учетом сигнала из приложения я вызову соответствующий API-метод в ОС. Это... ну, тривиальная часть приложения.
На самом деле большинство вещей, которые я делаю, связаны с взаимодействием с базами данных, файловой системой или другими приложениями, и это самые деликатные части.
В другом примере посмотрите мой инструмент сборки PHPmake. Я хотел бы реорганизовать его, поскольку он не очень хорошо написан, но я боюсь сделать это, поскольку у меня нет тестов. Поэтому я хотел бы добавить некоторые. Дело в том, что вещи, которые могут быть нарушены рефакторингом, не могут быть пойманы модульными тестами:
- Один из способов сделать это - решить, какие вещи нужно построить и какой из них уже обновлен, и это зависит от времени последней модификации файлов. Это время фактически изменяется внешними процессами, когда запускается некоторая команда сборки.
- Я хочу быть уверенным, что вывод внешних процессов отображается правильно. Иногда команды buikd требуют ввода, и это также должно управляться правильно. Но я не знаю априори, какие процессы будут выполняться - это может быть что угодно.
- Некоторая логика связана с сопоставлением шаблонов, и это может показаться проверяемой частью. Но функции, которые используют сопоставление шаблонов (добавление к их собственной логике), используют функцию PHP
glob
, которая работает с файловой системой. Если я просто высмеиваю дерево вместо фактической файловой системы,glob
не будет работать.
Я мог бы привести больше примеров, но дело в следующем. Если у меня нет деликатных алгоритмов, большинство из того, что я делаю, связано с взаимодействием с внешними ресурсами, и это не подходит для модульного тестирования. Более того, часто это взаимодействие фактически является нетривиальной частью. Тем не менее многие люди рассматривают модульное тестирование как базовый инструмент. Что мне не хватает? Как я могу научиться быть лучшим тестером?