【问题标题】:Why am I getting stackoverflow exception when calling a function twice?为什么调用函数两次时出现stackoverflow异常?
【发布时间】:2017-06-27 06:12:26
【问题描述】:

我有一个用 F# 编写的 selenium UI 测试(使用 canopy selenium nuget 包)。我有一个定义 page 选择器和辅助函数的模块。 page 模块由 test 模块调用。在测试模块中,我调用了一个名为“handlemobimodals()”的函数,该函数运行四个子函数(if/else 代码块),用于查找页面上是否存在元素并单击它(如果存在)。

我面临的问题是,当在测试中第二次调用“handlemobimodals()”函数时,我得到一个堆栈溢出异常(WebDriver 进程由于 StackOverflowException 而终止),就在它的第一个子之后函数被调用。

该函数第一次运行完全正常(在测试早期从另一个函数间接调用),但第二次在测试中直接调用时失败。我对 F# 很陌生,我无法弄清楚我是如何在我的测试中引起递归的,正如 stackoverflow 异常所暗示的那样。

任何见解都将不胜感激。

来自页面模块的片段:

module some_page

    let isOKGotItDisplayed () =
      isDisplayed <| "div.action-button.dismiss-overlay"

    let clickOKGotit() = 
      if isOKGotItDisplayed() = true then
        click "OK, GOT IT"
        describe "OK, Got It clicked"
      else describe "Got nothing"

    let isGoToSearchDisplayed() =
      isDisplayed <| "button:contains('Go to Search')"

    let clickGoToSearch() = 
      if isGoToSearchDisplayed() = true then
        click "button:contains('Go to Search')"
        describe "go search button clicked"
      else describe "Got nothing"

    let isSkipDisplayed() =
      isDisplayed <| "#uploadPhotos > div.continue.skip"

    let clickSkip() = 
      if isSkipDisplayed() = true then
        click "Skip"
        describe "Skip link clicked"
      else describe "Got nothing"

    let mobiOkayGotItDisplayed () =
      isDisplayed <| "Okay, got it"

    let mobiOKGotit() =
      if mobiOkayGotItDisplayed() = true then
        click "Okay, got it"
        describe "Okay, got it"
      else describe "Got nothing"

    let handleMobiModals() = 
      clickSkip()
      clickOKGotit()
      clickGoToSearch()
      mobiOKGotit()


    loginForPathAs user =
       username << "somename"
       paswword << "somepassword"
       handleMobiModals()

来自测试模块的代码片段(注意,handleMobiModals 函数的第一个实例是在 LoginforPathAs 函数中调用的,它是在同一个页面定义模块中定义的):

module_sometest

open some_page

      "Test 001: Log in and do something" &&& fun _ ->
         newBrowser platform
         loginForPathAs user1     
         displayed  quicknoteSendButton
         click quicknoteSendButton
         handleMobiModals ()
         displayed "Subscribe"

注意:为了简单明了,对片段进行了编辑。

【问题讨论】:

  • 快速评论:当您检查布尔函数的结果时,不需要= true。只需使用if mobiOkayGotItDisplayed() 而不是if mobiOkayGotItDisplayed() = true
  • @munn,因为从语言的角度来看不需要= true,一些团队/开发人员更喜欢明确写出预期的条件,因为如果你省略= true,你的代码的可读性会取决于描述性条件函数的命名方式。
  • @rmunn 使用 'if' 评估的函数的结果(例如 mobiOkayGotItDisplayed() )可能为真或假。
  • @codet3str - 没错。当您有一个布尔函数(即,一个可以返回真或假的函数)时,就不需要if function() = true,因为if 语句已经检查某事是否为真。所以说if function()完全等同于if function() = true。而且if isSkipDisplayed() then (code) 的阅读效果比if isSkipDisplayed() = true then (code) 好得多。风格很重要:当您编写更易于阅读和理解的代码时,您最终会产生更少的错误。
  • @rmunn,感谢您的洞察力 - 有道理。我应用了您关于使用更简洁的方式来使用布尔函数的建议。但是,我仍然收到前面描述的堆栈溢出异常。

标签: f# canopy-web-testing


【解决方案1】:

这不是一个直接的答案,但我相信这将有助于更轻松地找到问题。我确实注意到了一些使调试这个问题变得有些困难的东西。您正在从另一个函数调用多个函数,并从测试中调用这个单个函数。将这些功能拆分为单独的测试并将测试更改为 WIP 模式应该有助于查明您的问题。一个测试中有很多可能的失败点。

例如,您可以在 Canopy 的上下文中使用 before(fun _ -> some function(s) here) 或 once(fun _ -> some function(s) here) 来启动新的浏览器并登录,分开测试中的那部分。

【讨论】:

  • 感谢您的建议。我刚刚重新访问了这个问题,它似乎已经解决了。我相信最近对 Chrome 的自动更新解决了这个问题——我肯定尽可能多地调试了代码,所以我知道逻辑流程没有任何问题(即没有递归逻辑) .
【解决方案2】:

此问题似乎已自行解决。我相信我最近的 Chrome 自动更新解决了这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-06
    • 2015-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-20
    • 1970-01-01
    • 2013-01-08
    相关资源
    最近更新 更多