(Posted already at https://www.ruby-forum.com/topic/6876320, but crossposted here, because I did not receive a response so far).
A question about parallelizing tests in Minitest and/or Test::Unit (i.e. proper use of parallelize_me!):
Assume that I have some helper methods, which are needed by several tests. From my understanding, I could NOT do something like this in such a method (simplified example):
def prep(m,n)
@pid = m
@state = n
end
def process
if @stat > 5 && @pid != 0
...
else
...
end
end
I think I can't do this in Minitest and test-unit, because if I call prep and process from several of my test function, the tests can not be parallelized anymore - those test functions all set and read the same instance variable. Right?
Now, my question is, whether the following approach would be safe for parallelization: I make all of these mutable instance variables a hash, which I initialized in setup like this:
def setup
@pid ||= {}
@state ||= {}
end
My "helper methods" receive a key (for example, the name of the test method) and use it to access the their "own" hash element:
def prep(key,m,n)
@pid[key] = m
@state[key] = n
end
def process
if @stat[key] > 5 && @pid[key] != 0
...
else
...
end
end
It's a bit ugly, but: Is this a reliable approach? Is this way of accessing a hash thread-safe? How can I do it better?
In the Ruby programming language, an instance variable is a type of variable which starts with an @ symbol. An instance variable is used as part of Object-Oriented Programming (OOP) to give objects their own private space to store data.
The instance variables of an object can only be accessed by the instance methods of that object. The ruby instance variables do not need a declaration. This implies a flexible object structure. Every instance variable is dynamically appended to an object when it is first referenced.
Used declare variables within a class. There are two main types: class variables, which have the same value across all class instances (i.e. static variables), and instance variables, which have different values for each object instance.
Instance variables can be accessed directly by calling the variable name inside the class. However, within static methods (when instance variables are given accessibility), they should be called using the fully qualified name.
At least in Minitest you can safely do, for example,
setup do
@form = Form.new
end
without @form
getting mixed up between parallel tests, so this approach should be safe too:
def setup
@stat = m
@pid = n
end
which means that your original approach should be safe as well.
================
UPDATE
consider the following gist with a piece of code that define 100 different tests accessing @random
which is set in setup
https://gist.github.com/bbozo/2a64e1f53d29747ca559
You will notice that the stuff set in setup
isn't shared among tests, it is run before every test, basically every test is encapsulated so thread safety isn't an issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With