четверг, 8 августа 2013 г.

Если ты можешь, то не обязательно должен

Отличная статья попалась мне пару дней назад на просторах Интернета.

Идея этой статьи заключается в том, что можно значительно снизить затраты на тестирование, если правильно его распланировать и организовать, а именно - тестировать функциональность на как можно более высоком уровне интеграции различных компонентов вашего приложения.
Тестировать то, с чем будет работать конечный пользователь, а не всё подряд.

При интеграционном (или читай - системном, как кому больше нравится) тестировании всей системы в целом, когда основные действия выполняются через интерфейс конечного пользователя (например, Web интерфейс вашего приложения) мы действительно покрываем тестами сразу все компоненты, работа которых скрыта от глаз пользователя и получаем шанс найти гораздо большее число дефектов.

Конечно, впадать в крайности не следует и для этого есть несколько причин.
Первая причина заключается в том, что редко какая система имеет действительно лишь один пользовательский интерфейс. Например, на многих проектах есть Web интерфейс и API интерфейс, используя которые возможно делать одни и те же действия.
В такой ситуации у вас будет два уровня, которые вы должны считать конечным пользовательским интерфейсом, соответственно, писать тесты на все возможные конечные пользовательские интерфейсы.


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

И поэтому я в который раз убеждаюсь в преимуществе создания автоматизированных тестов на основе историй использования - именно они наводят на мысль и о тестировании непосредственно конечного интерфейса пользователя, и о том, что необходимо тестировать User Stories, а не что-то другое.

Единственная реальная проблема при таком подходе - это отладка и диагностика упавших тестов. Объясняется эта проблема тем, что дефекты есть на всех уровнях и, тестируя самый верхний уровень интерфейса, мы совсем не сразу можем понять где закралась ошибка - в каком компоненте у нас есть проблема.
Вот, например - какой-то высокоуровневый тест не прошёл. У вас даже снимок экрана Web интерфейса есть - но там видно лишь то, что некоторый элемент не создался или же не удалился. Чтобы понять в чём причина вам нужно пойти и руками проверить этот же функционал на нескольких уровнях, проанализировать отладочные сообщения каждого из компонентов и установить где спрятан корень этого зла ) - т.е. от вас требуется вмешательство для выявления причин и описания обнаруженного дефекта - по результатам автоматического теста разработчик с трудом может понять что и в каком компоненте сломалось (если он не специально это сделал).

Поэтому хорошие подробные отчеты для таких тестов на основе историй использования просто необходимы, если вы не хотите всё время заниматься выяснением причин ошибок в тестах вместо того, чтобы заниматься чем-нибудь интересным.