Проблема
«Иногда автоматизация остается относительно легкой, так как для автоматизации существует очень мало сценариев. На этом этапе создается лишь небольшое количество сценариев для позитивных и негативных путей (positive and negative path scenarios), чтобы быстро получить уверенность в регрессии.
В какой-то момент команда может осознать, что необходимо добавить все больше и больше сценариев для обеспечения функциональности приложения. Именно тогда команде приходится адаптировать скрипты тестовой автоматизации, чтобы они охватывали эти новые сценарии, а также убедиться, что их легко и интуитивно обновлять.
Существует также определенный порог, при котором набор тестов следует обновить для использования паттерна Page Object Model, поскольку в противном случае тесты станет очень трудно поддерживать.
Чем раньше будет принято это решение, тем лучше, поскольку рефакторинг или обновление тестов может занять очень много времени. Другая проблема — необходимость успевать за важными фичами, которые, возможно, требуют срочного тестирования. Это может превратиться в кошмар.
В нашем случае с оценщиком TCSE необходимо было провести рефакторинг семнадцати сквозных сценариев (e2e). Наш первый важный шаг заключался в преобразовании их с синтаксиса Python на Node.js. Это решение имело смысл, поскольку само приложение использовало то же окружение, а это означало, что, когда мы, в итоге, настроим GitHub Actions, нам потребуется настроить только то единственное окружение. Вторым важным шагом был рефакторинг существующих тестов в паттерн Page Object Model. Мы так решили, поскольку видели много существующих областей для автоматизации, а также фичи, которые будут добавлены в будущем.
Решение
Вот тут-то на помощь пришел GitHub Copilot. После создания различных методов и свойств в объектах страниц остальная часть работы обычно представляет собой рутинное копирование и вставку в наших семнадцати e2e-файлах.
Используя Copilot в IDE, такой как VSCode, тестировщики могут значительно сократить время, необходимое для выполнения трудоемких задач рефакторинга.
Вы можете спросить, что такого особенного в Copilot, если я могу добиться того же результата с помощью онлайн-чатбота, типа Claude или ChatGPT? Разница в том, что Copilot теперь будет интегрирован с вашей кодовой базой, что даст ему очень высокий уровень контекста проекта. Онлайн-чат-боты часто не справляются, поскольку они могут не предоставить вам то что нужно, если вы не вставили другие связанные файлы или фрагменты кода. Copilot, интегрированный с VSCode, сэкономит вам много времени, поскольку у него будет хороший контекст проекта. Это означает, что вы, скорее всего, придете к решению гораздо быстрее, не прибегая к повторному вводу промпта или добавлению большего количества фрагментов/файлов в онлайн-чатбот.
Сужение контекста
Если преобразование простое, мы можем применить его сразу к нескольким файлам. Мы можем переключить боковую панель чата и добавить файлы/папки в качестве контекста. Иногда нам заранее не известен весь контекст проекта для выполнения определенных задач. В идеале мы должны использовать меньше ресурсов (токенов), и именно здесь пригодится опция «добавить контекст». Мы можем ввести такой промпт: «Примени этот новый объект страницы к соответствующим e2e-файлам». По умолчанию файлы, которые у нас открыты, будут включены в контекст.
На практике шаги таковы:
- Найти релевантные файлы для редактирования.
- Найти релевантные строки для редактирования.
- Провести рефакторинг строк с помощью соответствующих методов или свойств из нашего класса Page Object.
Если мы вместо этого укажем на наши релевантные файлы/папки тестов и объектов страниц, мы можем вручную уменьшить область (scope). Это означает, что вероятность ошибок становится намного ниже. Допустим, теперь мы знаем точные файлы, которые хотим подвергнуть рефакторингу:


Теперь мы значительно сократили область этого рефакторинга. Стоит отметить, что вы, по сути, обучаете модель тому, как вы хотите провести рефакторинг этих тестов. Сначала она может допускать небольшие ошибки, но, правильным образом сужая контекст или scope, она становится очень хороша в выполнении повторяющихся задач.
Автозавершение
Copilot также имеет функцию автозавершения, которая предсказывает следующие строки кода на основе предыдущих действий. Это просто подарок с небес, когда дело доходит до создания классов, поскольку вы можете избежать еще большего количества копирования и вставки.

Примеры
В этом проекте мы провели рефакторинг двумя способами: преобразование с Python на TypeScript и оптимизация в паттерн Page Object Model.
Преобразование языка
Наш первый промпт прост: мы можем использовать как встроенный чатбот, так и отдельное окно чатбота. Мы можем просто выделить нужное место, а затем вызвать встроенный чатбот с помощью Ctrl+I. Затем ввести простой промпт:

После этого просто наблюдать за волшебством. Все, что нужно сделать, это проверить и принять изменения, если вы ими удовлетворены. Это очень важно, поскольку Copilot не всегда абсолютно точен, он может например иногда неправильно написать что-то или упустить нужное.
Преобразование в Page Object Model
Мы можем начать с промпта для настройки объектов страниц (page objects) и шаблонов фикстур (fixture templates):

Теперь он сгенерирует некоторые базовые объекты страниц и фикстуры в указанном файле и папке. Если мы введем промпт в чатбот, он сгенерирует там код, и тогда нам решать, разрешить ли создание этих файлов в кодовой базе.

Еще одна проблема с существующим тест-свитом заключалась в том, что там было много многократно используемых строк. В основном это были проверки видимости элементов. Мы решили эту проблему, добавив эти файлы в качестве контекста и введя промпт: «Определи повторяющийся код в этих файлах и предложи хелпер-метод». Это существенно сократило размер тестов. Copilot выделил, какие шаги используются чаще всего, что помогло нам позже при создании методов в Page Object Model.
Следующим шагом было разделение TCSE на разделы, поскольку это не многостраничное приложение. Вот общая схема, показывающая, как мы разделили страницу на объекты разделов:

На этом этапе пришлось немного поработать вручную, сопоставляя локаторы в тестах с объектами страниц. Как только у нас есть все свойства и методы в объектах страниц, мы можем добавить файлы объектов страниц и файлы спецификаций e2e в качестве контекста. Промпт был примерно таким: «На основе свойств и методов в этом объекте страницы проведи соответствующий рефакторинг прикрепленных файлов спецификаций e2e».
Теперь он должен увидеть совпадения между e2e и объектами страниц и начать рефакторинг тестов с помощью вновь сокращенных методов.
Пример. В нашем объекте страницы у нас есть:
this.numberOfServers = page.getByLabel('Number of Servers:');
async selectNumberOfServers(text: string) {
await this.numberOfServers.click();
await this.numberOfServers.fill(text);
}
В наших e2e-тестах есть тесты, которые взаимодействуют с этим же элементом:
await page.getByLabel('Number of Servers').click();
await page.getByLabel('Number of Servers').fill('20');
Таким образом, Copilot видит это совпадение в выполняемых действиях, что затем дает нам конечный результат:
await onPremSection.selectNumberOfServers('20');
Заключение
Copilot — очень полезный инструмент для трудоемких задач. Он чрезвычайно эффективен в случае, когда автоматизацию необходимо обновить, а элементы все еще нуждаются в тестировании. Я обнаружил, что он работает очень хорошо, если сузить контекст. Например, рефакторинг одного e2e-теста за раз.
Изначально я пытался провести рефакторинг всех 17 тестов сразу и заметил, что ошибок было больше. Также стоит повторить, что он понимает контекст всей кодовой базы, но не обязательно той задачи, которую вы выполняете в данный момент. Поэтому я обнаружил, что, если вы предельно ясно формулируете, что вы хотите получить, он работает намного лучше в целом. Например, не так: «Проведи рефакторинг этих файлов соответствующим образом», а так: «Я извлек свойства и методы в эти объекты страниц, теперь проведи соответствующий рефакторинг прикрепленных файлов спецификаций e2e».
