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
中设置的东西不在测试之间共享,它是 运行 在每个测试之前,基本上每个测试都是封装的,所以线程安全不是问题。
(已在 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
中设置的东西不在测试之间共享,它是 运行 在每个测试之前,基本上每个测试都是封装的,所以线程安全不是问题。