我的公司正在将Cucumber BDD 测试框架用于中等规模的 RAILS 应用程序。
它很慢。狗慢。仅我正在处理的单个黄瓜需要 30 到 40 秒才能运行,并且有几十个不同的测试文件。运行整个过程大约需要一个多小时。
稍微研究一下,有大量重复的数据库工作,但总数据量很小。例如,我看到缓慢的陈述,例如:
Given I have all the discussion threads for "fake user 47"
这需要 1000 多毫秒。它唯一要做的就是从磁盘上的文件中取出几十行库存夹具数据,然后一次将一行加载到数据库中。这不是一个巨大的数据量,最多几个 KiB。但是一旦你把 ActiveRecord 处理的所有开销加起来,并将其转换为几十条 SQL 语句,然后同步执行跨进程 IPC 到 mysql 以执行所述语句......好吧,它似乎加起来了。
Mysql 本身不是这里的问题,切换到内存表 / 等对测试的运行时间几乎没有影响。黄瓜进程以大约 70% 的 CPU 利用率运行。
然而,访问数据库仍然是一项相当昂贵的操作,因为它是一个跨进程请求,必须经过多层适配器、数据驱动程序和封送处理等等,更不用说每个请求 2 次以上的上下文切换。
所以我的理论是,如果我们只是将数据存储在一个简单的哈希表中,那么测试会运行得更快。(查找如何在 Ruby 中进行分析,以便我可以证明这个理论)。
是否可以使用已填充的进程内“模拟”数据库层来运行我们的测试套件?理想情况下,一些超级轻量级的东西,理想情况下甚至根本不需要处理 SQL,只需实现 ActiveRecord 期望的任何合同。
此外,我们似乎多次执行相同的设置。一项测试会说“鉴于我有数据 X”并花费很长时间加载数据 X 以进行一些检查。然后另一个测试会说“鉴于我有数据 Y”,清除数据库,花费很长时间加载数据 Y,并进行一些检查。然后第三个测试说“给定我有数据 X”,清除数据库,并再次花费很长时间重新加载 X。当然,第四个测试可能再次使用数据 Y....
是否有一种干净的模式可以跨场景重用测试初始化代码?或者缓存一个特定的初始化状态?