Nightwatch测试用例内forEach遍历数组及console.log不执行问题咨询
问题根因及修复方案
这两个问题本质都是Nightwatch的异步命令队列执行机制和测试用例生命周期控制逻辑导致的,和代码写在测试用例内部/外部没有直接关系。
原因说明
- 问题1:测试用例直接跳转执行的原因
- Nightwatch所有
browser调用的API都是异步的,执行时不会立刻生效,只会先加入内部命令队列排队等待执行 - 你当前使用同步写法编写测试用例,没有主动告知框架用例执行结束的时机:当用例内的同步代码(forEach遍历、console.log)执行完成的瞬间,框架就默认当前用例已经结束,直接销毁上下文启动下一个用例,队列中还没来得及执行的click命令就被直接丢弃
- 循环写在测试用例外部时,相当于模块加载阶段就已经把所有click命令提前加到了browser的全局队列中,用例执行时框架会自动等待队列全部命令执行完成,所以运行正常
- Nightwatch所有
- 问题2:console.log不输出的原因
- Nightwatch默认会隔离测试用例执行上下文的标准输出,未正常执行完成的测试用例的日志会被拦截,不会打印到控制台,你的用例被提前终止,日志自然无法输出
- 部分版本的Nightwatch如果开启了并行测试、静默日志配置,也会默认拦截用例内的普通console输出
修复方案
方案1:添加done回调明确用例结束时机
在测试用例参数中增加done回调,最后通过browser.perform()触发done,明确告知框架用例执行完成:
const namesArray = ["Red", "Blue", "Orange"] module.exports = { 'Delete all the items' (browser, done) { namesArray.forEach(myFunction); console.log("entered") function myFunction(value){ browser .useXpath().click(`//span[text() = "${value}"]`) //其余代码 } // 所有队列命令执行完成后触发done,标记用例结束 browser.perform(() => done()) } }
方案2:改用async/await异步写法(更适配Nightwatch v2+版本)
将测试用例标记为async函数,所有browser API前加await,框架会自动等待所有异步操作执行完成再结束用例:
const namesArray = ["Red", "Blue", "Orange"] module.exports = { async 'Delete all the items' (browser) { console.log("entered") // 改用for of循环保证异步顺序执行 for (const value of namesArray) { await browser.useXpath().click(`//span[text() = "${value}"]`) //其余代码 } } }
内容的提问来源于stack exchange,提问作者Dhruv Bhatnagar
相关产品推荐
相关产品推荐

