我试图避免进行 20 次左右的非常小的测试,每次测试基本上都测试白标签网站列表是否已启动并显示一些基本信息。
我有一个网站列表(数组)、它们的 URL、预期标题和网站名称。
我想迭代数组,转到每个 URL 并验证标题是否正确。
像这样:
var x = require('casper').selectXPath;
var white_labels = [
{
URL: "http://site1.com",
Title: "Site 1 Title",
Name: "Site 1"
},
{
URL: "http://site2.com",
Title: "Site 2 Title",
Name: "Site 2"
}
]
casper.test.begin('White Labels Test Suite', white_labels.length, function suite(test) {
var urls;
var i = -1;
casper.start(white_labels[0]["URL"], function() {
urls = white_labels;
});
casper.then(function() {
this.each(urls, function() {
i++;
this.echo("I: " + i);
this.thenOpen(urls[i].URL, function() {
this.echo("URL: " + urls[i].URL);
test.assertTitle(urls[i].Title, urls[i].Name + " title is correct");
});
});
});
casper.run(function() {
test.done();
});
});
当我运行它时,每次我打印出“I”时,它都是正确的...0,然后是 1。
但是,第一个测试失败,因为它返回的标题是站点 2 的标题,而不是站点 1。第二个测试成功。
此时我感到困惑。
最佳答案
问题是i
的变量范围。 casper.each
本质上是一个同步 for 循环。它的内部是异步的 casper.thenOpen
语句,它只安排一个 Action 。它实际上是同步调用的,并将正确的 url 传递给它。 each
循环执行后,casper 步骤队列开始执行(通过casper.run
触发),其中包括所有then*
调用。
问题是 i
是全局的,这意味着当 casper.thenOpen
回调最终执行时,i
是1 对他们两个。
针对您的情况有不同的解决方案:
- 通过将
i++;
替换为var j =++i;
和所有其他i
,将每次迭代的索引固定到该迭代在casper.each
中用于j
。 - 利用
casper.each
将迭代项注入(inject)迭代并且根本不使用任何索引的事实:this.each(urls, function(self, url) { ... });
. - 最简单的方法是将
this.each
更改为this.eachThen
以便它本身是步进的并且您没有i
-问题。
最后看JavaScript closure inside loops – simple practical example和 How do JavaScript closures work?获取更多信息。
关于javascript - 在 CasperJS 中测试 URL 列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26068181/