CodeceptJS BDD模式下如何在所有场景前执行浏览器前置操作?
可行方案整理
针对你在CodeceptJS并行测试中需要全局执行浏览器前置操作的需求,以下是几种落地性强的方案:
方案1:全局Bootstrap钩子+并发锁机制
利用CodeceptJS配置文件中的bootstrap钩子,结合文件锁避免并行进程重复执行前置操作,同时能直接访问浏览器上下文:
// codecept.conf.js const fs = require('fs-extra'); const lockFile = './.setup.lock'; const setupFlag = './.setup.completed'; exports.config = { // 其他配置项... bootstrap: async function() { // 检查前置操作是否已完成 if (await fs.pathExists(setupFlag)) return; // 处理并发冲突,等待锁释放后重试 if (await fs.pathExists(lockFile)) { await new Promise(resolve => setTimeout(resolve, 1000)); return await exports.config.bootstrap(); } try { await fs.writeFile(lockFile, 'locked'); // 获取浏览器实例执行前置操作 const browser = await codeceptjs.container.get('browser'); await browser.url('https://your-app.com'); await browser.fill('#username', 'test-admin'); await browser.fill('#password', 'test-pass'); await browser.click('#login-btn'); // 保存共享上下文(如登录Token)供测试用例使用 const authToken = await browser.getCookie('auth-token'); await fs.writeJson('./.auth-token.json', authToken); // 标记前置操作完成 await fs.writeFile(setupFlag, 'done'); } finally { // 释放锁 await fs.remove(lockFile); } }, teardown: async function() { // 构建结束后清理标记文件 await fs.remove(setupFlag); await fs.remove('./.auth-token.json'); } };
Travis配置补充:将标记文件加入缓存,确保并行任务共享状态:
cache: directories: - .setup.completed - .auth-token.json
方案2:全局步骤+前置检查
在全局步骤文件中定义前置操作方法,结合全局Before钩子,仅在首次调用时执行浏览器操作:
// steps_file.js const fs = require('fs-extra'); const setupFlag = './.setup.completed'; async function ensureGlobalSetup() { if (await fs.pathExists(setupFlag)) return; // 执行浏览器前置操作 await I.amOnPage('/'); await I.login('test-admin', 'test-pass'); await I.createSharedTestData(); // 标记完成 await fs.writeFile(setupFlag, 'done'); } module.exports = function() { return actor({ ensureGlobalSetup, // 其他自定义步骤... }); };
在配置文件中绑定全局前置钩子:
// codecept.conf.js exports.config = { hooks: { Before: async (I) => { await I.ensureGlobalSetup(); } } };
注意:同样需要添加并发锁机制,避免并行进程重复执行。
方案3:Travis前置任务独立执行
如果前置操作无需与测试用例共享浏览器上下文,可在Travis构建阶段单独执行一次:
- 编写独立的前置操作测试文件:
// setup.test.js Feature('Global Precondition Setup'); Scenario('Create all shared test data', async (I) => { I.amOnPage('/'); I.login('admin', 'admin'); I.createTestUser(); I.createTestProject(); });
- 修改Travis配置,在并行测试前执行前置任务:
# .travis.yml cache: directories: - .setup before_script: - if [ ! -f .setup/done ]; then npx codeceptjs run setup.test.js; mkdir -p .setup && touch .setup/done; fi script: - npx codeceptjs run --parallel --grep "@group1" & - npx codeceptjs run --parallel --grep "@group2" & - wait
这种方式无需处理测试进程的并发冲突,前置操作仅执行一次,适合创建静态共享测试数据的场景。
内容的提问来源于stack exchange,提问作者Sarath Babu V S
相关产品推荐
相关产品推荐

