这个问题或多或少与编程语言无关.然而,由于我现在主要使用Java,所以我将从中绘制示例.我也在考虑OOP的情况,所以如果你想测试一个方法,你需要一个该方法类的实例.
一个核心规则的单元测试是,他们应该是自主的,并且可以通过从它的依赖隔离一个类来实现.有几种方法可以做到这一点,这取决于你是否使用IoC注入依赖项(在Java世界中我们有Spring,EJB3和其他提供注入功能的框架/平台)和/或如果你模拟对象(对于Java你有JMock和EasyMock)将正在测试的类与其依赖项分开.
如果我们需要测试不同类中的方法组*并看到它们是很好的集成,我们编写集成测试.这是我的问题!
至少在Web应用程序中,状态通常持久存储在数据库中.我们可以使用与单元测试相同的工具来实现与数据库的独立性.但在我看来,我认为有些情况下,不使用数据库进行集成测试会嘲笑太多(但是可以随意反对;根本不使用数据库,这也是一个有效的答案,因为它使问题变得无关紧要).
当您使用数据库进行集成测试时,如何使用数据填充该数据库?我可以看到两种方法:
存储数据库内容以进行集成测试,并在开始测试之前加载它.如果它存储为SQL转储,那么数据库文件,XML或其他东西将会很有趣.
通过API调用创建必要的数据库结构.这些调用可能在您的测试代码中分成几个方法,并且每个方法都可能失败.它可以被视为您的集成测试,依赖于其他测试.
当您需要时,如何确保测试所需的数据库数据?你为什么选择你选择的方法?
请提供一个动机的答案,因为这是有趣的部分所在的动机.请记住,只是说"这是最好的做法!" 这不是一个真正的动机,它只是重复你从别人那里读过或听过的东西.对于这种情况,请解释为什么这是最佳做法.
*我在单元测试的定义中包含一个在同一个类的(相同或其他)实例中调用其他方法的方法,即使它在技术上可能不正确.请随意纠正我,但让我们把它作为一个侧面问题.
我更喜欢使用API调用创建测试数据.
在测试开始时,您将创建一个空数据库(内存中或生产中使用的相同),运行安装脚本以初始化它,然后创建数据库使用的任何测试数据.可以例如利用对象母模式来组织测试数据的创建,使得可以在许多测试中重用相同的数据,可能具有微小的变化.
您希望在每次测试之前使数据库处于已知状态,以便具有可重复的测试而没有副作用.因此,当测试结束时,您应该删除测试数据库或回滚事务,以便下一个测试可以始终以相同的方式重新创建测试数据,无论先前的测试是通过还是失败.
我之所以要避免导入数据库转储(或类似),是因为它会将测试数据与数据库模式耦合在一起.当数据库架构发生更改时,您还需要更改或重新创建测试数据,这可能需要手动操作.
如果在代码中指定了测试数据,那么您将掌握IDE的重构工具的强大功能.当您进行影响数据库架构的更改时,它可能也会影响API调用,因此您无论如何都需要使用API重构代码.通过几乎相同的工作,您还可以重构测试数据的创建 - 特别是如果重构可以自动化(重命名,引入参数等).但是,如果测试依赖于数据库转储,除了重构使用API的代码之外,还需要手动重构数据库转储.
与集成测试数据库相关的另一件事是测试从先前的数据库模式升级是否正常.为此,您可能需要阅读" 重构数据库:进化数据库设计 "一书或本文:http://martinfowler.com/articles/evodb.html
在集成测试中,您需要使用真实数据库进行测试,因为您必须验证您的应用程序是否可以实际与数据库通信.将数据库隔离为依赖关系意味着您推迟了对数据库是否已正确部署的真实测试,您的架构是否符合预期,并且您的应用程序配置了正确的连接字符串.部署到生产环境时,您不希望发现这些问题.
您还希望使用预先创建的数据集和空数据集进行测试.您需要使用仅包含默认初始数据的空数据库测试应用程序启动的路径,并开始创建和填充数据,还需要定义明确定义的数据集,这些数据集针对您要测试的特定条件,如压力,性能和等等.
另外,在每个州之前,让您拥有一个众所周知的数据库.您不希望在集成测试之间存在依赖关系.