2014-09-26 45 views
1

我試圖避免20個左右的非常小的測試,每個測試都基本上測試了一個白色標籤站點列表並顯示一些基本信息。測試CasperJS中的URL列表

我有一個列表(數組)的網站,他們的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(); 
    }); 
}); 

當我運行此,我每次打印出「我」,這是正確的... 0,然後按1

然而,第一次測試失敗,因爲它返回的標題是網站2的標題,而不是網站1.第二個測試成功。

我對此感到莫名其妙。

回答

4

問題是變量範圍icasper.each本質上是一個同步循環。它內部是異步的casper.thenOpen聲明,它只調度一個動作。它實際上是同步調用的,並將正確的url傳遞給它。執行each循環後,casper步驟隊列開始執行(通過casper.run觸發),其中包括所有的then*調用。

問題是,i是全球性的,這意味着當兩個casper.thenOpen回調最終執行時,i都爲1。

有你的情況下,不同的解決方案:與

  • 通過交換i++;var j = ++i;修復在每次迭代到迭代索引中的所有其他icasper.eachj
  • 使用casper.each將迭代項插入到迭代中並且根本不使用任何索引的事實:this.each(urls, function(self, url) { ... });
  • 最簡單的方法是將this.each更改爲this.eachThen,這樣它本身就可以步進,並且您沒有i-問題。

最後,請參閱JavaScript closure inside loops – simple practical exampleHow do JavaScript closures work?瞭解更多信息。

+0

工作就像一個魅力!很糟糕的是,我必須閱讀你的答案爲「更好地使用Javascript」!呃...有時真相會傷害你。謝謝! – 2014-09-26 21:38:05