0

我的任务是提出一种解决方案,以在 UI 级别进行有效的单元测试和集成测试。不幸的是,我们在 Windows 窗体中有很多代码隐藏。我们还有一个棕地项目,我们正在慢慢迁移到 WPF(新功能在 WPF 中,并且在需要进行重大更改时将旧功能迁移到 WPF)。

WPF 中的所有内容都经过单元测试(数据库除外)。我使用的是 MVVM 方法,所以几乎所有的代码都在那里。

但是,部署前的测试需要花费大量时间,我们需要一种方法来自动化其中的大部分。

也就是说,我所指的这个测试需要在 UI 上进行。

Windows 窗体部分必须进行集成测试,因为部分逻辑在代码隐藏中完成,部分在数据库中完成。

WPF 窗口应该在 UI 级别是可单元测试的,但也应该是集成测试的。

我知道对于一个问题来说这是一个很大的问题,但是有人有什么建议吗?

4

2 回答 2

2

(这个答案是关于如何集成测试你的代码:WinForms 和 WPF。)

我没有给你专利的解决方案,只有投入大量时间和精力使测试易于维护的建议。

确保您可以在 Visual Studio 中修改和运行测试。

必须为测试启动一个不同的工具的额外负担可能足以让开发人员不这样做(我已经看到它发生了)。所以尝试找到一个允许这样做的UI 测试工具。

不要记录测试。

虽然很舒服,但记录的测试代码很难阅读和理解,并且很可能包含许多无关紧要的细节。如果您需要对测试进行更改,您可能必须重新记录它们。测试将更多地是系统工作方式的文档,而不是您希望它如何工作的规范。

为您的测试创建共享基础架构。

在代表窗口行为的对象中为窗口/窗体创建抽象。通过这种方式,您可以隐藏这些对象中的实现细节,使实际测试紧凑且易于阅读。一旦你有了这个基础设施,就很容易添加新的测试。此外,如果实现细节发生变化,您只有一个地方可以对测试进行更改:在基础设施中。

在 Web 测试世界中,这称为页面对象模式

C# 中的测试示例:

ApplicationFake application = new ApplicationFake();

// ApplicationFake.Start() starts the application resulting in that main form opens.
// Start() returns an object that represents the actions that the user can perform on
// the main form.
// The Start() method might contain an assert that the main form was actually opened.
MainFormFake mainForm = application.Start();

// Performing an action that opens a new form returns a representation of the new form,
// in this case the object SomeFormFake.
SomeFormFake someForm = mainForm.ClickOpenSomeFormButton();

// The form fakes exposes properties that returns the forms' observable state.
Assert.That(someForm.Title, Is.EqualTo("Some Form's Title"));
于 2012-07-13T08:24:12.373 回答
1

我完全同意 Torbjorn 的回答,但想补充几点:

从小处着手

页面对象模式是简化测试的好方法,但您会发现需要很长时间才能正确进行抽象。首先抽象出你需要的东西,然后随着时间的推移慢慢添加。

增加价值

不要过分尝试编写端到端回归测试。相反,专注于编写增加价值的测试。例如,证明应用程序启动时没有错误的单个测试非常有用,并且可以为您的构建过程提供早期反馈。从那里干出来。

平衡“深”与“浅”

测试用户界面有几种不同的理念。在它们之间建立一个组合。

显而易见的方法是使用类似生产的设置来测试应用程序,以证明应用程序“从前端”工作。这些是“深度”集成测试,可以运行代码的所有部分并且很有用。它们也可能非常缓慢,因为它们通常依赖于外部服务等。通常,为了可靠,应用程序必须在测试运行之间重新启动以确保有效的环境。

对该方法稍作修改是使用已删除的服务(假产品目录、假身份验证提供程序等)测试应用程序。这些是“浅层”测试,证明用户界面在集成在一起时可以正常工作。它们通常运行得更快一些,因为它们不会有相同的物理限制,例如要考虑的网络延迟。您可以更多地关注演示细节和其他边缘案例。

进一步的修改是隔离部分用户界面并在测试工具中运行它们。这些测试将比以前的方法运行得更快,因为它们不会有启动整个应用程序的相同开销。使用这些测试来断言颜色和高度专业化的表示问题。

稳定时迭代

如果您打算编写功能测试来代替手动回归测试,您可能会发现最好等到开发稳定该功能后再为其编写自动化。如果您在开发过程中开始编写自动化,您将不断地重写测试。如果您想在开发过程中实现自动化,请记住:从小处着手。

获得早期反馈

UI 的自动化测试(也称为功能测试)很有用,但它可能非常非常慢。(我见过运行需要几个小时才能完成。)如果您每天运行一次整个测试套件,您会发现反馈循环太长,这会导致误报、维护问题等。

如果可能,尝试将功能测试集成到构建过程中。如果测试套件花费的时间太长,请找到一种方法来集成一些测试,以便您的构建管道可以将重要的测试作为构建的一部分进行验证。

于 2012-07-13T15:35:09.833 回答