如何使用C#和NUnit构建GUI应用程序的单元测试


16

我被要求做一个小项目,为我们的一个客户提供一个简单的应用程序。通常,我会在后端代码上工作,在那里我已经解决了所有测试需求,而且我还没有为GUI编写测试的乐趣,因此我不清楚应该如何设置EXE的测试代码和工具。

我的第一个直觉是简单地将测试与应用程序代码一起包含,但是这将需要提供一些特定于测试的依赖项,而我已被指示不要将其交付给客户。我也无法从任何现金中提取现金用于专用测试工具,因此我需要使用手边的工具(StoryQRhinoMocksNUnit),这实际上足以测试一个简单的GUI应用程序的行为。据我所知,这使我不得不在保持设计非常简单或为测试而故意过度设计之间寻求一个良好的平衡。似乎我要么像往常一样在单独的库中构建具有业务逻辑的应用程序并针对该库进行测试,要么找到其他机制使我可以执行该应用程序,而不会破坏应用程序设计所没有的其他模块真的需要。

编辑:
请注意,这个问题是关于如何构造NUnit和我的可执行文件之间的关系(而不是DLL),而不是关于如何分离表示和业务逻辑。
/编辑

所以我的问题是:

  1. 是否有特定/推荐的方法来配置带有单元测试的简单GUI应用程序,以使我能够使用手头的工具来充分检查状态和行为,而又无需过度设计?
  2. 我是否错过了一些有关测试EXE(而不是DLL)时应调用/配置NUnit的方式的基本知识?
  3. 您能否提供或指出我如何实现所有这些目的的示例?

我意识到可能有不止一种方法可以执行此操作,因此我正在根据您的经验寻找具体的实施准则。


NUnit并非旨在直接测试GUI。您需要将表示层(即视图)与数据和业务逻辑(即模型)分开,以便无需使用视图即可测试视图中包含的内容。
伯纳德

1
@Bernard这个问题不是关于分层GUI进行测试。我自然地将所有应用程序(甚至是琐碎的应用程序)分层放置,因此这对我来说真的不是问题。我已经对问题进行了编辑,以使其适合您,希望它可以消除所有误解。:)
S.Robins 2012年

1
EXE的单元测试中没有什么非常复杂的。只要让您的测试DLL引用您的EXE文件,就可以了。
whatsisname 2012年

Answers:


3

我在对simoraman的回答的评论中提到,我想到了几种方法来做到这一点。我的选择之一类似于Jalayn回答中关于创建重复项目并生成DLL的建议,而我的另一个想法是简单地链接到项目中要测试的代码中的文件。虽然两种方法都可以使用,但它们并不理想。

在第二种情况下,除非我能真正弄清体系结构以最小化依赖关系,否则我将不得不管理一些单元依赖关系。这对于较小的项目很好,但是较大的项目很容易变成一个真正的混乱局面。但是,我对此选择的最大抵制是它的绝对优雅。当然可以要使其正常工作,但这样做实际上需要打破封装,以直接通过源代码测试程序集的内部,而不是通过公共接口测试程序集,在我看来,这是一个很大的禁忌。同样,拥有一个额外的项目文件将意味着要么一次在两个项目中重复工作,要么意味着找到一种方式一次将项目文件设置自动添加到两个文件中,或者记住每次构建时都要复制并重命名项目字段。也许可以在构建服务器上将其自动化,但是在IDE中进行管理会很麻烦。同样,它可以工作,但是如果您弄错了,它充其量只是一个麻烦,更糟的是它会令人讨厌。

最好的方法似乎是通过whatsisname对我的问题进行评论,并简单地将EXE作为参考添加到测试项目中。事实证明,在这种情况下,EXE被有效地对待与DLL一样,并且我能够访问所有分层的类以测试漂浮的所有东西。


2

我觉得:

  • 您的业​​务测试代码应位于单独的项目中,以测试您的业务代码库。
  • 您的GUI测试代码应在单独的项目中,以测试您的GUI库。现在,如何构建GUI库而不是可执行文件,我将在以后尝试回答。
  • 如果您有my.namespace.biz.MyClass,则您的测试类应为my.namespace.biz.MyClassTest(或MyClassTestCase)。
  • 如果要测试在可执行目标中找到的代码,则应具有一个建立EXE的安装程序,以及一个建立一个库(DLL)的安装程序,该库是您将针对其进行测试的库。

这些是我想遵循的规则,无论是Java还是C#(当然Java都没有EXE问题:-))

至于如何配置测试环境,在我看来,您至少有以下两个选择:

使用MSBuild

创建您的.proj文件的克隆(例如myproject-as-dll.proj)。OutputType将克隆文件中的从“ EXE” 更改为“ Library”。现在,使用MSBuild命令可以生成一个库,可以将其设置为包含NUnit测试用例的项目中的引用。

在我看来,这是可能的,但我从未诚实地使用过它,所以我不确定。另外,您的集成测试服务器上可能没有MSBuild,而且我不知道它是否可以与Visual Studio分开...

使用NAnt

如果您不熟悉NAnt,则必须用Google搜寻如何使用它配置项目构建。也许看看这个,这是一个有点老,但笔者评论的恶性文件,如果找到自我解释(编辑:检查自己的文件更详细地,我发现他的配置文件非常可重复使用)。由于他执行测试用例并启动代码覆盖工具,因此他不仅完成构建工作。现在,我承认我从未使用过NAnt,与它使用过Java的老版本“ Ant”相反,但是我看到的是完全一样的东西,而且我认为学习起来并不难。

使用该工具,您可以提出一种配置,该配置将使您能够:

  • 将所有项目(业务逻辑,GUI等)构建到单独的库中
  • 建立您的测试项目
  • 启动测试(该特定部分由NUnit2任务完成)。
  • 使用NCover任务检查代码覆盖率。

使用更多代码,您甚至可以:

  • 在集成服务器中执行每晚部署
  • 如果您的集成服务器中有NAnt,请在计划任务的帮助下启动每晚的集成测试

无需更改Visual Studio文件中的任何内容即可完成所有操作。而且,实际上,对我来说,这看起来似乎不算过度,但这只是一个文件。可能需要一两天的时间才能完成所有工作,但我认为您将拥有一个不错的设置。

最后,我将把构建,测试和运行项目所需的一切交给客户。我倾向于认为它显示出您的专业水平以及您编写高质量代码的事实(在我看来,您正在这样做,因为您正在寻找优雅的解决方案)


0

仅仅因为项目很小(最初)并不意味着适当的架构会过度设计。您想要编写测试的事实表明,您的项目并不是一个完全琐碎的一次性黑客。

您没有提到要使用哪个GUI框架。WPF MVVM(Model-View-ViewModel)很不错,它使您可以轻松编写所有逻辑的测试。使用WinForms,我已经听说了有关MVP(模型-视图-演示器)的好消息


我为自己编写的所有代码编写测试。甚至您可能会发现的琐碎东西。我唯一不写测试的时间是当我加峰值时。在这种情况下,我要向客户提供一次性的公用事业,因此测试不仅仅是奢侈的事情,它是满足我们质量标准的要求。就“过度工程”而言,这不是在好还是坏的体系结构之间进行选择,而是避免了强加这种情况下不需要的附加分层的需要,因为该应用程序是单一用途的,生命周期相对较短。
S.Robins,2012年

就GUI框架的选择而言,我不认为这会如何影响测试环境的设置方式。我正在寻找使用现有工具专门为GUI层实施单元测试的方法。这个特定的答案并没有真正告诉我任何有关此的信息。
S.Robins 2012年

Simoraman-如果您删除了颇具判断力的第一段,这将是一个答案。解决此问题,我将删除-1。@ S.Robins注意第二段相关的-尽管不是完整的答案,但会有所帮助。如果您的GUI层很薄,结构良好且很明显,并且所有业务逻辑都已通过模型级别的单元测试进行了测试,则可能不需要进行额外的显式测试UI的麻烦。
Mark Booth 2012年

1
@MarkBooth分层并不是真正的问题。正如simiraman提到的,我可以MVP,MVVM,也可以构建更薄的东西。但是,我确实有一些GUI特定元素需要进行显式测试,这就是为什么我决定将其写成一个问题的原因。我有两个想法,如果情况变得更糟,我知道最终我将能够解决问题并自己写下答案。但是,我确实想向社区开放,因为我认为这对ProgrammersSE是一个很好的问题。;-)
S.Robins 2012年

0

看一下我对以下问题的回答: 如何为Winforms解决方案设置MVP?

实际上,我已经编写了一个示例应用程序,以显示如何对GUI进行分层和测试。

阅读您的编辑:使用与您的开发环境集成的测试运行器。我使用ReSharper。


感谢ReSharper的建议。这是我在开发时使用的工具。不幸的是,它在集成构建服务器上执行测试时无济于事。它还没有告诉我在测试时如何配置Nunit测试以访问exe中的代码。
S.Robins 2012年

1
非正式地,确实如此。exe只是视图,作为应用程序启动的一部分,它从类库中加载演示者,模型和视图模型。至少在我的解决方案中,视图足够笨拙,以至于我们不使用自动化测试来对其进行测试,而只是进行验收测试以确保所有内容拼写正确并且按钮在正确的位置。用NUnit测试dll非常容易。
Bryan Boettcher

0

几年前,我写了Nunit WinForms(我猜是6年)。我特别记得的一件事是,尽管它是一个单元测试用例,但它也可以用作端到端测试用例。有时,前端测试不多(一种简单的形式)。因此,即使您尝试测试单击按钮时弹出的消息框,也无意中测试了来自其他层的各种其他方法。有些事情您也无法自动化。使用自动单元测试无法自动实现外观,感觉和可用性。发布之前,您将必须运行一些手动测试。


如果客户指定屏幕应该以某种方式显示或以某种方式更改,则您应该能够测试这些内容。将规范捕获为测试是BDD方法的核心,而且我从未发现过这样的情况,即使有创造性,您也找不到能够自动化测试的方法。真正的问题是测试是否具有价值,应用程序的分解因素是否足以使您首先实现所有测试的自动化以及测试是否具有成本效益。不过,我同意,有时并非如此。
S.Robins,2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.