Тестирование приложения командной строки с помощью cucumber / aruba / timecop: как вставить контекст - PullRequest
6 голосов
/ 29 февраля 2012

Следующий сценарий в значительной степени подводит итог моей проблемы:

Scenario: problems with subprocesses
  Given the date is 01/01/2012 10:31
  When I run `ruby -e "puts Time.now"`
  Then the output should contain "10:31"

Это сводится к When I run ruby -e "puts Time.now" запуску дочернего процесса и, таким образом, делает все мои Timecop.freeze заглушки неэффективными, поскольку они работают только наосновной процесс.Мне нужно как-то «вставить» текущий контекст в команду, которая запускается, но мне кажется, что я ничего не могу придумать.Я пытаюсь что-то невозможное здесь?


Шаг:

require 'timecop'
Given /^the date is (\d+)\/(\d+)\/(\d+) (\d+):(\d+)$/ do |month, day, year, hour, minute|
  Timecop.freeze(Time.local(year.to_i, month.to_i, day.to_i, hour.to_i , minute.to_i, 0))
end

Ответы [ 2 ]

1 голос
/ 07 марта 2012

Здесь я вижу 2 варианта.

  1. Создайте ловушку в тестируемой системе, которую вы можете использовать для внедрения необходимого контекста, в этом примере вы можете добавить параметр «текущее время» в тестируемое приложение командной строки. В качестве альтернативы укажите фиксированное время в конфигурационном файле приложения или базе данных, существует множество опций. Это предполагает, что у вас есть приложение, которое вы тестируете, и можете вносить такие изменения. Это должно быть только очень маленькое изменение, например если указан параметр «текущее время», используйте Timecop, чтобы зафиксировать время в это время.

  2. Найдите способ задействовать тестируемую систему в процессе Cucumber. В вашем примере вместо выстрела на ruby -e "puts Time.now" вы могли бы instance_eval "puts Time.now". Более реалистично, вы могли бы require приложить, и если бегунок командной строки - просто тонкая оболочка вокруг некоторых классов, которые фактически выполняют работу, то вы можете вызывать их напрямую. В качестве альтернативы, вы можете заполнить любые ожидаемые параметры ARGV, смоделировать метод puts и просто require файл, который должен дать вам возможность практически полностью исключить его из процесса, но вы сможете эффективно использовать Timecop.

0 голосов
/ 23 апреля 2018

Аруба также поддерживает функцию под названием при выполнении процесса , которая позволяет запускать все в одном процессе. Тем не менее, он в значительной степени ограничивает вас тестированием Ruby CLI с Aruba, так как он работает путем переопределения поведения по умолчанию для оболочки при вызове метода Ruby.

Вот как это выглядит для меня - я использую Aruba для тестирования приложения Thor:

require 'aruba/cucumber'
require 'aruba/in_process'
require 'thor'
require 'thor/runner'

load 'Thorfile'

class ThorFriendlyMain
  def initialize(argv, stdin, stdout, stderr, kernel)
    @argv, @stdin, @stdout, @stderr, @kernel = argv, stdin, stdout, stderr, kernel
  end

  def execute!
    $stdin = @stdin
    $stdout = @stdout
    $stderr = @stderr
    Thor::Runner.start(@argv)
    $stdin = STDIN
    $stdout = STDOUT
    $stderr = STDERR
  end   
end     

Aruba.config.command_launcher = :in_process
Aruba.config.main_class = ThorFriendlyMain
...