Protractor多Spec文件执行时JSON文件数据异常问题
Hey, let's break down exactly what's causing this mismatch and how to fix it:
核心原因
1. Node.js require的缓存坑
当你在配置里用通配符*-Spec.js时,Protractor启动时会提前加载所有匹配的测试文件。这意味着你的第二个脚本(读取JSON的那个)会在第一个脚本生成文件之前,就执行了require('Created_Itinerari_Output.json')这行代码。Node.js会永久缓存第一次require的结果——所以哪怕第一个脚本后续更新了文件,第二个脚本依然会用缓存里的旧数据,不会去读磁盘上的新文件。
2. 异步文件写入的时序问题
你的第一个脚本用了fs.writeFile,这是个异步操作。默认情况下,Jasmine不会等这个操作完成就会进入下一个it块(甚至直接开始执行第二个测试文件)。虽然最终文件会被正确写入,但第二个脚本很可能在写入完成前就读取了文件,导致拿到过期或不完整的数据。
而当你指定单个测试文件(比如1 Create the Data-Spec.js)时,你只运行了第一个脚本,第二个脚本的require不会被触发。如果之后单独运行第二个脚本,require会读取磁盘上刚生成的新文件,所以功能正常。
可落地的修复方案
1. 放弃用require读取动态文件
不要依赖Node的缓存机制,直接从磁盘读取文件内容,这样每次都会拿到最新数据:
同步读取(简单但会阻塞事件循环):
// 替换原来的require代码 const fs = require('fs'); const jsonDNI = JSON.parse(fs.readFileSync('Created_Itinerari_Output.json', 'utf8'));
异步读取(更推荐,非阻塞):
用Jasmine的done回调等待读取完成:
it("Create the data in the system", function(done) { fs.readFile('Created_Itinerari_Output.json', 'utf8', (err, data) => { if (err) { console.error(err); done.fail(err); return; } const jsonDNI = JSON.parse(data); // 你的测试逻辑写在这里 done(); // 告诉Jasmine异步操作已完成 }); });
2. 等待文件写入完成再执行后续逻辑
在第一个脚本的it块里,用done回调确保Jasmine不会提前进入下一个测试步骤:
it("Create the preRequisite file", function(done) { // ... 你的DNI/邮箱生成代码 ... fs.writeFile(outputFilename, JsonFile, (err) => { if (err) { console.error(err); done.fail(err); } else { console.log("JSON saved to " + outputFilename); done(); // 通知Jasmine可以执行下一个测试了 } }); });
3. 显式控制测试文件执行顺序(可选)
如果想继续用通配符,可以在conf.js里明确列出测试文件的顺序,避免文件名排序导致执行顺序混乱:
specs: [ '1 Create the Data-Spec.js', '2 Use the Data-Spec.js' // 按顺序添加其他测试文件 ]
额外建议
尽量避免用文件在测试间传递数据,推荐用更可靠的方式:
browser.params:把数据存在Protractor的全局参数对象里- Jasmine的
this上下文:在同一个describe块内共享数据(注意要用普通函数function()而不是箭头函数) - Promise:通过返回Promise在测试间传递数据
这些方法更快、更稳定,能避开文件IO和缓存带来的所有问题。
内容的提问来源于stack exchange,提问作者Alexandre

