Хочу поделиться опытом по организации процесса тестирования, который охватывает 3 года моей работы и создание нескольких крупных систем. Описание будет затрагивать только автоматизацию «ручного» тестирования без пересечения с другими аспектами разработки ПО.
Я думаю стоит сразу упомянуть, что на всех этапах мы использовали:
Везде, где я буду говорить про автоматизацию тестирования, речь будет идти про тестирование интерфейса с подключением к внешним ресурсам (БД, файловая система, сервисы и т.п.).
На первом крупном проекте, в котором я участвовал, не было тестировщиков. Разработчики перед заливкой на боевой сервер сами проверяли основные части системы. При таком подходе частенько вылезали баги.
Для всех было очевидно, что программисты любят свой код и без особого энтузиазма подходят к тестированию только что написанной фичи. Про тестирование ранее написанных фич, да еще и другими разработчиками, вообще говорить не приходится. Программисты сами не станут заново прогонять всевозможные сценарии работы с системой и заходить во все вкладки всех страниц.
На самом деле на этом проекте мы могли себе позволить подобный подход. Наши пользователи сидели в зоне досягаемости. Это был проект по внутренней автоматизации компании. Операторы и менеджеры, которые работали с Системой, могли подойти к нам и обсудить функциональность, указать на ошибки. Соответственно мы могли сделать быстрый фикс и залить исправленную версию.
Отчеты об ошибках сводились к крикам за стенкой. Потери при багах были незначительные, ситуация всех устраивала.
Судя по опросу, который я проводил Как у вас устроен процесс тестирования? большинство может позволить себе именно такой подход к тестированию.
Мы начинали делать новую систему, которой должны были пользоваться не только люди за стенкой, но и сторонние пользователи. Появилась необходимость нанять тестировщика, который бы уберегал нас от плохих релизов.
Я нанял тестировщика и для начала мы решили, что тестирование должно быть автоматизированным, как запуск модульных тестов. Автоматизация должна была избавить тестировщика, от постоянного повторения одних и тех же сценариев.
Идея была проста и для всех казалась решением проблем. Мы хотели, чтобы CI запускала ночью набор интеграционных тестов. Утром мы приходим, если тесты все зеленые, то значит можно делать релиз. Если есть красные тесты, значит исправляем, снова запускаем весь набор тестов и т.д. пока все тесты не станут зелеными.
Для записи тестов попробовали разные варианты, остановились на Selenium. Сначала тесты писали на API самого Selenium. Со временем начала создаваться обертка над низкоуровневым API и эта обертка превращалась в некий DSL для тестирования.
Пока тестировщик разбирался с продуктами для тестирования и налаживал процесс автоматизации тестов разработка не останавливалась. Мы должны были выпускать новые версии после каждой 1-2 итераций. Тестировщик постоянно находился в стадии погони за программистами. Его цель была 100% покрытием сценариев, чтобы мы могли спокойно выпускать новые версии не боясь багов.
Проблемы с автоматизацией тестирования оказались для нас неожиданными. Фактически мы не были к ним готовы.
Чем больше была система, тем больше мы писали тестов. Тесты начали работать реально медленно. Если они проходили за 14 часов — это была невероятная удача. Со временем тесты перестали укладываться в промежуток между 18.00 прошлого дня и 9.00 текущего дня. Мы не получали от тестов обратную связь, возникали простои в работе. Бывало еще, что свет выключат или сервер перезагрузится, тогда потери времени были слишком большие.
Зелеными тесты не были никогда. Правда один раз были, 30 декабря они запустились и выдали результат как 100% зеленые. Наверное это был их подарок нам на Новый год. Больше такого за всё время не было.
Почему они не были зелеными? Для этого было несколько причин:
Из-за нестабильности тестов и того, что мы не успевали актуализировать их, нам пришлось:
У нас была цель — увидеть зеленые интеграционные тесты и, не боясь багов, залить на боевой сервер. Фактически мы этой цели так и не достигли.
Как итог, первый же запуск системы в реальных условиях показал, что автотесты пропускают множество багов. Эти баги мы нашли, когда вручную потыкали систему. За 10 минут ручного тестирования были обнаружены самые критичные баги.
Я волевым решение отменил работу по всем интеграционным тестам и ввел ручное тестирование с написание тестовых сценариев в Google Docs. После этого мы добили основные баги и тестирование отлично встроилось в Kanban поток.
В данный момент в моей компании мы с командой тестировщиков придерживаемся подхода: ручное тестирование + написание тестовых сценариев в Google Docs. Тестировщики вручную протыкивают все сценарии перед заливкой.
Тестовые сценарии считаются частью артефактов проекта и отдаются заказчику вместе с исходным кодом.
По факту это дает отличные результаты. В релизах у нас только минорные баги, либо баги, которые на самом деле фичи.
Надо понимать границы применимости подхода к автоматизации тестирования. Например, если вы пишите жука, который отлавливает ошибки 404 и 500 на живом сервере, то трудозатраты оправданы.
Если у вас несложное приложение, которое иногда меняется, то есть смысл сделать для него набор интеграционных тестов, но совместить это с ручным тестированием.
Если вы хотите заменить ручное тестирование автоматическим на 100%, то подумайте, как избежать проблем описанных выше. Возможно нам надо было сначала использовать ручное тестирование, а потом, автоматизировать те части, автоматизация которых даст максимальный эффект без необходимости поддерживать эти тесты.
Буду рад услышать, как развивалось тестирование в вашей компании.
Ссылки
Top Five (Wrong) Reasons You Don't Have Testers, Joel Spolsky
The Joel Test: 12 Steps to Better Code, Joel Spolsky
Обезьянки против роботов. Часть I (TestLabs09), Максим Дорофеев
Обезьянки против роботов. Часть II (TestLabs09), Максим Дорофеев
Обезьянки против роботов. Часть III (TestLabs09), Максим Дорофеев
Организация работы команды в Agile: разработка + тестирование
Я думаю стоит сразу упомянуть, что на всех этапах мы использовали:
- Модульные тесты с покрытием около 50%
- Continuous Integration с запуском модульных тестов (в последствии и интеграционных), автоматической сборкой и выпуском релиза
- Пересечение из гибких методологий под общим названием ScrumbanXP
Везде, где я буду говорить про автоматизацию тестирования, речь будет идти про тестирование интерфейса с подключением к внешним ресурсам (БД, файловая система, сервисы и т.п.).
Шаг 1. Тестировщиков нет
На первом крупном проекте, в котором я участвовал, не было тестировщиков. Разработчики перед заливкой на боевой сервер сами проверяли основные части системы. При таком подходе частенько вылезали баги.
Для всех было очевидно, что программисты любят свой код и без особого энтузиазма подходят к тестированию только что написанной фичи. Про тестирование ранее написанных фич, да еще и другими разработчиками, вообще говорить не приходится. Программисты сами не станут заново прогонять всевозможные сценарии работы с системой и заходить во все вкладки всех страниц.
На самом деле на этом проекте мы могли себе позволить подобный подход. Наши пользователи сидели в зоне досягаемости. Это был проект по внутренней автоматизации компании. Операторы и менеджеры, которые работали с Системой, могли подойти к нам и обсудить функциональность, указать на ошибки. Соответственно мы могли сделать быстрый фикс и залить исправленную версию.
Отчеты об ошибках сводились к крикам за стенкой. Потери при багах были незначительные, ситуация всех устраивала.
Судя по опросу, который я проводил Как у вас устроен процесс тестирования? большинство может позволить себе именно такой подход к тестированию.
Шаг 2. Начало автоматизации тестирования
Мы начинали делать новую систему, которой должны были пользоваться не только люди за стенкой, но и сторонние пользователи. Появилась необходимость нанять тестировщика, который бы уберегал нас от плохих релизов.
Я нанял тестировщика и для начала мы решили, что тестирование должно быть автоматизированным, как запуск модульных тестов. Автоматизация должна была избавить тестировщика, от постоянного повторения одних и тех же сценариев.
Идея была проста и для всех казалась решением проблем. Мы хотели, чтобы CI запускала ночью набор интеграционных тестов. Утром мы приходим, если тесты все зеленые, то значит можно делать релиз. Если есть красные тесты, значит исправляем, снова запускаем весь набор тестов и т.д. пока все тесты не станут зелеными.
Для записи тестов попробовали разные варианты, остановились на Selenium. Сначала тесты писали на API самого Selenium. Со временем начала создаваться обертка над низкоуровневым API и эта обертка превращалась в некий DSL для тестирования.
Пока тестировщик разбирался с продуктами для тестирования и налаживал процесс автоматизации тестов разработка не останавливалась. Мы должны были выпускать новые версии после каждой 1-2 итераций. Тестировщик постоянно находился в стадии погони за программистами. Его цель была 100% покрытием сценариев, чтобы мы могли спокойно выпускать новые версии не боясь багов.
Шаг 3. Борьба за зеленые тесты
Проблемы с автоматизацией тестирования оказались для нас неожиданными. Фактически мы не были к ним готовы.
Долгая обратная связь
Чем больше была система, тем больше мы писали тестов. Тесты начали работать реально медленно. Если они проходили за 14 часов — это была невероятная удача. Со временем тесты перестали укладываться в промежуток между 18.00 прошлого дня и 9.00 текущего дня. Мы не получали от тестов обратную связь, возникали простои в работе. Бывало еще, что свет выключат или сервер перезагрузится, тогда потери времени были слишком большие.
Зеленые тесты? Нет, не видел
Зелеными тесты не были никогда. Правда один раз были, 30 декабря они запустились и выдали результат как 100% зеленые. Наверное это был их подарок нам на Новый год. Больше такого за всё время не было.
Почему они не были зелеными? Для этого было несколько причин:
- Хрупкие тесты — интерфейс постоянно менялся и тесты не успевали за этими изменениями.
- Негибкие тесты — архитектура системы постоянно совершенствуется, находятся обобщающие решения для гибкости кода. Код тестов (описание) тоже надо рефакторить и обобщать, чтобы их было легче поддерживать. Например, у нас должно появиться много типовых workflow с незначительными изменениями. Разработчики
придумывают архитектуру, которая будет достаточно гибкой, чтобы позволять
быстро реализовывать эти workflow. Соответственно, архитектура тестов должна
совершенствоваться аналогично и «успевать» за совершенствованием архитектуры
кода, чего сделано не было из-за недостаточной квалификации тестировщика. Из-
за того, что архитектура тестов «не успевает» за архитектурой кода, программисты
реализуют фичи всё быстрее и отставание тестировщика накапливается - Минорные баги — тесты не всегда находили критические баги, иногда они падали из-за незначительных багов-недочетов, о которых мы знали, но исправлять их было не приоритетно. Для этого даже специально сделали плагин для TeamCity и можно было смотреть должен тест упасть или нет. Набор падающих тестов с минорными багами не давал тестам быть зелеными.
- Нечитаемые тесты – например, у нас есть сложный сценарий с большим
количеством действий, результат которого нужно протестировать. Соответственно,
тест нельзя разбить на несколько мелких (проверяется не промежуточный результат,
а конечный, который достигается в результате нескольких действий). Код такого теста
нужно оптимизировать так, чтобы он оставался понятным и читаемым, чего также не
удалось добиться. - Длинные сценарии — чтобы реализовать длинные сценарии нам надо сделать, например, 10-20 шагов. Промежуточный результат не важен, важен только конечный. С длинными сценариями возникает ряд проблем:
- Если на 2-м шаге произошла ошибка, то ошибочным считается весь сценарий. В этом случае красный тест говорит не об ошибке в том, что он тестировал, а в ошибке шага, который был где-то в начале (могли поменять интерфейс Входа в систему).
- В длинных сценариях шаги часто повторяются, возникает дублирование.
- Длинный сценарий нельзя начать с середины, потому что для этого придется готовить специальное состояние системы, в котором она должна быть к N-му шагу. Это вносит дополнительную хрупкость в структуру тестов.
Из-за нестабильности тестов и того, что мы не успевали актуализировать их, нам пришлось:
- Переключить разработчика, чтобы он помог тестировщикам перейти на SpecFlow, иначе тестировщики не удерживали объем тестов на C# коде. Руководитель отдела тестирования на тот момент делала доклад на тему Приемочные тесты на огурце
- 70% времени тестировщики переписывали автоматические тесты, чтобы они соответствовали текущему набору функций системы. Т.е. это была работа ради самих тестов.
- Как следствие из вышесказанного — мы наняли еще тестировщиков.
Достигнута ли цель?
У нас была цель — увидеть зеленые интеграционные тесты и, не боясь багов, залить на боевой сервер. Фактически мы этой цели так и не достигли.
Как итог, первый же запуск системы в реальных условиях показал, что автотесты пропускают множество багов. Эти баги мы нашли, когда вручную потыкали систему. За 10 минут ручного тестирования были обнаружены самые критичные баги.
Я волевым решение отменил работу по всем интеграционным тестам и ввел ручное тестирование с написание тестовых сценариев в Google Docs. После этого мы добили основные баги и тестирование отлично встроилось в Kanban поток.
Текущее состояние
В данный момент в моей компании мы с командой тестировщиков придерживаемся подхода: ручное тестирование + написание тестовых сценариев в Google Docs. Тестировщики вручную протыкивают все сценарии перед заливкой.
Тестовые сценарии считаются частью артефактов проекта и отдаются заказчику вместе с исходным кодом.
По факту это дает отличные результаты. В релизах у нас только минорные баги, либо баги, которые на самом деле фичи.
Против автоматизации тестирования?
Надо понимать границы применимости подхода к автоматизации тестирования. Например, если вы пишите жука, который отлавливает ошибки 404 и 500 на живом сервере, то трудозатраты оправданы.
Если у вас несложное приложение, которое иногда меняется, то есть смысл сделать для него набор интеграционных тестов, но совместить это с ручным тестированием.
Если вы хотите заменить ручное тестирование автоматическим на 100%, то подумайте, как избежать проблем описанных выше. Возможно нам надо было сначала использовать ручное тестирование, а потом, автоматизировать те части, автоматизация которых даст максимальный эффект без необходимости поддерживать эти тесты.
Буду рад услышать, как развивалось тестирование в вашей компании.
Ссылки
Top Five (Wrong) Reasons You Don't Have Testers, Joel Spolsky
The Joel Test: 12 Steps to Better Code, Joel Spolsky
Обезьянки против роботов. Часть I (TestLabs09), Максим Дорофеев
Обезьянки против роботов. Часть II (TestLabs09), Максим Дорофеев
Обезьянки против роботов. Часть III (TestLabs09), Максим Дорофеев
Организация работы команды в Agile: разработка + тестирование