Я пытаюсь объединить несколько тестов с одинаковыми действиями и проверками, используя параметризованное тестирование, но продолжаю получать ошибки. Я новичок в Cypress и JS в целом, имея опыт работы с .net. Любая помощь будет оценена по достоинству.
Моя приставка выглядит примерно так:
{
"username": "username",
"password": "password",
"inputErrorMessageText": "Invalid username or password.",
"homePageWelcomeText": "Welcome, bla bla bla",
"testCases": [
{
"description": "blank username and password",
"username": "",
"password": ""
},
{
"description": "blank password",
"username": "username",
"password": ""
}
]
}
Я пробовал как Cypress.each, так и data.testCases.forEach:
describe("Tests for login page", () => {
let loginPage;
let homePage;
let data;
before(() => {
cy.fixture("login_data").then((fixtureData) => {
data = fixtureData;
cy.wrap(fixtureData).should("have.property", "testCases");
});
});
beforeEach(() => {
loginPage = new LoginPage();
homePage = new HomePage();
cy.visit("/");
});
Cypress.each(data.testCases, (testCase) => {
it(`Invalid username or password error appears when attempting login with ${testCase.description}`, () => {
loginPage.login(testCase.username, testCase.password);
loginPage.verifyErrorMessage(data.inputErrorMessageText);
});
});
it("Successful login with valid username and password", () => {
loginPage.login(data.username, data.password);
homePage.verifyProfileDropDownExists();
});
it("Welcome text is displayed after successful log in", () => {
loginPage.login(data.username, data.password);
homePage.verifyWelcomeText(data.homePageWelcomeText);
});
data.testCases.forEach((testCase) => {
it(`Invalid username or password error appears when attempting login with ${testCase.description}`, function () {
loginPage.login(testCase.username, testCase.password);
loginPage.verifyErrorMessage(data.inputErrorMessageText);
});
});
Продолжайте получать следующую ошибку:
TypeError: следующая ошибка возникла из-за вашего тестового кода, а не из Cypress. > Невозможно прочитать свойства неопределенного значения (чтение «testCases»)
Проблемы
data.testCases.forEach()
не работает, поскольку Cypress (Mocha, но тут не помешает) должен знать, какие тесты запускать, прежде чем тесты действительно начнут выполняться. В этом случае, поскольку data.testCases
не будет иметь значения, когда Cypress начнет собирать тесты для запуска (поскольку данные задаются в блоке before()
), он выдает ошибку, когда data.testCases
не определено.Cypress.each
— это функция. Есть Cypress._.each()
(с использованием Cypress Lodash) и cy.each()
(это не то, что вам нужно).Решение
Импортируйте фикстуру напрямую, вместо того, чтобы загружать ее через cy.fixture()
, что должно предоставить вам доступ к переменной data.testCases
до того, как Cypress определит, какие тесты запускать. Тогда у вас появится возможность запускать несколько тестов либо через data.testCases.forEach()
, либо через Cypress._.each()
.
import data from '../path/to/data.json';
describe("Tests for login page", () => {
...
Cypress._.each(data.testCases, (testCase) => {
it(`Invalid username or password error appears when attempting login with ${testCase.description}`, () => {
loginPage.login(testCase.username, testCase.password);
loginPage.verifyErrorMessage(data.inputErrorMessageText);
});
});
});
Вы по-прежнему можете запустить проверку данных, которые data
имеют свойство testCases
, без cy.fixture()
.
Я имею в виду перебор массива и создание тестовых примеров таким образом, а не часть импорта данных.
Я думаю, что использование данных для реализации сценариев тестирования — довольно распространенная практика. Я мог бы задаться вопросом, имеет ли это ценность в данном конкретном случае (будут ли модульные или интеграционные тесты более разумным вариантом, чем пользовательский интерфейс?). Но в целом, в тех случаях, когда вам нужно повторить одни и те же шаги с разными данными/пользователями/и т. д., я Я бы сказал, что это довольно распространенная практика. Многие другие среды тестирования имеют более надежную поддержку аналогичных практик.
Пожалуйста, ознакомьтесь с рецептом Cypress фундаментальные принципы__dynamic-tests/cypress/e2e /fixture-spec.cy.js .
/// <reference types = "cypress" />
describe('generated from fixture', () => {
// We cannot load JSON file using "cy.fixture"
// because it means the test is already running.
// Same with using "before" hook - new tests cannot be created from "before" hook.
// Instead we need to load JSON file using "require" at the start time
// and generate tests.
const colors = require('../fixtures/colors')
const rainbow = ['red', 'orange', 'yellow', 'green', 'blue', 'violet']
colors.forEach((color) => {
it(`🌈 has color ${color}`, () => {
cy.wrap(color).should('be.oneOf', rainbow)
})
})
})
Хотя прибор технически исправен, я бы предложил поместить данные в начало теста.
Это гораздо более читабельно, поэтому вы можете легко рефакторить и добавлять случаи. Плюс вы можете включить ожидаемую ошибку там же.
const testCases = [
{
"description": "blank username and password",
"username": "",
"password": "",
"error": "user name must be filled in"
},
{
"description": "blank password",
"username": "username",
"password": "",
"error": "password must be filled in"
},
{
"description": "invalid username",
"username": "not-a-valid-user",
"password": "pword",
"error": "username or password is incorrect, please try again"
}
]
testcases.forEach((case) => {
it(case.description, () => {
loginPage.login(login.username, login.password);
loginPage.verifyErrorMessage(case.error);
})
})
``
Это работает, большое спасибо! Возможно, это глупый вопрос, но считается ли это хорошей практикой для тестов в целом?