在UI中执行业务逻辑的unit testing数据库应用程序

我自己pipe理一个相当大的应用程序(5万行代码),它pipe理一些相当关键的业务行为。 为了简单描述这个程序,我想说这是一个能够显示和更改数据库数据的奇特UI,它pipe理着大约1000个出租单位,大约3万个租户和所有的财务。

当我做出改变的时候,因为代码基础太大,我有时候会在别的地方把事情弄坏。 我通常testing它通过去function级别(即我运行该程序,通过用户界面工作)的东西,但我不能testing任何情况。 这就是为什么我想要开始unit testing。

但是,这不是一个真正的三层程序,具有数据库层,业务层和UI层。 许多业务逻辑在UI类中执行,许多事情都是在事件上完成的。 让事情变得复杂,一切都是数据库驱动的,而且我还没有看到(迄今为止)关于如何unit testing数据库交互的好build议。

怎样才能开始这个应用程序的unit testing。 记住。 我从来没有做过unit testing或TDD。 我应该重写它以从UI类中删除业务逻辑(很多工作)吗? 或者,还有更好的方法?

我会开始使用一些工具,通过用户界面来testing应用程序。 有许多工具可以用来创buildtesting脚本来模拟用户点击应用程序。

我还build议你在添加新function的时候开始添加unit testing。 一旦开发了应用程序,创build完整的覆盖范围是非常耗时的,但是如果您逐步完成,那么您就可以分配工作量。

我们通过一个单独的数据库来testing数据库交互,这个数据库只用于unit testing。 这样我们就有了一个静态和可控制的数据集,这样可以保证请求和响应。 然后我们创buildc#代码来模拟各种场景。 我们使用nUnit。

我强烈推荐阅读“ 有效地使用遗留代码”一文 。 它描述了你正在努力完成的一个可行的策略。

其中一个select就是 – 每次出现错误时,编写一个testing来帮助您find问题并解决问题。 使错误得到解决后,testing会通过。 然后,一旦错误得到解决,您将拥有一个工具,可以帮助您检测将来可能会影响您刚刚修复的代码的更改。 随着时间的推移,您的testing覆盖率将会提高,并且您可以随时运行不断增长的testing套件,以便进行潜在的深远变化。

TDD意味着你在build立(并运行)unit testing。 对于你正在做的事情 – 在事实之后添加unit testing – 你可以考虑使用Typemock(一种商业产品)。 另外,你可能已经构build了一个不适合unit testing的系统,在这种情况下,可能会有一些(或很多)重构。

首先,我会推荐阅读一本关于unit testing的好书,比如“unit testing的艺术” 。 在你的情况下,你现有的代码执行testing驱动开发有点晚了,但是如果你想围绕它来编写你的unit testing,那么下面是我会推荐的:

  1. 将要testing的代码隔离到代码库(如果它们不在库中)。
  2. 写出最常见的用例场景,并将其转换为使用您的代码库的应用程序。
  3. 确保你的testing程序按照你所期望的那样工作。
  4. 使用testing框架将testing程序转换为unit testing。
  5. 得到绿灯。 如果没有,那么你的unit testing是错误的(假设你的代码库工作),你应该做一些debugging。
  6. 增加unit testing的代码和场景覆盖率:如果input了意想不到的结果呢?
  7. 再次获得绿灯。 如果unit testing失败,那么很可能是您的代码库不支持扩展场景覆盖,所以这是重构时间!

而对于新的代码,我build议你使用testing驱动开发来尝试它。

祝你好运(你需要它!)

我build议您阅读Michael Feathers撰写的“ 遗留代码高效工作 ”一书。 这将向您展示许多技术,用于逐步增加代码库中的testing覆盖率(并沿途改进devise)。

重构是更好的方法。 即使这个过程是令人生畏的,你应该将演示文稿和业务逻辑分开。 在分离之前,您将无法针对您的业务逻辑编写好的unit testing。 就这么简单。

在重构过程中,您可能会发现一些您根本不知道的错误,最终成为一个更好的程序员!

另外,一旦你重构你的代码,你会注意到testing你的db交互将变得更容易。 您将能够编写testing来执行如下操作:“添加新租户”,这将涉及创build一个模拟租户对象并将“他”保存到数据库。 对于下一个testing,您将编写“GetTenant”,然后尝试从数据库创build租户,并将其转化为内存中的表示forms。然后比较第一个和第二个租户以确保所有字段都匹配值。 等等

我认为将业务逻辑与用户界面分开总是一个好主意。 这有几个好处,包括更简单的unit testing和可扩展性。 你也可能想参考基于模式的编程。 这是一个链接http://en.wikipedia.org/wiki/Design_pattern_(computer_science); ,这将有助于你理解devise模式。

你现在可以做的一件事就是在你的UI类中隔离所有的业务逻辑和不同的业务基础函数,并且在每个UI构造器或者page_load中都有unit testing调用来testing每​​个业务function。 为了提高可读性,您可以在业务function上应用#region标签。

为了您的长期利益,您应该研究devise模式。 select适合您的项目需求的模式,并使用devise模式重做您的项目。

这取决于你使用的语言。 但总的来说,从一个简单的testing类开始,使用一些组成数据(但仍然是“真实的”)来testing你的代码。 让它模拟在应用程序中会发生什么。 如果您在应用程序的特定部分进行更改,请在更改代码之前编写一些可用的内容。 现在,由于您已经编写了testing代码,所以在尝试testing整个应用程序时将会遇到相当大的挑战。 我build议从小开始。 但是现在当你编写代码时,首先编写unit testing,然后编写你的代码。 你可能也在考虑重构,但是在你一路进行unit testing的时候,我会重构重构与重写的成本。

我还没有尝试为遗留应用程序添加testing,因为这确实是一件非常困难的事情。 如果您打算将某些业务逻辑从UI中分离出来,并且在一个单独的层中,您可以在这里添加您的初始testing单元(重构和TDD)。 这样做会给你一个介绍,为你的系统创buildunit testing。 这真的是很多工作,但我想这是最好的开始。 由于它是一个数据库驱动的应用程序,我build议您在创buildtesting时使用一些模拟工具和DBunit工具来模拟数据库相关的问题。

开始unit testing没有比尝试更好的方法 – 它不需要很长时间,这很有趣和令人上瘾。 但是,只有当你在testing代码的工作

然而,如果你尝试通过修复一个你所描述的应用程序来学习unit testing,你可能会感到沮丧和灰心 – 而且你很可能会认为unit testing是浪费时间。

我build议下载一个unit testing框架,比如NUnit或者XUnit.Net 。 大多数这些框架都提供了在线文档,提供了一个简单的介绍,如NUnit快速入门 。 阅读一下,然后select一个简单的,自包含的类:

  • 对其他类几乎没有依赖关系 – 至less不在复杂的类上。
  • 有一些行为:一个简单的容器与一堆属性不会真正显示你很多关于unit testing。

尝试编写一些testing来获得对该类的良好覆盖,然后编译并运行testing。

一旦你了解了这一点,开始寻找重构现有代码的机会,尤其是在添加新function或修复错误时。 当这些重构导致符合上述标准的类时,请为它们写一些testing。 一旦你习惯了, 你可以开始写testing 。