(c) Harry Robinson
Продолжаем дискотеку
Слова:
SUT = System Under Test
Что у нас на входе обычного теста для SUT?
- Какие-то тестовые входные данные
- Данные предусловия
- Предусловия на состояние самой системы
- Входные данные среды
- Прочая бла бла бла
Все это в общем-то имеет свои же выходные данные: результаты тесты, среда после теста, система после теста, данные в системе после теста. Зачастую этого всего уже слишком много для несчастного человечка чтобы учитывать. В итоге большую часть входных данных человечек берет и тупо хардкодит. Нуачо? Проверить все не можем и не хотим, не можем контролировать входные данные в количестве, не знаем вообще что туда может попасть и так далее. Потому тупо захардкодить это надежный вариант из которого, что не удивительно, мы получаем много регрессионных тестов, которые ничего и не находят обычно (и в принципе это не удивительно).
И что это значит?
Ну некто Harry Robinson приводит пример поиска в документах. Если мы берем заданные документы и прогоняем по ним тесты которые ищут заданные слова в этих документах, то мы в общем-то знаем только то что эти слова в этих документах ищутся. Все. Мы не уверены, что:
- Эти слова найдутся в других документах
- Другие слова найдутся в других документах
- Другие слова найдутся в этих документах
Получается реально дофига. И все это дофига ручками покрыть будет сложно да и хардкоднутыми автотестами тоже заколебаться можно. Но нам никто не мешает автоматически генерировать документы и слова для поиска, например. Точно так же нам никто не мешает написать логику для определения результатов разных тестов и сценариев. В случае поиска по документу она вообще будет довольно простой. Так же в случае с тестированием не обязательно заморачиваться на агоритмы и прочая прочая. Это не боевая среда и мы можем себе позволить использовать простенькие алгоритмы которые будут относительно медленно принимать решения по результатам тестов. Это нормально, потому как нас в первую очередь интересует корректность, а не скорость.
Опять же мы можем сделать архитектуру тестов достаточно простой. Вынести все зависимые от среды вещи наружу и поставить их на зависимости от конфигов деплоя, например. А внутри оставить чистую логику.
Логеко?
Да, логика определения результатов. Не обязательно бинарный вывод (прошел/упал), можно сделать и более удобный прошел/выглядит подозрительно/упал. Мы можем сравнивать результат работы приложения с другим результатом (можем даже предсказывать этот результат). Мы точно так же можем сравнивать поведение приложения. Понятно что в случае когда результат предсказанный и результат действительный совпадают нам уже не очень интересно, т.к. тут все понятно. Но тут возникают ньюансы:
- Ложные ошибки: ну действительно, иногда разница значений на выходе нам не важна.
- Четность ошибок = все отлично: ошиблись в предсказании результата, ошиблась программа - тесты пишут что все ок (человек тоже так может ошибаться, да).
В итоге получаем что автоматизация тестов таким вот образом опирается в нашу способность формализовать распознание корректности/некорректности работы SUT.
Нам нужно чтобы логика всего этого добра обладала:
- Полнотой информации (покрытие входных/выходных данных, покрытие функционала, достаточность, корректность обработки ошибок, покрытие среды и т.д. и т.п.)
- Точностью своих выходных данных (арифметически и статистически сравнима с SUT, не зависела от SUT, размеры, типы ошибок и прочие тонкие места которые могут нам создавать искусственные ошибки)
- Пригодностью для использования (легко и непринужденно использовалась, работала там же где и SUT и т.д. и т.п.)
- Относительной легкостью в поддержке (нужно закладываться на изменения логики вслед за изменениями работы логики SUT, что накладывает определенные ограничения на ее сложность)
- Сравнительной простотой в сравнении с SUT (опять же - нам важно покрытие функционала SUT и симуляция поведения SUT, но когда это становится едва ли не сложнее чем сама SUT - ну его нафиг такие тесты)
- Временными отношениями с SUT (когда и как быстро генерировать входные данные и результаты, когда проверять)
- Приемлемой стоимостью (цена промаха, цена ложной ошибки, цена реализации, ценя поддержки логики в актуальном состоянии и так далее)
В идеале логика сама по себе должна быть:
- Полностью независимой
- Полностью покрывать все аспекты SUT
- Давать только корректные результаты
Но это что? Это фактически то же самое что написать SUT только без багов. То есть дорого и практически невозможно.
Тут начинаем обманывать.
Можно проверять на консистентность результатов. Будет работать только при уже имеющейся сравнительно серьезной базе, ну да фиг с ним. Что делаем?
- Берем предыдущие результаты
- Загоняем в систему
- Выносим приговор
- Заносим текущие результаты
Можно просто сравнивать с предыдущим и палиться на любые изменения. Можно вычислять статистически верное решение. Но дырки этого способа и так очевидны, хотя он и применим для некоторых областей в чистом виде.
Можно тупо включать во входные данные правильность результата. Это может быть просто сам результат или же как-той ключик. Вариантов много, но проблема одна - мы должны заранее задавать результат.
Можно написать модель поведения SUT, которая сама будет определять что такое хорошо, а что такое плохо. Это очень классный подход, про него много пишет Harry Robinson. Но так же он много пишет про оптимизацию этих моделей, про декомпозицию и т.п. Потому как есть серьезная проблема - как только у нас возникают очень сложные модели нам сразу становится сложно их поддерживать и начинает расти вероятность ошибки внутри самой модели, что так же плохо. Хотя и бонусы солидные - нам по сути нужно заниматься только поддержкой модели, потому как все тесты будут генерироваться из нее.
Можно эвристически подходить к оценке результатов. Например загонять огромное количество данных в SUT, статистически анализировать машинкой результат и смотреть самые "популярные" результаты на корректность. Дешево, сердито и в общем-то практически ручная работа, с той лишь разницей что ручками работаем со статистически "верными" результатами.
Вариантов много. Пока примемся за Robinson'а.
Комментариев нет:
Отправить комментарий