|
|
1
55
我更喜欢使用API调用来创建测试数据。 在测试开始时,您创建一个空数据库(内存中或生产中使用的数据库),运行安装脚本对其进行初始化,然后创建数据库使用的任何测试数据。测试数据的创建可以通过以下方式组织 Object Mother 模式,以便在许多测试中可以重用相同的数据,可能会有微小的变化。 您希望在每次测试之前使数据库处于已知状态,以便进行可重复的测试而没有副作用。因此,当测试结束时,您应该删除测试数据库或回滚事务,以便下一个测试可以始终以相同的方式重新创建测试数据,而不管之前的测试是通过还是失败。 我之所以避免导入数据库转储(或类似转储),是因为它将测试数据与数据库模式耦合。当数据库模式更改时,您还需要更改或重新创建测试数据,这可能需要手动操作。 如果测试数据是在代码中指定的,那么您将拥有IDE重构工具的强大功能。当您做出影响数据库模式的更改时,它可能也会影响API调用,因此您无论如何都需要使用API重构代码。通过几乎相同的努力,您还可以重构测试数据的创建,特别是如果重构可以自动化(重命名、引入参数等)。但是,如果测试依赖于数据库转储,那么除了重构使用API的代码之外,还需要手动重构数据库转储。 与数据库集成测试相关的另一件事是测试从以前的数据库模式升级是否正常。为此,你可能想读这本书 Refactoring Databases: Evolutionary Database Design 或者这篇文章: http://martinfowler.com/articles/evodb.html |
|
|
2
6
为什么这两种方法被定义为排他性的?
在现代 agile approaches ,单元测试是真正重要的地方,每次运行相同的测试。这是因为单元测试的目的不是发现bug,而是在开发过程中保留应用程序的功能,允许开发人员根据需要进行重构。 另一方面,集成测试旨在发现您没有预料到的错误。跑步 一些 在我看来,每次不同的数据甚至可能是好的。如果你失败了,你只需要确保你的测试保留了失败的数据。记住,在正式的集成测试中,除了bug修复外,应用程序本身将被冻结,因此您的测试可以更改为测试最大可能数量和种类的bug。在集成中,你可以而且应该把厨房水槽扔到应用程序上。 当然,正如其他人所指出的那样,所有这些自然取决于你正在开发的应用程序的类型和你所在的组织的类型等。 |
|
|
3
5
在集成测试中,您需要使用真实的数据库进行测试,因为您必须验证您的应用程序是否真的可以与数据库通信。将数据库隔离为依赖关系意味着您推迟了对数据库是否正确部署、架构是否符合预期以及应用程序是否配置了正确连接字符串的真正测试。您不希望在部署到生产环境时发现这些问题。 您还希望使用预创建的数据集和空数据集进行测试。你需要测试两条路径,即你的应用程序从一个只有默认初始数据的空数据库开始,开始创建和填充数据,以及一个针对你想要测试的特定条件(如压力、性能等)的定义良好的数据集。 此外,在每个状态之前,确保数据库处于已知状态。您不希望集成测试之间存在依赖关系。 |
|
|
4
4
听起来你的问题实际上是两个问题。您是否应该将数据库排除在测试之外?当你创建数据库时,你应该如何在数据库中生成数据? 如果可能的话,我更喜欢使用实际的数据库。CRUD类中的查询(用SQL、HQL等编写)在面对实际数据库时经常会返回令人惊讶的结果。最好尽早解决这些问题。开发人员通常会为CRUD编写非常精简的单元测试;只检测最良性的病例。使用实际的数据库进行测试可以测试您可能甚至没有意识到的各种极端情况。 话虽如此,可能还有其他问题。每次测试后,您都希望将数据库恢复到已知状态。我目前的工作是通过执行所有DROP语句,然后从头开始完全重新创建所有表来对数据库进行核处理。这在Oracle上非常慢,但如果你使用像HSQLDB这样的内存数据库,速度可能会非常快。当我们需要解决Oracle特定的问题时,我们只需更改数据库URL和驱动程序属性,然后针对Oracle运行。如果你没有这种数据库可移植性,那么Oracle也有某种数据库快照功能,可以专门用于此目的;将整个数据库回滚到某个先前状态。我肯定其他数据库都有。 根据数据库中的数据类型,API或加载方法可能会更好或更糟。当您拥有具有许多关系的高度结构化数据时,API将通过明确数据之间的关系使您的生活更轻松。在创建测试数据集时,您将更难出错。正如其他海报所提到的,重构工具可以自动处理数据结构的一些变化。我经常发现将API生成的测试数据视为构成场景是有用的;当用户/系统完成步骤X、Y和Z后,测试将从那里开始。这些状态可以实现,因为您可以编写一个程序来调用用户将使用的相同API。 当您需要大量数据时,加载数据变得更加重要,您的数据中几乎没有关系,或者数据中存在无法使用API或标准关系机制表示的一致性。在我团队的一份工作中,我正在为一个大型网络数据包检测系统编写报告应用程序。当时的数据量相当大。为了触发有用的测试用例子集,我们确实需要嗅探器生成的测试数据。这样,关于一个协议的信息之间的相关性将与关于另一协议的信息相关联。很难在API中捕捉到这一点。 大多数数据库都有导入和导出表的分隔文本文件的工具。但通常你只想要其中的子集;使得使用数据转储变得更加复杂。在我目前的工作中,我们需要对Matlab程序生成并存储在数据库中的实际数据进行转储。我们有一个工具,可以转储数据库数据的一个子集,然后将其和“地面实况”进行比较以进行测试。我们的提取工具似乎在不断地被修改。 |
|
|
5
4
我用过 DBUnit 对数据库中的记录进行快照并以XML格式存储。然后,我的单元测试(当它们需要数据库时,我们称之为集成测试)可以在每次测试开始时从XML文件中擦除和恢复。 我不确定这是否值得付出努力。一个问题是对其他表的依赖性。我们保留了静态引用表,并构建了一些工具来检测和提取所有子表以及请求的记录。我读到有人建议禁用集成测试数据库中的所有外键。这将使准备数据变得更加容易,但您不再检查测试中的任何引用完整性问题。 另一个问题是数据库模式更改。我们编写了一些工具,可以为拍摄快照后添加的列添加默认值。 显然,这些测试 慢一点 而不是纯粹的单元测试。 当你试图测试一些很难为单个类编写单元测试的遗留代码时,这种方法可能是值得的。 |
|
|
6
3
我两者都做,具体取决于我需要测试的内容:
当然,这条规则也有例外:
|
|
|
7
2
我通常使用SQL脚本来填充您讨论的场景中的数据。 它很简单,很容易重复。 |
|
|
8
0
这可能不会回答你所有的问题(如果有的话),但我在一个项目中决定对数据库进行单元测试。就我而言,我觉得数据库结构也需要测试,即我的数据库设计是否提供了应用程序所需的东西。在项目后期,当我觉得DB结构稳定时,我可能会放弃这个。 为了生成数据,我决定创建一个外部应用程序,用“随机”数据填充数据库,我创建了一个人名和公司名生成器等。 在外部程序中这样做的原因是: 1.我可以对逐个测试修改的数据重新运行测试,即确保我的测试能够运行多次,并且测试所做的数据修改是有效的修改。 2.如果需要,我可以清理数据库,重新开始。 我同意这种方法存在一些失败之处,但在我的情况下,由于例如人员生成是业务逻辑的一部分,因此为测试生成数据实际上也在测试该部分。 |
|
|
9
0
我们的团队最近也遇到了同样的问题。 以前,我们使用specflow进行集成测试。使用specflow,QA可以编写每个测试用例,在其中向DB填充必要的测试数据。 现在,QA想要使用poster来测试API,他们如何填充数据?一种解决方案是创建Api来填充它们。另一种方法是将Prod的历史数据同步到测试环境。 一旦我们尝试了不同的解决方案并决定采用哪种解决方案,我将更新我的答案。 |
|
|
Ricky Mo · 角度测试如何模拟导入的const 2 年前 |
|
|
Robert · 如何模拟Perl的unlink函数? 2 年前 |
|
|
Ivan · 模拟没有按预期工作(Django) 2 年前 |
|
|
Erfan Sabouri · 在laravel中测试多存储 2 年前 |