人们如何单元测试他们的业务应用程序?我已经看到很多单元测试的例子都是"简单测试"的例子.防爆.一个计算器.人们如何对数据量大的应用进行单元测试?你是如何整理样本数据的?在许多情况下,一个测试的数据可能根本不适用于另一个测试,这使得很难只拥有一个测试数据库?
测试代码的数据访问部分非常简单.它正在测试所有针对似乎难以测试的数据的方法.例如,想象一个发布过程,其中存在大量数据访问以确定发布的内容,数字被调整等.发生了许多临时步骤(并且需要进行测试)以及之后的测试以确保发布是成功的.其中一些步骤实际上可能是存储过程.
在过去,我尝试将测试数据插入测试数据库,然后运行测试,但老实说,编写这种代码非常痛苦(并且容易出错).我还尝试过预先构建测试数据库并回滚更改.这工作正常,但在许多地方你也不能轻易做到这一点(许多人会说这是集成测试;所以,我仍然需要能够以某种方式测试它).
如果答案是没有一种很好的方法来处理这个问题,而且目前只是很糟糕,那么知道也是有用的.
任何想法,想法,建议或提示都表示赞赏.
我的自动功能测试通常遵循以下两种模式中的一种:
数据库连接测试
模拟持久层测试
数据库连接测试
当我有连接到数据库的自动化测试时,我通常会创建一个测试数据库模板,该模板具有足够的数据用于所有测试.运行自动化测试时,将为每个测试从模板生成一个新的测试数据库.必须不断重新生成测试数据库,因为测试通常会更改数据.随着测试的增加,我通常会将更多数据附加到测试数据库模板中.
这种测试方法有一些很好的优点.显而易见的优点是测试还可以运用您的架构.另一个优点是,在设置初始测试后,大多数新测试将能够重用现有的测试数据.这样可以轻松添加更多测试.
缺点是测试数据库将变得难以处理.因为数据通常会在一次添加一个测试,所以它会不一致,甚至可能不切实际.当存在重大的数据库模式更改时,您最终会诅咒设置测试数据库的人(对我来说这通常意味着我最终诅咒自己).
如果您无法随意生成新的测试数据库,这种测试方式显然不起作用.
模拟持久层测试
对于此模式,您可以创建与测试用例一起使用的模拟对象.这些模拟对象拦截对数据库的调用,以便您可以以编程方式提供适当的结果.基本上,当您测试的代码调用该findCustomerByName()
方法时,将调用您的模拟对象而不是持久层.
使用模拟对象测试的好处是你可以非常具体.通常,有些执行路径在无模拟对象的自动化测试中无法实现.它们还使您无法维护大量的单片测试数据.
另一个好处是缺乏外部依赖性.因为模拟对象模拟持久层,所以测试不再依赖于数据库.在选择要选择的模式时,这通常是决定性因素.在处理具有严格许可条款的旧数据库系统或数据库时,模拟对象似乎更具吸引力.
模拟对象的缺点是它们经常导致大量额外的测试代码.这并不可怕,因为几乎任何数量的测试代码在运行测试的次数分摊时都很便宜,但是获得更多的测试代码然后生成代码会很烦人.