Итак, у меня есть проблема, по сути, между тестовыми блоками it()
у меня есть разные тесты e2e, которые ссылаются на файл тестовых данных *.data.ts
.
Эти файлы данных выглядят примерно так:
export const Customer: CustomerData = {
firstName: 'John',
lastName: 'Doe',
fullName: 'John Doe',
phoneNumber: '(111) 222-3333',
}
эти константы ссылаются на тип, который выглядит примерно так:
export interface CustomerData {
firstName?: string
lastName?: string
phoneNumber?: string
fullName?: string
}
Я не очень хорошо знаком с машинописным текстом, но это основа тестовых файлов данных.
Проблема, с которой я сталкиваюсь, заключается в том, что в некоторых из этих файлов данных я могу сгенерировать случайную строку или случайное число (для различных частей данных). Я хочу, чтобы они генерировались каждый раз между каждым тестом, ОДНАКО кипарис, кажется, использует предыдущие сгенерированные данные для каждого теста.
поэтому в файле данных у меня может быть функция: randomData: generateRandomString(10).toUpperCase()
, которая генерирует случайный набор из 10 символов. И первый тест он сгенерирует правильно, а вот 2-й тест будет использовать ранее сгенерированный набор символов.
Это вызывает проблемы с тестами из-за дублирования данных.
Как я могу убедиться, что Cypress не сделает этого? Я также сталкиваюсь с подобными проблемами, когда я вставляю свойство для данных для теста в тесте для ЭТОГО конкретного теста, и я не хочу его для других тестов. Но Cypress все равно сохранит собственность для следующего теста?
Преобразование ваших переменных данных в функции, которые возвращают переменные, заставит их перегенерировать нестатические переменные при присвоении значения.
// *.data.ts
export const getCustomer: CustomerData = () => {
return { ... }
};
Затем вы можете присвоить значение переменной в блоке beforeEach()
в своих тестах.
// Cypress spec file
import { getCustomer } from 'foo.data.ts'
describe('Some tests', () => {
let customerData: CustomerData;
beforeEach(() => {
customerData = getCustomer();
});
});
Я считаю, что причина того, что данные статичны от одного теста к другому, заключается в том, что когда вы импортируете переменную Customer
, она будет генерировать рандомизированные данные только при импорте, когда файл запускается, а не каждый раз, когда переменная используется. Преобразовывая переменную в функцию, которая вызывается при каждом выполнении теста, вы заставляете рандомизацию происходить до того, как значение будет возвращено из функции.
Вы ищете концепцию Factory Function.
function createPerson(firstName, lastName) {
return {
firstName: firstName,
lastName: lastName,
getFullName() {
return firstName + ' ' + lastName;
},
};
}
Вы можете передавать необязательные свойства при каждом вызове в зависимости от требований теста.
import { createCustomer } from '../support/create-customer.ts'
it('tests new customer', () => {
const customer = createCustomer()
...
})
it('tests existing customer', () => {
const customer = createCustomer('existing')
...
})
support/create-customer.ts
export function createCustomer(type): CustomerData {
const customer: CustomerData {
firstName: 'John',
lastName: 'Doe',
fullName: 'John Doe',
phoneNumber: '(111) 222-3333',
};
if (type === 'existing') {
customer.login = 'abc123'
}
return customer
}
export function createProduct(type): ProductData {
...
}
Как уже говорили другие, он генерирует данные при импорте, а не при вызове свойства.
Чтобы он регенерировался каждый раз, когда вы вызываете свойство, вы можете использовать геттеры свойств.
// randomCustomer will be used like a property
export const Customers = {
get randomCustomer(): CustomerData {
return {
firstName: getRandomName(),
lastName: getRandomName(),
// etc
}
}
}
// Usage
console.info(Customers.randomCustomer);
// { firstName: 'Alice', lastName: 'A' }
Затем каждый раз, когда вы вызываете свойство, оно будет генерировать новую случайную строку
import { Customers } from './customer.data.ts';
it('First test - new customer' ,() => {
console.info(Customers.randomCustomer);
// { firstName: 'Alice', lastName: 'A' }
});
it('Second test - new customer' ,() => {
console.info(Customers.randomCustomer);
// { firstName: 'Bob', lastName: 'B' }
});
Некоторые крайние случаи
it('Two new customers in one test' ,() => {
console.info(Customers.randomCustomer);
console.info(Customers.randomCustomer);
// { firstName: 'Calvin', lastName: 'C' }
// { firstName: 'Devin', lastName: 'D' }
});
// You can assign randomCustomer to a variable so it doesn't get regenerated if you need the same object later in the test
it('Save one new customer to re-use' ,() => {
const customer1 = Customers.randomCustomer;
console.info(customer1)
console.info(Customers.randomCustomer);
console.info(customer1)
// { firstName: 'Edward', lastName: 'E' }
// { firstName: 'Frank', lastName: 'F' }
// { firstName: 'Edward', lastName: 'E' }
});
Возможно, вам будет проще применять рандомизатор внутри каждого теста. Таким образом, становится яснее, какие данные относятся к каждому конкретному тестовому сценарию.
Используя разворот объекта, вы можете либо изменить свойства клиента, либо добавить новые свойства для клиента.
Что-то вроде:
файл данных
export const Customer: CustomerData = {
firstName: 'John',
lastName: 'Doe',
fullName: 'John Doe',
phoneNumber: '(111) 222-3333',
}
тест
import { Customer } from './customer.data.js'
import { generateRandomString } from './helpers'
it('customer with random firstName', () => {
const customer = {
...Customer,
firstName: generateRandomString(10).toUpperCase()
}
expect(customer.firstName).not.to.eq('John')
})
it('customer with login', () => {
const customer = {
...Customer,
login: '[email protected]'
}
expect(customer.login).to.eq('[email protected]')
})
В этой ситуации функция должна рассматриваться как любое свойство в Customer.
Будет ли использование объекта, распространяемого отдельно, также повторно генерировать функцию, если она помещена в файл данных?