Это определенно сложная проблема. Я начал писать свой тест, используя потоки, и понял, что они реализуют код, который я тестировал, и мне нужно, чтобы идентификаторы процессов (PID) действительно отличались. Потоки запускаются с использованием того же PID, что и процесс, запускающий поток. Урок выучен.
Именно в этот момент я начал изучать вилки, наткнулся на этот поток переполнения стека и поиграл с fork_break. Довольно круто и легко настраивается. Хотя мне не нужны были точки останова для того, что я делал, я просто хотел, чтобы процессы проходили одновременно, использование точек останова могло бы быть очень полезным в будущем. Проблема, с которой я столкнулся, заключалась в том, что я продолжал получать EOFError, и я не знал почему. Поэтому я начал реализовывать разветвление самостоятельно, вместо того чтобы проходить через fork_break, и обнаружил, что в тестируемом коде происходит исключение. Грустно, что трассировка стека была скрыта от меня EOFError, хотя я понимаю, что дочерний процесс завершился внезапно, и так оно и происходит.
Следующая проблема, с которой я столкнулся, была с DatabaseCleaner. Независимо от того, какую стратегию он использовал (усечение или транзакция), данные дочернего процесса усекались / откатывались по завершении дочернего процесса, поэтому данные, вставленные дочерними процессами, исчезали, и родительский процесс не мог выбрать и проверить, что это было правильно.
После того, как я покачал головой и попробовал много других неудачных вещей, я наткнулся на этот пост http://makandracards.com/makandra/556-test-concurrent-ruby-code, который был почти точно тем, что я уже делал, с одним небольшим дополнением. Вызов "Process.exit!" в конце вилки. Мое лучшее предположение (основанное на моем довольно ограниченном понимании разветвления) заключается в том, что это приводит к тому, что процесс завершается достаточно быстро, чтобы полностью обойти любой тип очистки базы данных после завершения дочернего процесса. Таким образом, мой родительский процесс, настоящий тест, может продолжаться и проверять данные, необходимые для проверки. Затем во время обычного перехвата теста (в данном случае огурца, но также легко можно использовать rspec) очиститель базы данных запускает и очищает данные, как обычно для теста.
Итак, я подумал, что поделюсь некоторыми из моих собственных уроков, полученных в этом обсуждении о том, как тестировать параллельные функции.