В тестировании веб-приложений с помощью Puppeteer эффективная организация параллельных пайплайнов позволяет значительно ускорить выполнение сценариев, уменьшить время ожидания и повысить производительность тестов. Параллельные пайплайны — это способ запуска нескольких независимых потоков работы браузера или страниц одновременно, что особенно важно при нагрузочном тестировании, скрапинге данных или комплексных интеграционных тестах.
Puppeteer поддерживает создание нескольких экземпляров браузера, каждый из которых работает независимо:
const puppeteer = require(&
async function runBrowsers() {
const browsers = await Promise.all([
puppeteer.launch(),
puppeteer.launch(),
puppeteer.launch()
]);
const pages = await Promise.all(browsers.map(browser => browser.newPage()));
await Promise.all(pages.map((page, index) =>
page.goto(`https://example.com/page${index}`)
));
await Promise.all(browsers.map(browser => browser.close()));
}
runBrowsers();
Ключевые моменты:
Promise.all позволяет запускать действия
одновременно.
Для экономии ресурсов можно использовать один экземпляр браузера с несколькими страницами:
const browser = await puppeteer.launch();
const pages = await Promise.all([
browser.newPage(),
browser.newPage(),
browser.newPage()
]);
await Promise.all(pages.map(page => page.goto('https://example.com')));
await browser.close();
Особенности:
При работе с параллельными пайплайнами важно грамотно управлять
асинхронными задачами. Puppeteer полностью поддерживает
async/await и промисы:
async function processPage(url) {
const page = await browser.newPage();
await page.goto(url);
const content = await page.content();
await page.close();
return content;
}
const urls = ['https://example.com/1', 'https://example.com/2', 'https://example.com/3'];
const results = await Promise.all(urls.map(url => processPage(url)));
Преимущества такого подхода:
Одновременный запуск слишком большого числа страниц может перегрузить систему. Используется контроль количества параллельных потоков с помощью очередей:
const pLimit = require('p-limit');
const limit = pLimit(3);
const tasks = urls.map(url => limit(() => processPage(url)));
const results = await Promise.all(tasks);
Пояснение:
p-limit позволяет ограничить количество одновременно
выполняющихся промисов.
При интеграции с фреймворками тестирования Puppeteer позволяет параллельное выполнение тестов через нативные возможности Jest:
describe('Parallel Tests', () => {
const urls = ['https://example.com/1', 'https://example.com/2'];
test.each(urls)('Check page %s', async (url) => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(url);
const title = await page.title();
expect(title).toBeDefined();
await browser.close();
});
});
Особенности:
test.each позволяет запускать один и тот же тест для разных
данных.
maxWorkers в Jest контролирует количество
параллельных процессов.
Для больших параллельных пайплайнов важно учитывать следующие рекомендации:
await page.setRequestInterception(true);
page.on('request', request => {
if (['image', 'font', 'stylesheet'].includes(request.resourceType())) {
request.abort();
} else {
request.continue();
}
});
Для крупных проектов с сотнями параллельных задач можно применять
кластеризацию с помощью пакета puppeteer-cluster:
const { Cluster } = require('puppeteer-cluster');
const cluster = await Cluster.launch({
concurrency: Cluster.CONCURRENCY_PAGE,
maxConcurrency: 5
});
await cluster.task(async ({ page, data: url }) => {
await page.goto(url);
console.log(await page.title());
});
cluster.queue('https://example.com');
cluster.queue('https://example.org');
await cluster.idle();
await cluster.close();
Преимущества кластера:
Понимание этих принципов позволяет строить эффективные и надежные параллельные тестовые сценарии на Puppeteer, минимизируя время выполнения и повышая производительность автоматизации.