Релизы мы делали примерно раз в 4 месяца, спринты получались недели по 3 и команда QA из Индии фактически просто прогоняла набор сценариев. Product Owner лично тестировала наше приложение и находила ошибок больше, чем QA. Конечно, при таком качестве исходного кода ошибки были постоянно и мы их упорно исправляли. И ещё production incidents уж как минимум раз в неделю. Потом релиз отправляли на пользовательское тестирование и оттуда нам прилетал список багов обязательных к исправлению перед релизом, список багов для исправления сразу после релиза и просто список багов, которые хорошо бы починить. Конечно, перерабатывали мы во все тяжкие и в итоге получалось включить в релиз фич 5-7, может быть 10, если считать небольшие. Разумеется, всё это сопровождалось войнами приоритетов и трудными управленческими решениями.
Внезапно у нас появилась возможность (вернее, бизнес-требование) переписать наиболее критичный PL/SQL на Java. Иногда, в процессе миграции, я сталкивался с кодом, который делает какую-то полную ахинею. И Product Owner подтверждала, что эта функциональность работает чёрт знает как и вместо переписывания мы делали какую-то простую реализацию на Java с чистого листа. После этого жизнь стала стремительно налаживаться. Кода стала меньше, код стал понятней, мы стали активно его рефакторить и у нас исчезли трудности с дебагом.
Миграция с PL/SQL на Java позволила нам нанести много пользы проекту, из глобального: обильно добавили логи, применили принципиально новый подход к реализации ключевой бизнес-логики, по коду сделали в wiki описание переходов между возможными состояниями транзакции и стали поддерживать его в актуальном состоянии. После этого количество production incidents резко упало, те, что случались, стали расследоваться в течение получаса, QA перестал находить баги, а пользовательское тестирование перестало выявлять фатальные проблемы.
И в этот момент тестирование перевели из Индии к нам в Питер и мы набрали профессиональных тестировщиков, которые стали писать автоматические тесты на Selenium. Примерно через год мы получили практически полное покрытие системы автоматическими интеграционными тестами. Теперь мы делаем за релиз десятки фич, у нас нет никаких авралов, а пользовательское тестирование проходит как по маслу. И разработчики постоянно ломают тесты, потому что система очень сложная и небольшие изменения запросто могут аукнуться в самом неожиданном месте для каких-то специфических транзакций.
В дальнейшем мы планируем настроить continuous integration и ускорить время прохождения тестов, это позволит нам ещё раньше замечать ошибки, смелее вносить изменения и сократить время между релизами. Можно смело утверждать, что современные программные системы настолько сложны, а программисты способны так быстро вносить изменения, что автоматические тесты обязательны для промышленной разработки. Если перед релизом нужно две недели ручного тестирования и после успешного прохождения 80 процентов тестов нашлась критическая бага, которую разработчики ещё 2 дня исправлять будут, вы релиз ещё на 2 недели отложите?
При этом я не верю в unit-тестирование бизнес-приложений. Например, наша система интегрируется с несколькими сторонними системами (отнюдь не всегда добрыми к пользователям) и я, как разработчик, предпочитаю их не видеть, а наш QA иногда находит в них баги, которые unit-тесты не могли бы обнаружить. Конечно, бывают программисты, которые могут разбить всё на независимые модули и устроить полный DevOps, но вряд ли их заинтересует ваша система на технологиях 5-летней давности. В некоторых проектах QA во многом заменяется A/B-тестированием, но в финансовой сфере такой подход не всегда применим.
Также тестировщики могут очень сильно помочь в уточнении требований. Разработчику гораздо проще прочитать описание задачи в трекере или спросить тестировщика, который сидит в той же комнате, чем организовать ещё один созвон с менеджером. Фактически, тикеты являются документацией к разрабатываемому проекту, причем по строчке кода можно найти коммит, а в описании коммита должна стоять ссылка на тикет, то есть это документация, которую потом читают, в отличие от традиционного подхода. Конечно, хорошие программисты тоже пишут тикеты, но тестировщики делают это гораздо лучше.
Ещё нужно отметить, что времена, когда разработчик мог знать все тонкости системы давным-давно прошли, современные решения настолько сложны, что один человек обычно физически не в состоянии держать в голове все её тонкости. К тому же программисты регулярно меняют работу и тестировщики помогают сохранить накопленный опыт. Более того, тестировщики могут заниматься поддержкой пользователей, а если менеджер уходит на повышение, то иногда ему можно найти замену среди тестировщиков.
Прошу считать этот пост словами благодарности тестировщикам за их работу.