我有一个集成测试,可以显示一个表单。它不是一个编码的UI测试,它只是一个恰好使用表单的测试。我们现在不讨论,一般来说这是一个好主意,在我看来是必要的。
如果一切按顺序运行,则表单出现,调用一些函数,关闭表单,进行断言,单元测试通过。
但是,如果出现问题......
如果发生异常,则代替失败的单元测试,我得到了“Unhadled exception occurred”对话框。此对话框当然会停止应用程序,直到somone单击“确定”(并且没有人在CI服务器上单击“确定”),然后测试通过。 (或者至少它标记为绿色。)
问题是,我该如何改变这种行为?
经过一些研究,我发现有2 top level exception handlers,一个用于应用程序,一个用于UI线程。
我这样设置:
Application.ThreadException += (o, e) => MessageBox.Show("hello ui thread");
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
AppDomain.CurrentDomain.UnhandledException += (o, e) => MessageBox.Show("hello app");
然后,当发生异常时,我会收到“hello ui thread”消息框。
我能否以某种方式设置Application.ThreadException
,以恢复原始行为?有没有其他方法可以解决这个问题?
更新
正如一些回答者指出我手中有一块非常糟糕的代码,没有什么可以否认的。相信我,UI和业务逻辑没有充分分离的事实远不是最糟糕的事情。
我不是在找借口,但我可以诚实地说,这不是我的错。这段代码是由我从未见过的人编写的,不再在我的公司工作。 (这是一个很好的理由。)
没有足够的文档或说明这个代码的作用,但遗憾的是它是软件的一个重要部分,我们无法承受破坏它,或者使它比现在更加破碎。
我必须重构它,是的。我 * am * 重构它。但为此,我需要先写一些测试。写一些测试,我需要重构它。这是鸡蛋和鸡肉的情况。
现在我不需要关于良好软件设计的一般建议。我不需要对我所处的情况作出判断。我需要对我提出的具体技术问题作出具体的技术解答。
关闭
关于“如果你是我的开发者之一”的评论。我认为你会非常高兴让开发人员清理别人制造的混乱。
答案 0 :(得分:1)
在CI服务器上运行任何类型的UI测试都不是一个好主意,因为您看到的确切行为。更改生产代码以适合您的测试也不是一个好主意。
如果我遇到这种情况,我会做两件事。首先,我将重构代码,以确保可以在没有标准单元测试形式的UI的情况下驱动表单的大部分功能。这可以是演示者,控制器或某种视图模型的形式。
其次,我将删除使用CI套件中的实际表单的集成测试,并仅作为最终集成套件的一部分手动运行,以确保视图模型正确连接。
在您的情况下,如果您设置逻辑模块,如果所有测试都通过表单测试不会抛出任何异常,那么您可以继续运行测试,如果您设置了如果先前的测试失败,则表单测试不运行。
答案 1 :(得分:1)
有了这段代码,我可以从主线程上的UI线程中重新抛出异常:
[TestMethod]
public void Test1()
{
Exception thread_ex = null;
ThreadExceptionEventHandler eventHandler = (o, e) =>
{
thread_ex = e.Exception; //store the exception from the UI thread
Application.ExitThread(); //kill the UI thread
};
Application.ThreadException += eventHandler;
DoTest(); //do the test
Application.ThreadException -= eventHandler;
if (thread_ex != null) //if an exception was stored
throw thread_ex; //throw it again on the main thread
}
因为我使用了Application.ThreadException
,所以"发生了未处理的异常"对话框不会出现。