Property-based testing (тестирование на основе свойств) представляет собой подход, при котором вместо проверки отдельных заранее заданных входных данных проверяется соблюдение определённых свойств системы для широкого диапазона возможных данных. В контексте Protractor и JavaScript это позволяет создавать более надёжные и гибкие автоматизированные тесты для веб-приложений на Angular и других фреймворках.
1. Свойства (Properties) Свойство — это утверждение о поведении системы, которое должно выполняться для любого допустимого входа. Например, для функции сортировки можно сформулировать свойство: “После сортировки массив должен содержать все исходные элементы и быть отсортированным по возрастанию”.
В Protractor такие свойства проверяются через генерацию множества случайных данных и проверку соответствия поведения приложения ожидаемым результатам.
2. Генерация данных (Data Generators) Property-based testing строится на генераторах данных, которые создают случайные входные значения в заданных пределах. В JavaScript для этого часто используют библиотеки fast-check или jsverify.
Пример генерации случайного числа для теста поля ввода в форме:
const fc = require('fast-check');
fc.assert(
fc.property(fc.integer({ min: 0, max: 100 }), async (num) => {
await element(by.id('input-number')).clear();
await element(by.id('input-number')).sendKeys(num.toString());
const value = await element(by.id('input-number')).getAttribute('value');
return parseInt(value, 10) === num;
})
);
Ключевое здесь — использование fc.property, где задаётся
генератор входных данных и функция, проверяющая свойство.
3. Асинхронность и Protractor Protractor работает с
промисами и асинхронными действиями на странице. Для property-based
testing важно корректно обрабатывать асинхронные операции, используя
async/await.
Пример асинхронного теста свойства:
fc.assert(
fc.property(fc.string(), async (text) => {
await element(by.id('text-input')).clear();
await element(by.id('text-input')).sendKeys(text);
const value = await element(by.id('text-input')).getAttribute('value');
return value === text;
})
);
1. Тестирование форм и полей ввода Property-based подход позволяет проверять поля ввода с множеством случайных значений, включая граничные случаи: пустые строки, специальные символы, длинные тексты. Это обеспечивает выявление ошибок валидации и обработки данных.
2. Валидация сортировок и фильтров Для таблиц и списков можно проверить свойства, такие как “сортировка должна сохранять все элементы” или “фильтр должен возвращать только элементы, удовлетворяющие условию”. Генерация случайных наборов данных позволяет обнаружить ошибки, которые не покрываются ручными тест-кейсами.
3. Проверка реактивного поведения UI Свойства, например “кнопка должна становиться активной только при заполнении всех обязательных полей”, можно проверять с помощью комбинации случайных входных значений и проверки состояния элементов интерфейса.
Property-based тесты могут сосуществовать с классическими сценариями на Jasmine или Mocha. Важно соблюдать следующие принципы:
Пример комбинированного подхода:
describe('Property-based tests for form', () => {
it('should correctly handle random numbers', async () => {
await browser.get('/form');
fc.assert(
fc.property(fc.integer({ min: 0, max: 1000 }), async (num) => {
await element(by.id('number')).clear();
await element(by.id('number')).sendKeys(num.toString());
const value = await element(by.id('number')).getAttribute('value');
return parseInt(value, 10) === num;
})
);
});
});
Property-based testing в Protractor открывает возможность создавать более надёжные и масштабируемые тесты, особенно для приложений с динамическим UI, разнообразными входными данными и сложной логикой валидации.