测试CasperJS中的URL列表

时间:2014-09-26 20:56:16

标签: javascript casperjs

我正在努力避免进行20个左右的非常小的测试,每个测试都会测试一个白色标签网站列表,并显示一些基本信息。

我有一个网站列表(数组),网址,预期标题和网站名称。

我想迭代数组,转到每个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.第二次测试成功。

我在这一点上感到困惑。

1 个答案:

答案 0 :(得分:4)

问题是i的变量范围。 casper.each本质上是一个同步for循环。它内部是异步casper.thenOpen语句,它只调度一个动作。它实际上是同步调用的,并将正确的url传递给它。执行each循环后,casper步骤队列开始执行(通过casper.run触发),其中包括所有then*个调用。

问题是i处于全局状态,这意味着当最终执行两个casper.thenOpen回调时,i对于它们都是1。

您的案例有不同的解决方案:

  • 通过为i++;交换var j = ++i;,为i交换casper.each内的所有其他j,将每次迭代的索引修复到该次迭代。
  • 使用casper.each将迭代项注入迭代的事实,并且根本不使用任何索引:this.each(urls, function(self, url) { ... });
  • 最简单的方法是将this.each更改为this.eachThen,以使其本身处于步调状态,而您没有i - 问题。

最后,请参阅JavaScript closure inside loops – simple practical exampleHow do JavaScript closures work?了解详情。