Добрый день
Спасибо за выполненную работу :)
Как проверяем:
- выгружаем проект
- ставим зависимости
npm i
- запускаем тесты
- проект стартует?
- тесты проходят (не падают по ошибкам кода)?
- находят баги (если что-то поменялось)?
- понятный ли отчет (allure)?
- смотрим код
- понятна ли структура проекта
- соблюдается ли подход ООП
- чистота кода (субъективно, но есть правила)
- читаем readme
Обратите внимание, что, с нуля, проект не стартует, к сожалению. Можно проверить на другом комьюере или в изолированном окружении (https://pypi.org/project/nodeenv/)
Как получил:
git clone
npm i
npm run test
- тут, кстати, спасибо, что заполинили секцию scripts - сразу понятно, что можно/требуется делать в проекте.
Ожидал, что побегут тесты Получил сообщение на каждый тест:
╔═════════════════════════════════════════════════════════════════════════╗
║ Looks like Playwright Test or Playwright was just installed or updated. ║
║ Please run the following command to download new browsers: ║
║ ║
║ npx playwright install ║
║ ║
║ <3 Playwright Team ║
╚═════════════════════════════════════════════════════════════════════════╝
Выполнив команду npx playwright install
, запустил тесты снова. Каждый тест упал но уже с новой ошибкой.
Error: locator.fill: value: expected string, got undefined
at ../pages/login.page.js:18
16 | await test.step(`Login with '${login}' email & '${password}' password`, async () => {
17 | await this.page.waitForTimeout(500);
> 18 | await this.loginField.fill(login);
| ^
19 | await this.page.waitForTimeout(500);
20 | await this.passwordField.fill(password);
21 | await this.page.waitForTimeout(500);
Тут круто, что не стали хранить в коде логин и пароль. Мало ли какие у нас там данные. С другой стороны, новому коллеге на вашем проекте не запустить тесты без вашего участия.
Потребовалось время, чтобы понять, чего не хватает (логина и пароля). Тут, как вариант, или прописывать дефолт-значения, или выводить сообщение, мол, товарищ, логин-пароль не задан, че ты хочешь?
Даже, раскопав, что нужно определить process.env.PASSWORD
и process.env.LOGIN
, коллега не поймет, какие значения нужно подставить.
Что предлагаю.
Прежде всего, давайте документировать все, что нужно сделать, чтобы получить работающие тесты. Для этого у вас есть файли readme.md. Можно прям в нем описать, что требуется создать файл с настройками по такому-то шаблону (такие-то настройки). Или, наприер, запуск тестов осуществляется командой LOGIN=test PASSWORD=123 npm run test
Запустил 4 теста (только в chromium) 3 прошли, один упал с ошибкой
Expected string: "500000.00 ₽"
Received string: "498800.00 ₽"
Тут ок, мы уже разобрались в чате, что ценник плавает от курса доллара - в рамках итоговой работы, допускаем такие падения. Кстати, как будем стабилизировать такой тест в реальном проекте?
- Круто, что документируете шаги для отчета в аллюре. При этом, некоторые ключевые шаги сценария будто бы не описаны. От этого складывается ощущения магии посреди теста. Вот, например, репорт по 2му тесту. Обратите внимание на подшаг 2. Что он делает? Можно вычитать, что кликает, но на что? Хорошо, что остальные шаги вы подписываете. Передлагаю этот степ тоже описать, чтобы ручникам было проще воспроизвести.
Click on "Hide TableTop" button 3 sub-steps 35ms
Check 'Show TableTop' title is not visible 6ms
locator.getByTestId('hide-countertop').locator('img').click 23ms
Check 'Show TableTop' title is visible
- Продолжайте практиковать локаторы :) Я согласен, что проект отличается от упражнений на уроке – далеко не все элементы имеют хорошие локаторы. Справедливости ради, большинство проектов будет ближе к этой реализации. А значит, проект готовит нас к реальной жизни. Здорово, что вы добились стабильности в локаторах - за все прогоны не упал ни один тест по причине не найденного элемента. 1й критерий вы выполняете. Давайте качать 2й критерий читаемость :)
Что бросается в глаза
Локатор page.locator('[data-testid="order-list"] > ul > li:nth-child(1)').nth(2);
сбивает с толку, потому что и в самом css-селекторе есть ссылка на дочерний элемент, так еще и потом, средствами playwright вы обращаетесь к дочернему. Если я скопирую локатор в браузер, то он будет отличаться от того, который, в итоге, использует PW (в браузере не будет .nth(2)). Напомню, что у локтора в pw есть методы, которые позволяют искать внутри заланного элемента. Проще говоря, вам может подойти вариант page.locator('').locator('').locator('')...
. Или наоборот, всю логику положить в css-селектор.
Второй совет по локаторам – пробуйте отступать выше по дереву от искомого элемента. Сравните 2 локатора:
this.userName = page.locator('[class^="style_workerInfo__"]').first();
и
this.userName = page.locator('#root h2').first();
Оба локатора находят один и тот же жлемент. Второй выглядит короче и надежнее (завязываемся на id) потому что мы привязались не к div'у, содержащему текст, а к элементу чуть выше в дереве.
Здесь, к сожалению, не дам универсального совета - практикуйтесь :)
-
Попробуйте TS. Понимаю, что на маленьком проекте не ощутить всего удобства, но проекты быстро растут. Не успеешь оглянуться, а он уже большой
и курит за школой. -
Заметил, что во всех проверках у вас стоит таймаут 20000 – 20 секунд. тут два вопроса: зачем и как не писать в каждой строке? Найдите параметр, который в конфиге задает таймаут на ожидание проверок – легче будет управлять.
-
Предлагаю в readme.md прописать основные команды для пользователя: как поставить зависимости, как запустить тесты, как посмотреть отчет и т.д. Кроме того, если есть какие-то особые настройки проекта (url'ы, логин/пароли, константы какие-то), желательно тоже описать в файле, какие есть настройки и где их указывать.
-
Все, что выражается в коде константами, нужно подвергать сомнению. Это не значит, что в коде не должно быть констант (чисел или конкретных строк). Просто мы должны каждый раз себя спрашивать "а точно ли это значение мне не придется переписывать завтра?")
Мы не знаем, будет ли в каталоге завтра такой цвет. Точно ли цена будет 50000 (уже знаем, что нет). Проточки для стока воды – можем перестать их делать. Все это - какие-то бизнесовые вопросы, которые никак не влияют на функциональность сайта. А значит, не должны и влиять на тесты.
const color = 'N-103 Gray Onix';
const option = 'Проточки для стока воды';
const total = '500000.00 ₽';
Предлагаю вынести тестовые данные во внешний json. Тут два плюса:
- вам легче объяснить ручникам, что и где нужно менять, чтобы поменять тестовые данные (меняй вот в этом json'е все, остальной код не трогай!)
- у вас есть возможность формировать этот файлик программно. Например, перед тестами, вы шлете селект в базу и смотрите, какие цвета сейчас доступны. Берете первый попавшийся - это и будет ваш
color
. Или, раз мы поняли, что цена привязана к курсу доллара, значит, есть какое-то API, которое отдает текущий курс... Давайте запросим и посчитаем, какая должна быть цена.
- Респект за проработку GitHub Actions и публикацию отчета в частности :)
Хорошая работа, видно, что сделана вдумчиво, с поиском наиболее подходящих решений. Еще раз спасибо.
Общая рекомендация – держать в голове мысль, что все переменчиво в нашем мире. В том числе, тестовое окружение и тестовые данные. А потому, важно продумывать механизм, как удобно и быстро менять эти данные в вашем проекте, не переписывая классы с логикой.
Кроме того, помните, что код, который вы писали и отложили на месяц – это уже код другого человека. Вам нужно будет снова вникать, что здесь происходит, как это все настроить, запустить и поправить.
Оставляйте себе подсказки в виде документации – используйте readme.md
Если подготовите ответы на заданные вопросы, готовы будем продолжить ветку беседы по ним. На этот раз, сильно быстрее :)