17

有没有人有一些很好的提示来为严重依赖状态的数据库后端开发编写测试代码?

具体来说,我想为从数据库中检索记录的代码编写测试,但答案将取决于数据库中的数据(可能会随着时间而改变)。

人们是否通常使用“冻结”数据库创建一个单独的开发系统,以便任何给定的函数都应该始终返回完全相同的结果集?

我很确定这不是一个新问题,所以我很想学习其他人的经验。

有没有很好的文章来讨论这个基于 Web 的开发问题?

我通常编写 PHP 代码,但我希望所有这些问题在很大程度上与语言和框架无关。

4

10 回答 10

6

您应该查看 DBUnit,或尝试找到一个 PHP 等效项(必须有一个)。您可以使用它来准备具有代表您的测试数据的特定数据集的数据库,因此每个测试将不再依赖于数据库和某些现有状态。这样,每个测试都是独立的,不会在进一步使用数据库时中断。

更新:快速谷歌搜索显示 PHPUnit 的数据库单元扩展

于 2008-08-05T22:03:29.750 回答
3

如果您最关心数据层测试,您可能需要查看这本书: xUnit 测试模式:重构测试代码。我自己一直对此不确定,但这本书很好地帮助列举了性能、可重复性等问题。

于 2008-08-06T04:14:42.433 回答
2

我想这取决于您使用的数据库,但 Red Gate (www.red-gate.com) 制作了一个名为 SQL 数据生成器的工具。这可以配置为用看起来合理的测试数据填充您的数据库。您还可以告诉它在其随机数生成器中始终使用相同的种子,这样您的“随机”数据每次都是相同的。

然后,您可以编写单元测试来利用这些可靠、可重复的数据。

至于测试网络方面的事情,我目前正在研究 Selenium (selenium.openqa.org)。这似乎是一个支持跨浏览器的测试套件,可以帮助您测试功能。然而,与所有这些网站测试工具一样,没有真正的方法可以测试这些东西在所有浏览器中的外观而不用人眼观察它们!

于 2008-08-06T13:44:48.443 回答
2

We use an in-memory database (hsql : http://hsqldb.org/). Hibernate (http://www.hibernate.org/) makes it easy for us to point our unit tests at the testing db, with the added bonus that they run as quick as lightning..

于 2008-09-10T12:02:14.610 回答
1

我的工作也有同样的问题,我发现最好的办法是用一个 PHP 脚本重新创建数据库,然后用一个单独的脚本向它抛出疯狂的数据,看看它是否会破坏它。

我从未使用过任何单元测试或类似的东西,所以不能说它是否有效。

于 2008-08-05T22:03:33.260 回答
1

如果您可以在运行测试之前使用已知数量设置数据库并在最后拆除,那么您将知道您正在使用哪些数据。

然后,您可以使用 Selenium 之类的东西轻松地从您的 UI 进行测试(假设这里是基于 Web 的,但是有很多用于其他 UI 风格的 UI 测试工具)并检测从数据库中提取的某些记录的存在。

绝对值得设置数据库的测试版本 - 或者让您的测试脚本使用已知数据填充数据库作为测试的一部分。

于 2008-08-05T22:08:11.050 回答
1

您可以尝试http://selenium.openqa.org/它更多地用于 GUI 测试而不是数据层测试应用程序,但确实记录了您的操作,然后可以回放这些操作以跨不同平台进行自动化测试。

于 2008-08-06T12:06:28.597 回答
1

这是我的策略(我使用 JUnit,但我确信有一种方法可以在 PHP 中进行等效操作):

我有一个在特定 DAO 类的所有单元测试之前运行的方法。它将开发数据库置于已知状态(添加所有测试数据等)。当我运行测试时,我会跟踪添加到已知状态的任何数据。每次测试结束时都会清理此数据。在该类的所有测试都运行之后,另一个方法会删除 dev 数据库中的所有测试数据,使其保持在运行测试之前的状态。完成这一切需要一些工作,但我通常在 DBTestCommon 类中编写方法,我的所有 DAO 测试类都可以访问它们。

于 2008-08-11T13:30:32.457 回答
1

我建议使用三个数据库。一个生产数据库,一个开发数据库(为每个开发人员填充了一些有意义的数据)和一个测试数据库(带有空表和可能总是需要的几行)。

测试数据库代码的一种方法是:

  1. 插入几行(使用 SQL)来初始化状态
  2. 运行要测试的函数
  3. 将预期结果与实际结果进行比较。在这里您可以使用正常的单元测试框架
  4. 清理已更改的行(因此下一次运行不会看到上一次运行)

可以使用标准方式(当然,仅在测试数据库中)使用DELETE * FROM table.

于 2008-08-19T18:40:33.063 回答
1

一般来说,我同意 Peter 的观点,但对于创建和删除测试数据,我不会直接使用 SQL。我更喜欢使用产品中使用的一些 CRUD API 来创建尽可能类似于生产的数据......

于 2008-09-10T11:31:15.260 回答