Матерый enterprise проект с "зоопарком" из разнообразных технологий. Часто меняющаяся команда и требовательный заказчик. Менеджер, активно пытающийся вытянуть проект... Все составляющие для сюжета, достойного Титаника.
Было перепробовано множество практик для улучшения процесса разработки, и больше всего это влияло на нас, разработчиков. В одночасье рушились привычные устои, а новые, не успев прижиться, менялись снова. Разве возможна нормальная работа в такой нервной обстановке?
Автор критически оценит парное программирование, тестирование, code review и прочие практики из мира улучшения разработки, а также расшарит набитые шишки и обнаруженные грабли.
3. Зачем этот доклад?
Будут:
+ Решения фундаментальных проблем
разработки
+ Примеры из реальной работы большой
команды (25-30 человек)
Не будет:
- Теоретических выкладок
- Низкоуровневых технических деталей
4. Структура доклада
Context context = me.DescribeContext();
Debug.Assert(context.ProblemCount == 4);
for (int i = 0; i < context.ProblemCount; ++i)
{
if (i == 2)
me.ShowVideo();
Problem problem = context.Problems[i];
me.Analyze(problem);
}
me.Summarize();
5. Обзор проекта
Продолжительность 4+ года (c мая 2008)
Технологии Java, JS, Groovy, Flex,
C#, C++, PHP, ...
Средний размер 20-25 разработчиков
команды
Всего работало 75 человек
Инструменты Git, JIRA, Bamboo,
Review Board
9. И понеслось...
● Неопытный менеджер
● Резкий рост команды (8+ разработчиков)
● Много разноплановых задач
● Эйфория от работы над новым кодом
10. Разные члены команды пишут много кода в
разных частях системы без должных
проектирования и синхронизации.
В результате:
● Сырой код;
● Проблемы при
интеграции;
● Люди знают только
свой код;
11. Проблема 1: После релиза
обнаруживаются критичные баги
Почему?
● Мало времени на написание кода
● Невнимательно тестировали код
● Низкий уровень знания разработчиков
● Не учли реальные условия
Как не допустить?
12. Тестировать продукт перед релизом
Идея:
Нельзя релизить непротестированный продукт.
Как:
Перед релизом тестируем продукт, фиксим
обнаруженные баги.
13. Пример 1: Продукт тестируют все
разработчики
+ Можно оперативно пофиксить проблему;
+ Хорошо знают систему, при должной
внимательности могут найти много всего.
- Не замечают ошибок в собственном коде;
- Лень фиксить, проще забить;
- Разработчики не любят тестирование и
тестируют поверхностно;
- Можно увлечься локальным фиксом и
забыть про остальное;
14. Пример 2: Продукт тестирует аккуратный
разработчик
+ Другие разработчики не отвлекаются на
тестирование - только фиксят;
+ Хорошо знает систему, при должной
внимательности может найти много всего;
+ “Это не баг, а фича” - не пройдет.
- Тестирование быстро надоедает, особенно
регрессионное;
- Тяжело найти такого разработчика.
15. Пример 3: Продукт тестируют
тестировщики
+ Не дергаем разработчиков;
+ Полная объективность;
+ Профессионально занимаются этим;
+ Взгляд со стороны на систему.
- Ниже уровень технических знаний;
- Разработчики отрицают баги - “так и
должно быть”;
- Первое время часто репортят ерунду.
16. Проект сейчас
Команда из 7 тестировщиков в Омске
Релизная ветка фиксируется за 2 недели
2 раунда регрессионного тестирования
Sanity тестирование сразу после релиза
50 тестовых серверов
Тестовые скрипты в TestLink
17. Резюме
После релиза обнаруживаются критичные баги
Тестировщики - лакмусовая бумажка
качества разработки.
Иногда привлекайте разработчиков к
тестированию.
Разработчики должны помогать
тестировщикам.
18. Проблема 2: После релиза ломается
старый функционал
Почему?
● Невнимательно тестировали свой код
● Низкий уровень знаний разработчиков
(код, система, язык)
● Невозможно все учесть
Как не допустить?
19. Автоматические тесты
Идея:
Покрывать код автоматическими тестами.
Перед релизом все тесты должны
проходить.
Как:
Пишем модульные и интеграционные тесты
для новых фич и багов.
20. Пример 1: Выделенный разработчик
пишет интеграционные тесты после
завершения задачи
+ Другие разработчики не отвлекаются на
написание тестов;
+ Взгляд на код со стороны;
- Не успевает за остальными;
- Тесты поверхностные - подгоняются под
функционал, а не наоборот;
- Если обнаруживаются проблемы -
исправление затягивается.
21. Пример 2: Java - все разработчики пишут
интеграционные тесты
+ Позволило проекту дожить до
сегодняшнего дня
- Много интеграционных тестов - проходят
долго;
22. Пример 3: Render Server - покрытие
большой базы существующего кода
Проект:
● зависит от многих сторонних компонентов
● многопоточный и многопроцессный
● требует тонких настроек окружения
Тесты:
+ Уверенность в отсутствии регрессий
+ Упростили отладку
23. Пример 4: Тесты для фронтенда (ExtJS)
+ Защищают от регрессий
- Сложно писать
- Сложно обеспечить глубокое покрытие
- Могут замедлять работу продакшн кода
- Очень чувствительны к окружению
24. Пример 5: Тесты проходят долго
Интеграционные тесты:
● работают долго
● зависят от окружения
Сервер для автоматических тестов
(Bamboo):
+ Продолжаем разработку пока тесты идут
- Дополнительный сервис
- Узкое место - нужен всей команде
25. Проект сейчас
Java 4 плана Bamboo 2175 тестов
Flex 1 план Bamboo 1048 тестов
C++ 3 плана Bamboo 290 тестов
C# 2 плана Bamboo 109 тестов
JS 2 плана Bamboo 60 тестов
Java Doc 1 план Bamboo 1 тест
26. Резюме
После релиза ломается старый функционал
Тесты - ваш проводник в светлое будущее.
Тесты должны писать разработчики.
Интеграционные тесты будут работать
долго.
Покройте UI базовым набором тестов.
28. Проблема 3: Не можем выкатить релиз -
код в репозитории нестабилен
Почему?
● Код не тестируется перед попаданием в
публичный доступ
● Тесты занимают много времени
● Нельзя коммитить локально
Как не допустить?
29. Continuous integration
Идея:
Любые изменения в коде должны тестироваться.
Непротестированному коду запрещено попадать
в публичный доступ.
Как:
В основной ветке - только стабильный код.
Код стабилен, если проходят все тесты и
тестировщики не нашли багов.
30. Пример 1: Тесты перед каждым
коммитом в SVN
- Коммиты становятся “жирными” и долгими
- Тестировщики не участвуют в проверке
кода
31. Пример 2: Каждая задача в отдельной
ветке. С SVN на Git.
+ Легкая работа с ветками
+ Проще рулить конфликты
+ Возможность коммитить локально
- Мигрировать всю историю
- Другая идеология - людей надо учить
- Неудобный клиент под Windows
32. Пример 3: Жесткий workflow
Ограничения:
● Мержить в master может только JIRA.
Jira2Bamboo plugin.
● Мерж возможен только когда пройдут все
тесты и нет конфликтов.
+ Проблема решается железобетонно
- merge plugin не стабилен
- мержить может только один человек - надо
ждать, когда освободится
33. Пример 4: Эволюция merge plugin
Улучшения:
● Баг фиксы
● Поддержка очереди с приоритетом
● E-mail уведомления
+ Отправил в мерж и гуляй
+ Приоритетные задачи мержатся раньше
+ Задачи, где мало тестов, мержатся
раньше
34. Пример 5: Единый QA сервер -> N
тестовых серверов
Сделано:
● JIRA plugin для резервирования сервера
● Скрипт для автоматического билда
заданной ветки на сервере
35. Проект сейчас
До мержа обязательный прогон тестов и
полное ручное тестирование.
Обязательное обучение людей работе с Git
и workflow.
Jira2Bamboo плагин с поддержкой очереди.
Оптимизация работы с Bamboo - не гонять
тесты лишний раз.
36. Резюме
Не можем выкатить релиз - код в репозитории нестабилен
В большом проекте создайте "островок"
стабильного кода.
Используйте DVCS для большой команды
Обучайте людей workflow и работе с DVCS.
Сделайте коммиты, билды, запуск тестов
простыми и быстрыми операциями.
37. Проблема 4: Нужно править незнакомый код
Почему?
● Автор кода недоступен
Следствия:
● Тратится много времени на понимание кода
● Вероятность ошибок возрастает
Как не допустить?
39. Пример 1: Парное программирование
обязательно
+ Качественней код
+ Непрерывная разработка - не нужны
перерывы
+ Люди учатся друг у друга
- Все равно получается медленней
- Надоедает
- Могут отвлекать других болтовней
- Гибкий график может быть проблемой
40. Пример 2: Парное программирование
только для серьезных проблем
+ Взгляд со стороны на проблему
+ Максимально качественное решение
+ Не успевает наскучить
41. Пример 3: Неопытные разработчики
работают в парах
+ Минимизируем негативный эффект в
первое время
+ Вдвоем проще осваивать незнакомую
систему
42. Пример 4: Позадачное code review
+ Любой код знает минимум еще 1 человек
+ Левый код отсеивается сразу
+ Меньше затрат, чем при работе в парах
- Опытный разработчик может скептически
относиться к замечаниям
- Затягивает процесс завершения задачи
- Разработчики ленятся ревьювить чужой
код
44. Проект сейчас
Обязательное ревью перед тестированием.
Review Board, нет интеграции с JIRA.
Новые разработчики начинают ревьювить
код через 1-2 месяца.
Парное программирование только при
необходимости.
45. Резюме
Нужно править незнакомый код
Используйте Code Review непрерывно.
Сделайте процесс Code Review удобным.
Применяйте парное программирование
только в сложных случаях.
46. Итоги
Непродуманные решения превратятся в
серьезные проблемы в будущем.
В большой команде проблемы будут
происходить постоянно.
Решайте проблемы фундаментально, чтобы
избежать повторного появления вовсе.
Готовьте команду к изменениям.
47. Итоги
На большом проекте с самого начала:
● Пишите тесты
● Наймите тестировщиков
● Используйте DVCS
● Следуйте принципам Continuous
Integration
● Внедрите обязательное Code Review
48. Спасибо за внимание!
Виталий Шибаев
vshibaev@issart.com
Skype: shibvit
Компания ИСС Арт
http://issart.com/