【问题标题】:Loop with condition at the beginning in protractor在量角器中以条件开头的循环
【发布时间】:2016-03-29 15:03:05
【问题描述】:

我需要一个像 while() 这样的重复块,它在执行之前验证条件。我的代码在下面,但是 while 不起作用...

var foundPersonen = true;

      while (foundPersonen) {
        detailPage.getAllPersonen().then(function(value) {
          if (value.length == 0) {
            foundPersonen = true;
            remoteControl(Keys.HK_BACK);
            remoteControl(Keys.HK_P_up);
            remoteControl(Keys.HK_INFO, 1, 3000);
          } 
          else {
            foundPersonen = false;
          }
        });
      }

我怎样才能替换 while 但仍然有我需要的结果?

【问题讨论】:

  • 这是什么语言?它似乎是 C#。有点不清楚问题是什么;你所说的“这段时间不起作用”到底是什么意思?
  • 它是javascript - 量角器工具。我认为量角器没有while循环,所以它需要类似的东西来解决我的问题。我想重复该块,直到我的布尔条件变为假然后停止。如果我使用这个,我的测试甚至没有开始,我得到了浏览器,但页面没有加载,然后它失败并显示一条奇怪的消息: 189098 ms:标记扫描 1270.6 (1457.6) -> 1270.6 (1457.6) MB, 2569.1 / 0 ms [al location failure] [GC in old space requested]。 192186 毫秒:标记扫描 1270.6 (1457.6) -> 1270.6 (1457.6) MB,3087.6 / 0 毫秒 [

标签: while-loop protractor


【解决方案1】:

我至少部分同意alecxe。一些“等待”命令应该可以解决这个问题。我只是想解释一下我的想法,希望它对你有用......因为我花了很多时间在这种问题上^^。

对我来说最重要的是 Protractor 异步运行所有内容。 当您运行测试时,Protractor 基本上会运行它可以运行的代码的每一部分,即直到它遇到一个 Promise。当它遇到一个 promise 时,Protractor 可以做两件事,这取决于你是否设置了browser.ignoreSynchronization = true;(这是我的情况)

  1. 如果是真的,Protractor 会创建一个新线程并等待 promise 被解析,但在“主线程”中 Protractor 会继续执行您的代码。如果你想让 Protractor 等待某些东西,你必须明确地写出来。
  2. 如果为假(默认情况下是这种情况),Protractor 将在继续之前添加browser.waitForAngular。当然,您始终可以在代码中添加显式等待命令,并且在某些情况下您可能希望这样做以获得更稳定的代码。

如果您想了解更多信息,请阅读this post

    var foundPersonen = true;
        while (foundPersonen){
           detailPage.getAllPersonen().then(function(value) {
           if (value.length == 0) {
              foundPersonen = true;
              remoteControl(Keys.HK_BACK);
              remoteControl(Keys.HK_P_up);
              remoteControl(Keys.HK_INFO, 1, 3000);
           } 
           else {
              foundPersonen = false;
           }            
       }

在我的情况下 (browser.ignoreSynchronization = true;),会发生这种情况:

  1. 为布尔值分配一位内存并将值设置为 1;
  2. 评估位
  3. 如果是1

    创建一个线程。在这个线程中,创建一个promise并等待它被解析,然后用promise的值做一些事情

    在主线程中,返回第2步

  4. 如果为0,继续

这种解释导致了一个简单的预测。由于将布尔值设置为 0 的代码在 承诺被解决后被处理,这段代码将尽可能快地创建承诺 直到其中一个承诺被解决并将布尔值设置为 false

结果呢?在解决第一个承诺之前,您的代码将达到最大内存。 --> 你会收到一些与内存分配相关的异常。

我用这段代码测试过:

    return scenariiSteps.AtlasLogin("my", "credentials")
    .then(function () {

        var foundDialogs = element.all(by.xpath("//div[@dialog-id]"));
        var foundDialogsZero = true;
        while (foundDialogs) {
            foundDialogs.count().then(function (value) {
                if (value == 0) {
                    foundDialogsZero = true;
                    console.log("0, man")
                }
                else {
                    console.log("Found something!")
                    foundDialogsZero = false;
                }
            });
        }
    });

这段代码的作用是

  1. 登录
  2. 为某个对象分配内存(它将在我的应用页面中存储对话框列表)
  3. 为布尔值分配一位内存并将其设置为 false。
  4. 评估比特
  5. 如果是1

    创建一个promise并等待它被解决,然后用promise的值做一些事情

    返回第 4 步

并且,为了确保我的解释,请注意,一旦用户登录,我的应用程序就会包含 2 个对话框。

如我所想,我收到了FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory

“好的,谢谢你这么长的解释,但是……我现在该怎么办?”

基本上你必须告诉 Protractor 在执行你想要的操作之前等待一些条件。最好的方法取决于您的要求和环境。例如,我认为alecxe 的解决方案不会解决我的环境中的问题。

如果您需要更多帮助,了解更多有关您想要做什么的信息会很有用。

【讨论】:

  • 好的,非常感谢...这是我想要做的:我有一个电视页面 -> 选择去一个频道。到达那里后,通过我的特定 css 获取所有元素。如果该 css 至少有一个元素,请执行某些操作,如果没有,请从上一页返回主菜单并移至另一个频道。
  • 好的,我只是找不到在评论中编写代码的正确方法,但是...您对此有何看法?我喜欢递归函数,但你必须绝对确定当然至少有一个“好”通道。但是,您仍然可以在 evaluteChannel 中添加一些条件。 var evaluateChannel = function(){(go to some channel)element.all(by.css('identifier')).count().then(function(value){if(value === 0){evaluateChannel();}else {console.log("Yihaaaa")}})}
【解决方案2】:

是的,由于量角器不断将所有内容添加到控制流中,因此像 while 这样的块不会按预期工作。尝试在函数中递归调用它。

function keepChecking(){
    while (foundPersonen) {
        detailPage.getAllPersonen().then(function(value) {
            if (value.length == 0) {
                foundPersonen = true;
                remoteControl(Keys.HK_BACK);
                remoteControl(Keys.HK_P_up);
                remoteControl(Keys.HK_INFO, 1, 3000);
                keepchecking();
          } 
          else {
            foundPersonen = false;
          }
        });
      }
}
keepchecking();

【讨论】:

  • 我已经尝试过了,但它仍然不起作用......我遇到了同样的错误。
【解决方案3】:

我想你可以用browser.wait()解决它:

browser.wait(function () {
    return detailPage.getAllPersonen().count().then(function (count) {
        if (count == 0) {
            remoteControl(Keys.HK_BACK);
            remoteControl(Keys.HK_P_up);
            remoteControl(Keys.HK_INFO, 1, 3000);
            return false;  
        }
        else {
            return true;
        }
    }
}, 10000);

这将在计数为 0 时执行最长 10 秒的条件函数。如果为 0,它将执行您的远程控制功能。请测试。

【讨论】:

  • 谢谢,但这并不能解决我的问题。我需要从 (count == 0) 重复该块,从那里重复所有操作,直到 (count != 0)。
  • @oc.bara browser.wait() 将持续执行该函数,直到它评估为真或发生超时。如果你尝试这样做会发生什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-27
  • 1970-01-01
相关资源
最近更新 更多