2015-11-05 124 views
0

我对单元测试很新,但我一直在尝试使用Nightwatch创建一个脚本,该脚本通过页面的主体内容,单击每个链接并报告返回它是否坏了。Night循环执行命令for循环内循环顺序不正确

我试图做一个for循环遍历每个标签的正文内容,统计'a'标签中包含的数量,然后点击它们中的每一个,但每当我使用browser.execute命令在for循环中,脚本执行顺序不正确。

这是我的代码。我扔在一对夫妇的console.log语句,试图弄清楚这是怎么回事:

'Click Links' : function(browser) { 
browser 
    //Count all tags (p/div) in content that aren't links 
    .useCss() 
    .execute(function() { 
    return document.querySelectorAll("div.field-item.even *:not(a)").length; 
    }, 
    function(tags){ 
    tag_total = tags.value; 

    //Loop through every tag in content & check every a tag contained within 
    for (var x = 1; x < tag_total+1; x++) { 
     console.log("x val before execute: " + x); 
     browser.execute(function() { 
     return document.querySelectorAll("div.field-item.even *:not(a):nth-child(" + x + ") a").length; 
     }, 
     function(links){ 
     console.log("x val at start of execute: " + x); 
     a_total = links.value; 

     for (var y = 1; y < a_total+1; y++) { 
      browser.click("div.field-item.even *:not(a):nth-child(" + x + ") a:nth-child(" + y + ")"); 
      browser.pause(1000); 

      //Conditionals for on-site 404/403 links 
      browser.execute(function() { 
      return document.querySelector("meta[content='Error Document']"); 
      }, 
      //Grabs url if link is broken 
      function(result){ 
      if (result.value != null) { 
       browser.url(function(result) { 
       console.log("BROKEN LINK: " + result.value); 
       }); 
      } 
      }); 

      //Go back to previous page 
      browser.url(process.argv[2]); 
      browser.pause(1000); 
     } 
     console.log("x val at end of execute: " + x); 
     }); 
    console.log("x val at end of for loop: " + x); 
    } 
    }) 

.end() 
} 

输出我得到:

x val before execute: 1 
x val at end of for loop: 1 
x val before execute: 2 
x val at end of for loop: 2 
x val at start of execute: 3 
x val at end of execute: 3 
ERROR: Unable to locate element: "div.field-item.even *:not(a):nth-child(3) a:nth-child(1)" using: css selector 

这似乎是在for循环运行通过并跳过整个browser.execute块。循环结束后,browser.execute块随后以x输入,其数字为3。

为什么browser.execute命令会导致for循环乱序执行,并且可以执行任何操作来修复它是否按照预期的顺序运行?

回答

2

这与Nightwatch无关,但与Javascript。

当你有一个循环并且你在那个循环中调用一个函数时,这个函数中使用的变量就会被引用保存。换句话说,该变量对于任何函数都不会改变。

这是更容易,如果我们通过一个简单的例子:

var myFuncs = []; 
for (var i = 0; i < 3; i += 1) { 
    myFuncs.push(function() { 
    console.log('i is', i); 
    }); 
} 

myFuncs[0](); // i is 3 
myFuncs[1](); // i is 3 
myFuncs[2](); // i is 3 

这是因为i保存为函数的引用。因此,当在下一次迭代中增加i时,引用不会改变,但值会改变。

这可以通过移动功能的循环之外很容易解决:

function log (i) { 
    return function() { 
    console.log(i); 
    } 
} 

var myFuncs = []; 
for (var i = 0; i < 3; i += 1) { 
    myFuncs.push(log(i)); 
} 

myFuncs[0](); // i is 0 
myFuncs[1](); // i is 1 
myFuncs[2](); // i is 2 

如果你想探索这个概念多一点点,你可以看看这个similar SO answer(其中有一个非常相似的例子 - 讽刺)。

+0

非常感谢。完美回答问题并澄清问题。只是想知道;在Nightwatch脚本中以句法方式格式化此解决方案的最佳方式是什么?你会为每个单独的函数创建一个自定义命令吗? – JoPinsy