RSpec testing work with files: Errno::EACCES
-
29-06-2021 - |
题
I'm currently issuing a problem with running tests with rspec. All the test files (*_spec.rb) may run successfully. In same rare cases an error -- Errno::EACCES
may appear and one of the tests may fail. E.g:
All the test in the file *_spec.rb
run:
- Successfully.
- Successfully.
- One the test had failed.
- Successfully.
- One the test had failed (not the same as in #3).
- etc.
The exception raises from the lines like:
FileUtils.mv
FileUtils.mkdir_p
FileUtils.rm_r
All of those list work with files or directories and are used many times in tests. I.e.:
create folder(with subfolders, with files, etc.), rename folder, test something, delete.. and so on.
It looks like the problem is hidden somewhere in "timing"(if something is not done yet and another action tries to access that something). That mind comes from:
begin
FileUtils.mv(a, b) # if an `Errno:EACCESS` was raised here
rescue #
FileUtils.mv(a, b) # it wouldn't be raised now
end
The question is:
How can it be fixed? (i mean Errno:EACCESS
which is reproduced rarely and some tests)
- Adding
sleep
after every operation with files is not acceptable nevertheless it will help. - ruby's methods (
FileUtils.(mv|rm_r|mkdir_p)
) may be modified to retry once onErrno::EACCES
but is this the best solution?
P.S.
Sorry for my English and feel free to ask any question as i've tried to explain as brief as i could. Thanks in advanced, at least for you've read this to the end;
解决方案
Look for the root cause, don't succumb to workarounds you mentioned.
First make sure you're using before
and after
for setting up and tearing down file fixtures. If you code your setup and teardown procedures in the spec itself you run a risk of it not running when the test fails.
Second, make sure your setup & teardown procedures create different files and directories for each test. If all you're doing is reading it's ok to use shared fixtures, but for all other things (moving, creation, appending, deletion) use a fresh file/directory. The best thing to do is to use freshly generated temporary files and directories. It will make your tests independent, even allowing to run them in parallel.
Third, check what other processes may use files created/used by your tests. I don't know your setup, and it all depends on that, but possible things are web servers, browsers (e.g. via selenium), mail servers, etc. Simply check what other processes are you running as a part of your build.