当您仅使用数据访问层或大多数应用程序堆栈进行集成测试时。如果多个测试在同一个数据库上运行,那么防止多个测试相互冲突的最佳方法是什么?
6 回答
交易。
ruby on rails 单元测试框架的作用是:
Load all fixture data.
For each test:
BEGIN TRANSACTION
# Yield control to user code
ROLLBACK TRANSACTION
End for each
这意味着
- 您的测试对数据库所做的任何更改都不会影响正在进行的其他线程
- 下一个测试的数据没有被之前的测试污染
- 这比为每个测试手动重新加载数据快了大约数十亿倍。
我个人认为这很酷
对于简单的数据库应用程序,我发现使用SQLite非常宝贵。它允许您为每个测试拥有一个独特且独立的数据库。
但是,它仅在您使用简单的通用 SQL 功能或可以轻松地将 SQLite 和您的生产数据库系统之间的细微差别隐藏在一个类后面时才有效,但我一直发现在我的 SQL 应用程序中相当容易发达。
只是为了添加到 Free Wildebeest 的答案,我还使用HSQLDB进行了类似的类型测试,其中每个测试都获得了一个干净的数据库实例。
我想同时接受 Free Wildebeest 和 Orion Edwards 的答案,但它不会让我接受。我想这样做的原因是我得出的结论是,这是两种主要的方法,但选择哪一种取决于具体情况(主要是数据库的大小)。
还要在不同的时间运行测试,这样它们就不会影响彼此的性能或有效性。
虽然在此处的其他答案中不如 Rails 单元测试框架聪明,但为每个测试或测试组创建不同的数据是另一种方法。这种解决方案的乏味程度取决于您拥有的测试用例的数量以及它们之间的依赖程度。如果每个测试或一组依赖测试都有一个数据库,那么乏味将保持不变。
运行测试套件时,您在开始时加载数据,运行测试套件,卸载/比较结果以确保实际结果符合预期结果。如果没有,请再次执行此循环。加载、运行套件、卸载/比较。