Protractor — это инструмент для end-to-end тестирования Angular и AngularJS приложений на JavaScript, построенный поверх WebDriverJS. Одной из ключевых практик организации тестов является правильное разделение на суеты (suites) и спеки (specs), что обеспечивает структурированность, масштабируемость и удобство поддержки кода.
Суита представляет собой логическую группу тестов, объединённых общей
целью или функциональной областью. В Protractor используется структура
describe, которая позволяет задавать название суиты и
объединять внутри неё несколько спецификаций.
describe('Авторизация пользователя', () => {
it('Должна открываться страница логина', () => {
browser.get('/login');
expect(browser.getTitle()).toEqual('Login Page');
});
it('Должен происходить успешный вход', () => {
element(by.id('username')).sendKeys('admin');
element(by.id('password')).sendKeys('password');
element(by.buttonText('Login')).click();
expect(browser.getCurrentUrl()).toContain('/dashboard');
});
});
Ключевые моменты о суитах:
describe('Название суиты', function() {...}).Спек — это отдельный тестовый сценарий, проверяющий конкретное
поведение приложения. В Protractor спек создаётся через функцию
it, которая принимает описание теста и функцию с шагами
выполнения.
it('Должна отображаться форма регистрации', () => {
browser.get('/register');
expect(element(by.css('form#registerForm')).isPresent()).toBe(true);
});
Особенности спецификаций:
it должен быть самодостаточным:
выполнять проверку одной функциональности.Protractor поддерживает вложенные суиты, что позволяет строить иерархию тестов:
describe('Панель администратора', () => {
describe('Управление пользователями', () => {
it('Должен отображать список пользователей', () => {
browser.get('/admin/users');
expect(element.all(by.css('.user-row')).count()).toBeGreaterThan(0);
});
it('Должен добавлять нового пользователя', () => {
element(by.buttonText('Add User')).click();
element(by.id('username')).sendKeys('newUser');
element(by.id('submit')).click();
expect(element.all(by.css('.user-row')).last().getText()).toContain('newUser');
});
});
describe('Настройки системы', () => {
it('Должны сохраняться изменения конфигурации', () => {
browser.get('/admin/settings');
element(by.id('enableFeature')).click();
element(by.buttonText('Save')).click();
expect(element(by.id('enableFeature')).isSelected()).toBe(true);
});
});
});
Вложенные суиты позволяют:
beforeEach и
afterEach.Для больших проектов разделение на файлы также важно:
*.spec.js.auth.spec.js, dashboard.spec.js и т.
д.).protractor.conf.js)
поддерживает указание суитов через suites:exports.config = {
framework: 'jasmine',
specs: [],
suites: {
login: 'specs/login/*.spec.js',
admin: 'specs/admin/*.spec.js',
all: 'specs/**/*.spec.js'
},
directConnect: true,
capabilities: {
browserName: 'chrome'
}
};
С помощью suites можно запускать отдельные группы тестов
командой:
protractor protractor.conf.js --suite login
beforeEach и afterEach для суитДля подготовки окружения и очистки состояния используется структура хуков Jasmine:
describe('Форма обратной связи', () => {
beforeEach(() => {
browser.get('/feedback');
});
afterEach(() => {
browser.manage().deleteAllCookies();
});
it('Должна отправлять сообщение', () => {
element(by.id('message')).sendKeys('Тестовое сообщение');
element(by.buttonText('Send')).click();
expect(element(by.css('.success')).isPresent()).toBe(true);
});
});
beforeEach выполняется перед каждым it
внутри текущей суиты.afterEach выполняется после каждого
it.it должен проверять один сценарий.Хотите, я могу отдельно составить подробную схему оптимальной структуры больших проектов Protractor с разделением на суиты и спеки, чтобы наглядно показать, как организовать сотни тестов?