«Сюда не лезь», «Это не трогай», «Это для тебя слишком сложно», «А это ты, может, и поймешь, но нескоро». Звучит, как слова суровых родителей, пытающихся оградить своего ребенка от всего нового, непонятного и, не дай бог, интересного. И знаете что? К сожалению, многие переносят такой подход в свою работу.
Тогда ничего, что выходит за пределы рабочих инструкций, не то, что не хочется, а вообще нельзя делать.
Учиться новому становится страшно и кажется, что коллеги могут осудить за проактивность, но точно не поощрить или одобрительно оценить ваши старания.
Лично я никогда не разделял такой подход. Будучи ментором, в работе со своими подопечными я всегда стараюсь сделать так, чтобы все было возможно, интересно и открыто для изучения. В этой статье я попробую на примере отдельно взятой практики объяснить, что изучать новое — это полезно, а расширять свой круг ответственности по собственной инициативе — совсем не страшно.
Перейдем от лирики к конкретным понятиям. Инженерный подход к тестированию может изменить умение читать код. Возможно, прозвучит банально, но QA-инженеры часто забывают об этом.
На лекции в рамках NIX MultiСonf я упоминал о преимуществах ситуации, когда QA не только умеет писать тестовый код, но и не стесняется самостоятельно изучать код, который пишут разработчики. Обычно это возможно, когда команда разработки использует для своих активностей тот же язык программирования, что и тестировщики для автоматизации.
Зачем это нужно и какую пользу можно извлечь из инженерного подхода?
- QA-инженер начинает лучше понимать программу, которую тестирует
Написанные тест-кейсы и тесты становятся более рациональными за счет того, что вы лучше понимаете, как работает приложение, и то, как его тестировать.
- В случае нечетко написанных требований тестирование не блокируется
Если функционал, который нужно протестировать, недостаточно покрыт требованиями (что само по себе, конечно, проблема, которую нужно решать отдельно), то QA-инженер все равно поймет, как работает новая фича, посмотрев на ее реализацию в коде.
- Баги получают более подробное и более глубокое описание
Обнаружив проблему в приложении, QA может не только описать шаги с точки зрения пользователя, но и глубже проанализировать их, изучив код, касающийся «проблемной» фичи. С найденной информацией вы сможете вести более информативный баг-репорт. Прочитав такой документ, разработчик скорее всего сможет все пофиксить. А это уже сэкономит значительную часть времени, которую девелопер мог потратить на инвестигейт проблемы.
- Код автоматизаторов становится более качественным за счет начитанности
Чтение хороших книг помогает хорошо формулировать мысли. Слежка за модными тенденциями улучшает умение одеваться со вкусом. По аналогии — чтение хорошо написанного кода позволяет писать более чистый, понятный и правильный код самостоятельно. Соответственно, чем чаще автоматизатор читает код разработчиков, тем больше он черпает полезных практик и подходов для своей повседневной работы.
Следует подчеркнуть, что при всех плюсах этого подхода я бы не советовал условному QA manual изучать программирование исключительно для того, чтобы читать девелоперский код. Этот скилл больше касается тех, кто и так использует программирование в решении своих задач. Например, тех же QA Automation и иногда General QA.
С чего начать чтение кода
Еще на старте разработки рекомендую озвучить в команде важный момент: код по умолчанию будет общим.
Не должно существовать барьеров, из-за которых разработчик никогда не захочет читать автотесты, а тестировщик — исходный код программы.
Инициативу предлагаю взять на себя именно тестировщику.
Для начала узнаем, на каком фреймворке планируют писать приложение. Об этом расскажет любой из разработчиков. Также можно обратиться к документации на условном Confluence. В зависимости от типа программы (с/без GUI, десктоп/мобайл/веб и т.д.) фреймворков может быть несколько.
Далее нужно погрузиться на несколько дней в гугл и изучить то, что будет интересовать нас в дальнейшей работе:
- какая структура выбранного фреймворка;
- как выглядят типичные конструкции.
После ресерча можете попробовать сделать простенький пример, чтобы лучше понять происходящее. Когда начнется активная разработка фич, при наличии свободного времени посмотрите код пул-реквестов, который будут выкладывать девелоперы, и попытайтесь понять все, что там написано.
Очень скоро окажется, что все типовые конструкции, которые мы изучили накануне, будут хорошо выделяться на фоне всего написанного кода. Теперь в коде, скажем, микросервиса вы сможете легко найти, например, список доступных эндпоинтов или полей, которые нужно или наоборот не нужно отправлять на каждый из них, чтобы он отработал. Самое время применить эти знания в процессе тестирования!
А теперь обо всем этом — на примерах
Предположим, что для бэкенда нашего приложения разработчики используют популярный фреймворк SpringBoot. Погуглив узнаем, что стандартная структура проекта на этом фреймворке выглядит примерно так:
корневойПакет +- ещеПакет +- названиеПриложения +- ГлавныйКласс.java | +- пакетСущности1 | +- Сущность1.java | +- Сущность1Controller.java | +- Сущность1Service.java | +- Сущность1Repository.java | +- Сущность1Model.java | +- пакетСущности2 +- Сущность2.java +- Сущность2Controller.java +- Сущность2Service.java +- Сущность2Repository.java +- Сущность2Model.java
Прекрасно! Теперь мы немного понимаем структуру, но остаются непонятными слова: controller, service, repository и model. Снова обращаемся к гуглу и выясняем, что:
- Controller — это класс, обрабатывающий получаемые запросы и переправляющий их «вглубь» программы, своего рода входная точка;
- Model — описание структуры сущностей, с которыми готово работать приложение;
- Service — это класс, в котором описывается бизнес-логика конкретной сущности;
- Repository — код, взаимодействующий с базой данных.
Все еще ничего непонятно? А если вот так:
- Controller — это то, как мы обращаемся к приложению;
- Model — показывает, какие данные от нас ожидаются во время обращения;
- Service — то, что приложение будет делать, когда мы успешно обратились к нему;
- Repository — место, где будут храниться обработанные данные.
Да, кажется, уже проще. Теперь дело за малым — использовать все это на практике.
Нет документации для доступных в микросервисе эндпоинтов? Не беда, просто идем смотреть контроллеры. Находим список всех доступных эндпоинтов для каждой сущности:
@RestController @RequestMapping("/api/subject") @RequiredArgsConstructor @Slf4j public class SubjectController { private final CommandDispatcher commandDispatcher; @PostMapping("") public ResponseEntity<CommandResult<String>> create(@RequestBody @Valid CreateSubjectCommand command) { … } @PutMapping("/{id}") public ResponseEntity<CommandResult<String>> update(@PathVariable String id, @RequestBody @Valid UpdateSubjectCommand command) { … } @PutMapping("/{id}/rate") public ResponseEntity<CommandResult<String>> rate(@PathVariable String id, @RequestBody @Valid RateSubjectCommand command) { … }
Нужно узнать структуру объекта, который мы туда будем передавать? Идем в код модели этого объекта и видим список всех полей:
@Data @Builder @Document(collection = "subjectStore") public class SubjectModel { @Id private final String id; private final Date timeStamp; private final String aggregateIdentifier; private final String aggregateName; private final int version; private final String subjectName; private final BaseSubject subjectData; }
Приведенный выше код понадобился нам для примера. В реальном же проекте код вашего приложения может оказаться не столь тривиальным. Но если наблюдать за его развитием в динамике, проблем возникнуть не должно.
Кстати, есть приятный бонус для вас. Современная разработка производится с использованием относительно небольшого количества архитектур. Достаточно большое количество фреймворков на разных языках имеют схожую структуру именно потому, что они имплементируют одну и ту же архитектуру. То есть один раз изучаете ее, а затем рассматриваете в коде приложения.
Приведу еще один пример в пользу самостоятельного изучения кода. Представим, что вы как QA не можете продолжить тестирование продукта, потому что часть функционала не работает. Например, указанный в требованиях параметр REST endpoint на бэкенде недоступен. Что в таком случае может сделать тестировщик?
Попробует разные варианты этого параметра. Если успехов нет, обратится за помощью к разработчику, и они вместе попытаются решить проблему. Казалось бы, очевидный и простой способ, но у него есть недостатки:
- Разработчику придется потратить время на то, чтобы объяснить тестировщику суть проблемы.
- Тестировщик становится «зависимым» от разработчика и не может сам справиться с задачей.
- Общение с девелопером может замылить глаз неопытному тестировщику. В результате фактически разработанный функционал он будет считать эталонным. На его основе и будет разрабатываться стратегия тестирования (возможно при условии нечетко прописанных требований).
Я советовал бы поступать иначе. Если во время тестирования вы заметили ошибку, найдите подходящий тикет, например, в Jira, с указанным там автором тестируемой фичи. Там вы найдете Pull Request — набор изменений в кодовую базу в пределах этого таска. Вы увидите, какие изменения и в какую строку кода вносил каждый из участников команды. Имея больше контекста, вам будет проще понять, почему система указала на неправильный параметр на бэкенде.
Плюсы для тестировщика очевидны:
- у специалиста формируется насмотренность за счет анализа кода;
- вместо совместного поиска ошибок вы экономите время коллег и свое личное;
- в будущем сможете подобрать разные варианты тестирования для каждой новой функциональности.
На мой взгляд, описанная практика потенциально повысит качество тестирования и поможет стать самостоятельнее. Не ограничивайте себя монотонными задачами, разрушайте стереотипы о работе QA. Всегда старайтесь глубже разобраться в предметной отрасли. И тогда качество тестируемых продуктов вырастет в разы.
Читайте также: «Главное — понять основы, дальше будет легче»: сколько языков программирования нужно знать тестировщику
Этот материал – не редакционный, это – личное мнение его автора. Редакция может не разделять это мнение.
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: