18

我的一般设置:我们编写了一个带有小 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

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

此外,问题不是(或不应该?)主线程结束,就像在这个线程中的情况一样:尝试在调试中逐步执行 BackgroundWorker 代码,但程序意外结束,因为 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。所以线程不应该完全死掉。

4

2 回答 2

5

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

在调试/异常对话框中标记“抛出”之前,运行这个小片段不会显示未处理的异常。

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 事件,现在正在触发,所以这可能与您的问题完全无关,抱歉出现噪音。

于 2015-04-29T11:34:32.733 回答
1

如果在 app.config 中切换到旧的异常处理模式会发生什么?

<configuration>
  <runtime>
    <legacyUnhandledExceptionPolicy enabled="1"/>
  </runtime>
</configuration>
于 2015-05-01T05:35:47.003 回答