Backgroundworker中的测试执行突然终止于具有许多childelements的元素

CAA*_*CAA 18 c# white-framework backgroundworker ui-automation

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

但是,只要我与TestStack.White.UIItems.WindowItems.Window或具有大量元素的TestStack.White.UIItems.UIItemContainer进行交互,testexecution就会结束.

通过交互,我的意思是从简单的东西,如非空检查或分配到局部变量或类似要求它的子计数.结束测试的一些例子: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
}
Run Code Online (Sandbox Code Playgroud)

2)

UIItemContainer pointOfInterest = theElement; //everything after this line does not happen
Run Code Online (Sandbox Code Playgroud)

3)

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

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

我的意思是很多元素,例如一个内部有ScrollView的Window,它有一个包含数十个甚至数百个条目的表,其中每个条目包含3-4列文本或复选框或类似的东西.

BackgroundWorkers RunWorkerCompleted以及Disposed也不会被调用.我没有得到任何异常,即使有目的地放置了try/catch块我也没有得到任何东西.调试器到达导致问题的那一行,就是这样.之后没有任何事情发生,即使等待1小时.

相反,我得到了几个不同的"线程{某些十六进制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).
Run Code Online (Sandbox Code Playgroud)

据我所知,这意味着线程仍然存在./sf/answers/1567688391/

如果我进入debuger检查导致错误的元素的内容,我会得到超出项目(带有childelements的列表)之后的所有元素的超时,包括Items.

问题也不是(或不应该?)主线程结束,就像在这个线程中的情况一样:尝试在调试中逐步执行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())
Run Code Online (Sandbox Code Playgroud)

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

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
      }
    }
Run Code Online (Sandbox Code Playgroud)

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

更新:如果我关闭要测试的应用程序,在关闭测试程序之前,我得到一个ElementNotAvaiableException.因此线程不应该完全死亡.

Ste*_*n B 5

按照上面的评论,我认为你的BackgroundWorker会抛出一个未显示的异常 - 也许是因为这个Bug/Feature.

在调试/异常对话框中标记"Thrown"之前,运行此小片段不会显示任何未处理的异常.

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
Run Code Online (Sandbox Code Playgroud)

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

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

编辑:我的第一个示例错过了RunWorkerCompleted事件,现在正在解雇,所以这可能与你的问题完全无关,对不起噪音.