如何在Protractor中计算各步骤执行耗时并设置超时失败规则?
Hey there! Let's break down how to solve your problem of measuring test step execution time (like how long it takes for a page to load and be ready for the next step after clicking a link) and failing the test if it exceeds 2 seconds.
First off, I notice you tried protractor-perf—but that tool is built for tracking browser performance metrics (like frame rates, style/JS execution times) rather than measuring the exact duration of a single user action + page readiness. That's why the data you got felt unhelpful for your specific need. Let's use a more direct approach instead.
This method lets you precisely measure the time between starting an action and the page being fully ready for the next step.
Example Code
describe('Test Step Duration Check', () => { it('Measure time to load after clicking a link', async () => { // 1. Capture start timestamp right before the action const startTime = Date.now(); // 2. Perform your test action (e.g., click the target link) await element(by.linkText('Your Target Link')).click(); // 3. Wait for the page to be truly ready (adjust this to your page's key indicator) // Use ExpectedConditions to wait for a critical element that signals "ready" await browser.wait( protractor.ExpectedConditions.elementToBeClickable(element(by.id('critical-element-after-load'))), 10000 // Max wait time to avoid hanging indefinitely ); // 4. Calculate elapsed time const elapsedTime = Date.now() - startTime; console.log(`Time taken after click: ${elapsedTime}ms`); // 5. Fail the test if it takes over 2 seconds expect(elapsedTime).toBeLessThanOrEqual(2000); }); });
Key Notes
- Don't skip the wait step: Clicking a link doesn't mean the page is ready immediately. Always wait for a clear signal (like a key element being visible/clickable, or an API request finishing) to ensure you're measuring the actual "ready" time.
- Adjust ExpectedConditions: Use
visibilityOf,presenceOf, orelementToBeClickablebased on what defines "ready" for your page.elementToBeClickableis often the best choice for "can execute next step".
The data you got from protractor-perf relates to browser performance, not action duration. Here's a quick breakdown of what those metrics mean:
Styles/Javascript: Time spent processing stylesheets and JavaScript (in ms—0 here likely means your action didn't trigger heavy style/JS work)numAnimationFrames/numFramesSentToScreen: Total animation frames generated by the browser vs. those actually rendered to the screendroppedFrameCount: Number of frames that failed to render (high numbers mean page lag, but this doesn't directly tell you how long the action took)
If you want to use protractor-perf to complement timing checks (e.g., ensure the page doesn't lag during loading), you can do this:
const PerfRunner = require('protractor-perf'); describe('Performance + Timing Check', () => { let perfRunner; beforeAll(() => { perfRunner = new PerfRunner(protractor); }); it('Check load time and frame rate after click', async () => { const startTime = Date.now(); await perfRunner.start(); await element(by.linkText('Your Target Link')).click(); await browser.wait(protractor.ExpectedConditions.elementToBeClickable(element(by.id('critical-element'))), 10000); const elapsedTime = Date.now() - startTime; await perfRunner.stop(); // Check duration first expect(elapsedTime).toBeLessThanOrEqual(2000); // Optional: Check for excessive frame drops (e.g., less than 10% drop rate) const frameDropRate = (perfRunner.getStats().droppedFrameCount / perfRunner.getStats().numFramesSentToScreen) * 100; expect(frameDropRate).toBeLessThan(10); }); });
- Wait for async requests: If your page loads data via API calls, use
browser.executeAsyncScriptto wait for all XHR requests to finish before ending the timer. - Average multiple runs: To avoid flakiness from one-off slowdowns, run the test 3-5 times and check the average elapsed time instead of a single run.
内容的提问来源于stack exchange,提问作者ASB

