在测试中使用表单

时间:2015-05-13 12:05:39

标签: c# winforms mstest

我有一个集成测试,可以显示一个表单。它不是一个编码的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 * 重构它。但为此,我需要先写一些测试。写一些测试,我需要重构它。这是鸡蛋和鸡肉的情况。

现在我不需要关于良好软件设计的一般建议。我不需要对我所处的情况作出判断。我需要对我提出的具体技术问题作出具体的技术解答。

关闭

关于“如果你是我的开发者之一”的评论。我认为你会非常高兴让开发人员清理别人制造的混乱。

2 个答案:

答案 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,所以"发生了未处理的异常"对话框不会出现。