Ruby:Minitest、测试单元和实例变量

Ruby: Minitest, test-unit and instance variables

(已在 https://www.ruby-forum.com/topic/6876320 发布,但在这里交叉发布,因为到目前为止我还没有收到回复)。

关于 Minitest 中并行化测试的问题 and/or Test::Unit(即 parallelize_me 的正确使用!):

假设我有一些辅助方法,几个测试都需要这些方法。据我了解,我不能用这种方法做这样的事情(简化示例):

def prep(m,n)
 @pid = m
 @state = n
end

def process
 if @stat > 5 && @pid != 0
   ...
 else
   ...
 end
end

我想我不能在 Minitest 和测试单元中这样做,因为如果我从我的几个测试函数调用准备和处理,测试就不能再并行化了——那些测试函数都设置并读取了相同的实例变量。对吗?

现在,我的问题是,以下方法对于并行化是否安全:我将所有这些可变实例变量设为一个散列,我在设置中对其进行了初始化,如下所示:

def setup
  @pid ||= {}
  @state ||= {}
end

我的 "helper methods" 收到一个密钥(例如,测试名称 方法)并使用它来访问它们的 "own" 散列元素:

def prep(key,m,n)
 @pid[key] = m
 @state[key] = n
end

def process
 if @stat[key] > 5 && @pid[key] != 0
   ...
 else
   ...
 end
end

有点难看,但是:这是一种可靠的方法吗?这种访问哈希线程安全的方式吗?我怎样才能做得更好?

您使用散列的方法很有意义,可以区分线程。问题出在全局解释器锁上。

除非您的辅助方法是 IO 绑定的(发出 HTTP 请求、套接字请求、处理本地文件),否则您不会看到速度提升,因为 Ruby 几乎可以(简化事情)运行 您的代码在多个线程上按顺序执行,没有保证 运行 顺序。

祝你好运!

至少在 Minitest 中你可以安全地做,例如,

setup do
  @form = Form.new
end

没有@form在并行测试之间混淆,所以这种方法也应该是安全的:

def setup
  @stat = m
  @pid = n
end

这意味着您原来的方法也应该是安全的。

================

更新

考虑以下要点和一段代码,这些代码定义了 100 个不同的测试访问 @random,它在 setup https://gist.github.com/bbozo/2a64e1f53d29747ca559

中设置

你会注意到 setup 中设置的东西不在测试之间共享,它是 运行 在每个测试之前,基本上每个测试都是封装的,所以线程安全不是问题。