轨道unit testing是否应该打到数据库?

我一直在为我的rails应用程序编写测试。 我使用TestUnit进行unit testing和function测试。 我也使用黄瓜进行GUI测试。

但我发现http://www.dcmanges.com/blog/rails-unit-record-test-without-the-database说unit testing最好不要打到数据库。

我同意击中数据库需要相当长的时间。 我已经使用spork来减少环境负荷。

在测试rails应用程序时,最佳做法是什么?

这是你不应该对名字过于笼罩的情况之一。 Rails指的是将ActiveRecord模型作为“单元”测试运行的测试,主要是因为它们是框架直接支持的最低级别测试。 根据测试传说,我承认我倾向于相当一致,unit testing应该没有测试单元外部的依赖性; 这意味着持久性机制,即数据库。

也就是说,在没有数据库的情况下测试任何复杂的ActiveRecord模型会很快让你想吃掉你的手。 Rails假定您使用数据库进行测试; 这就是框架编写的方式。 您可以尝试将所有内容都删除,但最终会失败,因为您最终会在ActiveRecord关联的内部混乱(不适合胆小的人)。 您可以尝试将所有与非持久性相关的代码提取到不使用数据库进行测试的单独模块中,但是您将创建相当多的不必要的复杂性。

不要试图打击框架。 ActiveRecord和ActionController具有非常特定的预期用途模式,包括生产和测试。 毕竟,Rails就是关于惯例。 如果你遵循使用模式,你将会做更少的工作,并且变得更加沮丧,而不是为了坚持unit testing理想而对抗惯例。 如果它让您感觉更好,请将您的ActiveRecord测试视为“模型”测试,并将您的function测试视为“控制器”测试(这是rspec使用的术语,顺便提一下)。

总而言之,您不应在模型测试(或规范)中不必要地访问数据库。 某些validation(例如唯一性)需要数据库,但大多数validation不需要。 与创建/保存回调和关联相关的许多操作都需要数据库,但其他操作则不需要。 请注意您正在调用的操作正在执行的操作。

unit testing不应该打到数据库。 如果正确的数据可用(无论数据来自何处),他们应该测试方法是否按预期运行。 因此,您应该根据需要进行存根/模拟,以确保每个unit testing都是隔离的。

但是,集成测试(例如,您可能会使用Cucumber编写)应该将整个MVC堆栈绑定在一起,并且没有理由让那些不打算访问数据库

关于测试具有“击中数据库的unit testing”的模型的“Rails方式”的论点与说“好吧每个人都跳出桥梁,也许我应该这么做?”是相同的。

你应该仔细分析你遵循的每个Rails惯例,因为事后看来“monolothic Rails应用程序”,如果他们遵循这个建议,他们就会有100多个模型进行集成测试。 即使您使用慢速和快速标记规范,您也无法在“快速”类别中对模型进行unit testing(除非您也编写它们,在这种情况下,您可能正在测试太多)。

副作用:一个缓慢的unit testing套件需要一个小时。 并且假设你坚持模型中的每一个方法而不是将它抽象到不同的类中,你会受到更多伤害,因为你需要为它们编写集成测试。

我知道无论你做什么,集成测试仍然会很慢,但是你能够对抗缓慢的唯一方法就是巧妙地编写它们。

我正在尝试编写从HTTP请求中击中数据库的“请求规范”。 并将它们用作我的“function测试”。 我编写的每个类,无论是服务,模型还是拥有什么,都围绕他们的公共方法进行unit testing(显然存在于DB中)。

使用快速内存​​数据库进行unit testing。 如果要测试“如果正确的数据可用,则按预期运行方法”,最好使用与实际数据集非常相似的数据集。 内存数据库可以包含非常小或相当大的数据集,具体取决于您的需要。 ruby-on-rails支持HSQLDB ,通常用于unit testing。