【问题标题】:Test execution inside Backgroundworker apruptly ends on elements with many childelementsBackgroundworker 中的测试执行突然在具有许多子元素的元素上结束
【发布时间】:2015-06-30 03:14:45
【问题描述】:

我的一般设置:我们编写了一个带有小 gui 的小型 excel 导入器,它允许非程序员使用“Button.Click”之类的命令编写和执行 gui 测试。底层框架是 TestStack.White。导入 excel 文件和其他一些用户交互后,测试在 System.ComponentModel.BackgroundWorker 内部开始,只要我不查看(甚至不与)包含大量子元素的元素交互,它就可以正常工作。

但只要我与具有很多元素的 TestStack.White.UIItems.WindowItems.Window 或 TestStack.White.UIItems.UIItemContainer 交互,测试执行就会结束。

对于交互,我的意思是从简单的东西,如非空检查或赋值到局部变量或询问它的子数之类的东西。结束测试执行的一些示例: 1)

if(theElement != null){ //everything after this line does not happen. The operator doesn't seem to be overloaded
   doStuff(); //it never reaches this point
}

2)

UIItemContainer pointOfInterest = theElement; //everything after this line does not happen

3)

System.Diagnostics.Debug.WriteLine("AmountOfElements: " + UIAnchor.Items.Count); //the output doesn't come. everything after this line does not happen

在没有数百个元素的窗口中,所有三个示例都按预期工作。

我的意思是很多元素,例如一个窗口,里面有一个 ScrollView,它有一个包含几十个甚至几百个条目的表格,其中每个条目由 3-4 列组成,其中包含文本或复选框或类似的东西。

Backgroundworkers RunWorkerCompleted 和 Disposed 不会被调用。我根本没有任何异常,即使故意放置了 try/catch 块,我也一无所获。调试器到达导致问题的行,就是这样。之后什么也没有发生,即使等待了 1 小时。

相反,我得到的只是几个不同的“线程 {some hex id} 已退出,代码为 259 (0x103)。”在 Visual Studio 的输出窗口中。这是我上次执行的测试:

The thread 0x830 has exited with code 259 (0x103).
The thread 0xfc0 has exited with code 259 (0x103).
The thread 0xc04 has exited with code 259 (0x103).

据我了解此消息,这意味着线程仍然存在。 https://stackoverflow.com/a/22395548/1171328

如果我进入调试器检查导致错误的元素的内容,我会在项目之后的所有元素(带有子元素的列表)上得到超时,包括项目。

此外,问题不是(或不应该是?)主线程结束,就像这个线程中的情况一样:Trying to step through BackgroundWorker code in debug but program ends unexpectedly,因为 gui 仍然运行良好。

有没有人知道这里可能发生了什么或如何解决这个问题?

这就是我启动应用程序的方式:

Application app = TestStack.White.Application.Launch(pathToExeFile);
context.setApp(app); //context is a class with static variables to eas the access to all kind of stuff, so that i access it without having 20 parameters in every method (e.g. Button.Click())

然后用户设置他想要测试的窗口(可能是也可能不是模态窗口 - 但在没有数百个元素的窗口中它可以工作):

foreach (Window win in context.getApp().GetWindows()) {
      System.Diagnostics.Debug.WriteLine("###SelectWindow: " + win.Name + " # " + win.PrimaryIdentification + " # " + win.Title);

      if (win.Name.Equals(nameOfWindowToTest)) {
        System.Diagnostics.Debug.WriteLine("###SelectWindow: gefunden");
        context.UIAnchor = win;
        System.Diagnostics.Debug.WriteLine("####SelectWindow: Anz Items: " + context.UIAnchor.Items.Count); //this gets called, but is the very last thing the thread does
        return null; //does not happen
      }
    }

context.UIAnchor 就是上面提到的Element。然后调用用户设置的方法(例如 Button.Click)。有趣的是 context.UIAnchor = win 并且 items.count 的输出有效。

更新:如果我关闭要测试的应用程序,在我关闭测试程序之前,我会收到 ElementNotAvaiableException。所以线程不应该完全死掉。

【问题讨论】:

  • 如果我不得不猜测 UIItemContainer pointOfInterest = theElement;当您到达该行时,尽管 theElement (可能)仍然为 null 是另一种数据类型,然后是 UIItemContainer ,这会导致问题。您是否尝试在该部分周围加上 if ?如果 )theElement 是 UIItemContainer)
  • 即使由于某种原因此时它仍然为空,[not] null 检查也不起作用。 :'(
  • 我最近遇到了一个问题,BackgroundWorker.DoWork 中的异常没有在 Visual Studio 中显示,worker 刚刚消失。您是否尝试打破抛出的异常?我在我的代码中发现了一个缺失的 Invoke,并且在修复它之后它工作了。
  • @CAA 请添加初始化“theElement”/excel 元素的代码。我认为您的程序仅加载要显示的项目。因此,与这些元素的交互会导致您的程序加载其余部分。
  • @OldFox 我已经添加了我如何设置“theElement”。 Excel 内容在应用程序启动之前就已加载 - 因此不会出现某种形式的问题,例如赛车条件

标签: c# backgroundworker ui-automation white-framework


【解决方案1】:

根据我上面的评论,我认为您的 BackgroundWorker 引发了一个未显示的异常 - 可能是因为 Bug / Feature

在调试/异常对话框中标记“Thrown”之前,运行这个小 sn-p 不会显示未处理的异常。

Public Class Form1

    Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        For I As Integer = 0 To 100
            BackgroundWorker1.ReportProgress(I)
            Threading.Thread.Sleep(25)
            If I = 50 Then Throw (New NullReferenceException)
        Next
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        BackgroundWorker1.RunWorkerAsync()
    End Sub

    Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        ProgressBar1.Value = e.ProgressPercentage
    End Sub

    Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        ProgressBar1.Value = 0
    End Sub
End Class

(对不起VB,应该适用于任何CLR)

示例显示(单击按钮后)ProgessBar 填充到 50% 然后停止,没有 BackgroundWorker 运行,没有 Done 事件。进入 Throw 只会退出该方法。

编辑:我的第一个示例错过了 RunWorkerCompleted 事件,现在 正在 触发,所以这可能与您的问题完全无关,抱歉打扰了。

【讨论】:

  • 没问题。有噪音总比没有好:)。而且即使对我没用,下一个有类似情况的人可能会找到这个帖子。
  • 无名氏和 Windows 传说史诗巨著的绝佳链接
【解决方案2】:

如果你切换到 app.config 中的legacy exception handling mode 会发生什么?

<configuration>
  <runtime>
    <legacyUnhandledExceptionPolicy enabled="1"/>
  </runtime>
</configuration>

【讨论】:

  • 遗憾的是,这并没有改变这种行为。没有额外的异常消息,Visual Studio 的任何窗口中的输出或任何内容。 ://
猜你喜欢
  • 2011-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-19
  • 2022-08-16
  • 2021-10-05
相关资源
最近更新 更多