Protractor — это инструмент для энд-ту-энд тестирования Angular и не только Angular приложений. Важной частью эффективного тестирования является оптимизация производительности выполнения тестов и корректная организация работы с асинхронным JavaScript-кодом.
JavaScript в браузере и Node.js работает на основе событийного цикла. Protractor взаимодействует с браузером через WebDriver, где большинство операций асинхронны.
Основные принципы управления асинхронностью в Protractor:
async/await для линейного, читаемого
кода..then(), которые создают избыточные
уровни вложенности.sleep(), которые блокируют
выполнение, снижая производительность тестов.Пример оптимального ожидания элемента:
const EC = protractor.ExpectedConditions;
const button = element(by.id('submit'));
await browser.wait(EC.elementToBeClickable(button), 5000);
await button.click();
Использование ExpectedConditions гарантирует, что тест
не выполняет лишние операции и не простаивает без необходимости.
Protractor поддерживает параллельное выполнение
через конфигурацию multiCapabilities или
shardTestFiles. Это позволяет распределять нагрузку между
браузерами и ускорять общий прогон тестов.
Пример настройки в protractor.conf.js:
exports.config = {
capabilities: {
browserName: 'chrome',
shardTestFiles: true,
maxInstances: 3
},
framework: 'jasmine'
};
Важно: каждый шардинг создает отдельную сессию браузера, поэтому ресурсы машины и количество одновременных потоков должны быть учтены, иначе возникнет деградация производительности.
Производительность сильно зависит от локаторов элементов.
Рекомендации:
by.model,
by.binding и by.repeater только при
необходимости, поскольку они добавляют дополнительную обработку
Angular-специфичных данных.Пример эффективного CSS-селектора:
const loginInput = element(by.css('input#login'));
await loginInput.sendKeys('user');
Тесты, которые повторно открывают страницы или выполняют полную перезагрузку браузера, значительно замедляют прогон. В Protractor есть механизмы, позволяющие оптимизировать этот процесс:
browser.get() один раз и работать с
состояниями приложения через маршрутизацию.beforeAll(async () => {
await browser.get('https://example.com');
await login('user', 'password'); // Пользователь логинится один раз
});
Неоптимальные ожидания часто становятся узким местом в производительности:
browser.sleep() следует избегать, так как это
принудительная задержка.ExpectedConditions.Чтобы улучшить скорость тестов:
chromeOptions: { args: ['--headless'] }), который снижает
затраты ресурсов на визуализацию.Protractor позволяет интегрироваться с инструментами Chrome DevTools и Node.js профайлерами. Это помогает выявить узкие места в тестах и приложении:
browser.manage().logs() для анализа
производительности загрузки и JS-ошибок.Оптимизация кода тестов снижает их время выполнения:
class LoginPage {
constructor() {
this.usernameInput = element(by.css('#username'));
this.passwordInput = element(by.css('#password'));
this.submitButton = element(by.css('#submit'));
}
async login(user, pass) {
await this.usernameInput.sendKeys(user);
await this.passwordInput.sendKeys(pass);
await this.submitButton.click();
}
}
Главная цель оптимизации — ускорение тестов без потери стабильности. Чрезмерная экономия на ожиданиях и проверках может привести к нестабильным тестам. Компромисс достигается через:
Эффективная оптимизация Protractor-тестов требует комплексного подхода: управление асинхронностью, рациональная организация локаторов, параллельное выполнение, контроль загрузки страниц и модульный код. Все эти меры в совокупности позволяют уменьшить время прогонов и повысить стабильность тестового процесса.