用于RAILS/ActiveRecord的Cucumber BDD-通过填充数据库层来加速慢速测试



我的公司正在为一个中等规模的RAILS应用程序使用Cucumber BDD测试框架。

它很慢。狗慢慢来。我正在处理的每一个黄瓜都需要30到40秒的时间才能运行,而且有几十个不同的测试文件。整个过程大概需要一个多小时。

仔细观察一下,有大量重复的数据库工作,但总数据量非常小。例如,我看到诸如之类的慢速语句

Given I have all the discussion threads for "fake user 47"

这需要1000多毫秒。它所做的唯一一件事就是从磁盘上的一个文件中提取几十行库存夹具数据,并一次一行地将其加载到数据库中。这不是一个庞大的数据量,最多只有几个KiB。但是,一旦你把ActiveRecord处理的所有开销加起来,并将其转换为几十条SQL语句,然后同步地进行跨进程IPC到mysql来执行所述语句。。。好吧,这似乎加起来了。

Mysql本身并不是问题所在,切换到内存表等对测试的运行时间几乎没有影响。黄瓜进程的CPU利用率约为70%。

然而,访问数据库仍然是一项相当昂贵的操作,因为它是一个跨进程的请求,必须经过多层适配器、数据驱动程序和封送处理等等,更不用说每个请求2个以上的上下文切换了。

因此,我的理论是,如果我们只是将数据存储在一个简单的哈希表中,那么测试会运行得更快。(查找如何在Ruby中进行评测,以便证明这一理论)。

是否可以使用填充的进程中"模拟"数据库层来运行我们的测试套件?理想情况下,一些超轻量级的东西甚至根本不需要处理SQL,只需实现ActiveRecord所期望的任何契约

此外,我们似乎多次进行相同的设置。一个测试会说"假设我有数据X",并花费很长时间加载数据X来进行一些检查。然后另一个测试会说"如果我有数据Y",清除数据库,花很长时间加载数据Y,并进行一些检查。然后,第三个测试说"给定我有数据X",清除数据库,并花费很长时间重新加载X。当然,第四个测试可能再次使用数据Y。。。。

是否有一个干净的模式来跨场景重用测试初始化代码?或者缓存特定的初始化状态

这可能不是您问题的完整答案。但至于问题的最后一部分,你可以使用黄瓜全局挂钩。由于这是集成测试,我建议您根据实际情况填充数据库。因此,在使用黄瓜挂钩进行所有测试之前,只要合适,就可以填充数据X和数据Y。如果仔细规划,所花费的时间可能会得到很大程度的优化。

最新更新