Tricentis Tosca中执行复杂JavaScript代码检查电商网站dataLayer的语法问题求助
我最近在做电商网站dataLayer的Tosca自动化测试,目标是在网站的特定节点校验推送的追踪数据是否正确。按照Tosca手册的指引,我用了「Execute JavaScript」和「Verify JavaScript」这两个模块,简单的读取操作比如 return dataLayer[0].event.charAt(0) 是能正常跑的,但一涉及到复杂点的逻辑(比如筛选dataLayer里的特定事件)就彻底卡壳了——明明在浏览器控制台能正常执行的代码,放到Tosca里就各种报错,折腾了好久都没搞定,来求助大家!
我遇到的具体问题
比如我想筛选dataLayer里所有event为PageView的对象,在浏览器控制台里这段代码完全没问题:
var result = dataLayer.filter(obj => { return obj.event === "PageView" })
但放到Tosca里,按照手册说的用额外的双引号转义字符串后,写成这样:
"var result = dataLayer.filter(obj => { return obj.event === """PageView"""})"
不管加不加return,Tosca都会报:Expression provided in test step item "JavaScript" could not be parsed due to the following reason: Token is not valid in this context: " ",看起来是引号的问题,但我明明按手册要求转义了啊。
后来我换成数字测试(虽然逻辑上不合理,只是为了排查):
return var result = dataLayer.filter(obj => { return obj.event === 1})
又报错:No suitable value found for command 'return obj.event === 1',彻底搞不懂Tosca对JS代码的语法规则到底是啥了...
试出来的几个可行解决思路
折腾了好多次,终于摸出了Tosca执行JS代码的几个坑和解决方案,分享给同样踩坑的朋友:
- 绝对不要写多行JS代码
Tosca对多行JS的解析兼容性极差,换行符很容易被判定为无效语法,所以不管多复杂的逻辑,都尽量压缩成单行代码。比如上面的筛选代码,直接改成一行:
return dataLayer.filter(obj => obj.event === """PageView""");
- 引号转义的正确姿势
Tosca里如果你的JS代码是用双引号包裹的,内层字符串的双引号必须用三个连续双引号转义;如果用单引号的话,就用三个连续单引号转义。比如上面的代码也可以写成:
return dataLayer.filter(obj => obj.event === '''PageView''');
亲测两种转义方式都有效,选哪种看个人习惯。
- 尽量用ES5语法替代ES6箭头函数
部分老版本的Tosca对ES6的箭头函数支持有问题,换成ES5的普通函数写法,能避免很多莫名其妙的兼容性错误:
return dataLayer.filter(function(obj) { return obj.event === """PageView"""; });
- 明确指定全局上下文的dataLayer
有时候Tosca的JS执行上下文可能找不到全局的dataLayer对象,加上window.前缀明确指定:
return window.dataLayer.filter(function(obj) { return obj.event === """PageView"""; });
- 简化校验逻辑(如果只是要验证存在性)
如果你的需求只是校验PageView事件是否存在,没必要返回整个筛选结果,直接返回布尔值更简单,也不容易出错:
return window.dataLayer.some(function(obj) { return obj.event === """PageView"""; });
然后在Tosca的Verify步骤里校验这个返回值是否为true就行。
最后再提醒几个坑
- 所有JS代码必须有明确的
return语句,Tosca需要拿到可识别的返回值 - 尽量不要在代码里定义变量后再返回,直接返回表达式结果更稳妥
- 测试前先在浏览器控制台确认代码能正常执行,再转成Tosca兼容的格式
希望这些经验能帮到同样在Tosca里折腾dataLayer测试的朋友!
备注:内容来源于stack exchange,提问作者Fl43cH3

