тестирование многопоточного кода в ruby - PullRequest
4 голосов
/ 22 октября 2009

Я пишу клон delayed_job для DataMapper. У меня есть то, что я думаю, работает и протестировал код, за исключением потока в рабочем процессе. Я посмотрел на delayed_job как это проверить, но сейчас есть тесты для этой части кода. Ниже приведен код, который мне нужно проверить. идеи? (Я использую rspec BTW)

def start
  say "*** Starting job worker #{@name}"
  t = Thread.new do
    loop do
      delay = Update.work_off(self) #this method well tested
      break if $exit
      sleep delay
      break if $exit
    end
    clear_locks
  end

  trap('TERM') { terminate_with t }
  trap('INT')  { terminate_with t }

  trap('USR1') do
    say "Wakeup Signal Caught"
    t.run
  end

см. Также эту тему

Ответы [ 4 ]

9 голосов
/ 24 февраля 2015

Лучший подход, я считаю, состоит в том, чтобы заглушить метод Thread.new и убедиться, что любой «сложный» материал находится в своем собственном методе, который можно проверить индивидуально. Таким образом у вас будет что-то вроде этого:

class Foo
    def start
        Thread.new do
            do_something
        end
    end
    def do_something
        loop do
           foo.bar(bar.foo)
        end
    end
end

Тогда вы бы протестировали так:

describe Foo
    it "starts thread running do_something" do
        f = Foo.new
        expect(Thread).to receive(:new).and_yield
        expect(f).to receive(:do_something)
        f.start
    end
    it "do_something loops with and calls foo.bar with bar.foo" do
        f = Foo.new
        expect(f).to receive(:loop).and_yield #for multiple yields: receive(:loop).and_yield.and_yield.and_yield... 
        expect(foo).to receive(:bar).with(bar.foo)
        f.do_something
    end
end

Таким образом, вам не нужно так много раздувать, чтобы получить желаемый результат.

3 голосов
/ 29 июня 2010

Вы можете запустить рабочий процесс как подпроцесс при тестировании, дождаться его полного запуска, а затем проверить на нем сигналы вывода / отправки.

Я подозреваю, что вы можете получить довольно много конкретных идей для тестирования в этой области из проекта Unicorn .

0 голосов
/ 24 декабря 2014

Как насчет того, чтобы поток получился прямо в вашем тесте?

Thread.stub(:new).and_yield
start
# assertions...
0 голосов
/ 23 октября 2009

Невозможно полностью протестировать потоки. Лучшее, что вы можете сделать, это использовать насмешки.

(что-то вроде) object.should_recieve (: trap) .with ('TERM'). и yield object.start

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...