Что пишут в блогах

Подписаться

Онлайн-тренинги

Что пишут в блогах (EN)

Разделы портала

Про инструменты

.
Создание рандомного пользователя в Cypress-тесте
29.06.2021 00:00

Автор: Филип Рик (Filip Hric)
Оригинал статьи
Перевод: Ольга Алифанова

Большая часть тестируемых веб-приложений требует той или иной аутентификации. Тестируя такие приложения, я хочу иметь возможность создавать тестового пользователя. Обычно он генерируется случайным образом и затем используется в большинстве моих тестов. В этой статье я расскажу о нескольких способов генерации пользователя, а затем применю его в Cypress-тестах.

Как обычно, я использую приложение-клон Trello в репозитории, в который вы можете заглянуть и следовать за мной предметно. Я старался сделать статью простой, поэтому создание пользователя в моем приложении – это единичный http-запрос. Однако в целом вы должны быть способны применить эти подходы и в вашем приложении.

Использование хука

В файл support/index.js можно добавить хук before() или beforeEach:

./cypress/support/index.js

const { internet } = require('faker');
const email = internet.exampleEmail()
const password = internet.password()
 
beforeEach(() => {
cy
.request('POST', '/signup', { email, password })
.then(({ body }) => {
cy
.setCookie('trello_token', body.accessToken);
});
});

При помощи faker можно сгенерировать рандомные примеры почтовых адресов для каждой спеки или каждого теста. В нашем тесте мы авторизуемся, вставляя куки авторизации в браузер.

Авторизация перед каждым тестом может создать множество данных. С другой стороны, это помогает тестам быть независимыми друг от друга. Обычно это хорошее дело, но создание нового пользователя для каждого теста – это чересчур для большинства из них.

Кстати, синтаксис с фигурными скобками известен как деструктуризация. Это синтаксис JavaScript, и я писал о том, как применять его в Cypress.

Создание скрипта

Раньше я пользовался вот таким подходом. По сути, перед началом прогона своего теста через cypress run я запускал скрипт, создающий пользователя и сохраняющий его в файл. Затем этот файл применялся в тесте для авторизации пользователя.

signup.js

const axios = require('axios')
const { internet } = require('faker');
const email = internet.exampleEmail()
const password = internet.password()
const fs = require('fs')
 
const signupUser = async () => {
 
const user = await axios
.post('http://localhost:3000/signup', { email, password })
 
fs.writeFileSync("./cypress/data.json", JSON.stringify(user.data))
 
}
 
signupUser()

Я запускал это как отдельный скрипт, заданный в файле package.json.

package.json

"scripts": {
"start": "cd trelloapp && npm start",
"cy:run": "cypress run",
"createUser": "node signupUser.js"
}

Имея такой скрипт, я запускал его через npm run createUser, а затем прогонял свои тесты: npm run cy:run. В тестах я просто считывал файл и устанавливал куку из файла:

cy
.readFile('./cypress/data.json')
.then(({ accessToken }) => {
cy
.setCookie('trello_token', accessToken);
});

Если вы предпочитаете этот подход, очень важно включить data.json в файл .gitignore. Это особенно важно, если это не одноразовый пользователь. Хранить важные данные в открытом виде – не очень хорошая идея, и это основная причина, по которой я больше так не делаю: это довольно рискованный подход, особенно когда команда начинает расти, и все больше и больше людей получают доступ к базе кода.

Я также считаю, что это не очень изящное решение. Если я забуду запустить скрипт, мои тесты упадут. Но это было частью моего пути в обучении, и хорошо мне послужило. Наилучшим подходом для меня стал запуск этого скрипта как плагина в ходе конфигурации Cypress.

Создание плагина

Перепишем наш скрипт так, чтобы он возвращал данные ответа и импортировался как модуль:

signupUser.js

const signupUser = async () => {
 
const user = await axios
.post('http://localhost:3000/signup', { email, password })
 
return user.data
 
}
 
module.exports = signupUser

Теперь мы можем импортировать этот модуль в наш файл plugins/index.js и использовать его в ходе конфигурации:

cypress/plugins/index.js

const signupUser = require('../../signupUser.js')
 
module.exports = async (on, config) => {
 
config.env = await signupUser()
 
return config;
 
}

Cypress подождет, пока не разрешится функция signupUser(), а затем сохранит данные, возвращаемые функцией, в объект config. В этом случае данные генерируются в ходе прогона теста и доступны только тогда, когда Cypress запущен. Если вы запускаете тесты параллельно – например, на десяти машинах – тогда этот скрипт будет вызван десять раз. Но это даже и хорошо – эти пользователи не будут мешать друг другу.

Обсудить в форуме