Tester une application de ligne de commande avec Cucumber / Aruba / TimeCop: comment injecter le contexte

StackOverflow https://stackoverflow.com/questions/9503579

Question

Le scénario suivant résume à peu près mon problème:

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"

Ça se résume à When I run ruby -e "puts Time.now" lancement d'un processus d'enfant et faisant ainsi tout mon Timecop.freeze Stubs inefficaces, car ils ne travaillent que sur le processus principal. J'ai besoin d'injecter en quelque sorte le contexte actuel dans la commande qui est exécuté, mais je semble ne pas être en mesure de trouver quoi que ce soit. Est-ce que j'essaye quelque chose d'impossible ici?


La marche:

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
Était-ce utile?

La solution

Je vois 2 options ici.

  1. Créez un crochet dans le système testé que vous pouvez utiliser pour injecter le contexte requis, dans cet exemple, vous pouvez ajouter un paramètre «Time actuel» à l'application de ligne de commande que vous testez. Alternativement, spécifiez un temps fixe dans le fichier de configuration des applications ou la base de données, il existe de nombreuses options. Cela suppose que vous possédez l'application que vous testez et que vous pouvez apporter de telles modifications. Cela n'a besoin que d'un très petit changement, par exemple, si le paramètre «l'heure actuelle» est spécifié, utilisez TimeCop pour geler l'heure à ce moment-là.

  2. Trouvez un moyen de faire passer le système sous test dans le processus de concombre. Dans votre exemple au lieu de se débarrasser de ruby -e "puts Time.now", vous pourriez instance_eval "puts Time.now". Plus réaliste, vous pourriez require L'application, et si le coureur de ligne de commande est simplement un wrapper mince autour de certaines classes qui font réellement le travail, vous pouvez les appeler directement. Alternativement, vous pourriez être en mesure de peupler les paramètres Argv attendus, se moquer du puts Méthode, et juste require Le fichier, qui devrait vous donner une expérience étroite pour l'exécuter hors du processus, mais vous pourriez utiliser TimeCop efficacement.

Autres conseils

Aruba prend également en charge une fonctionnalité appelée En exécution de processus ce qui vous permet de tout exécuter dans un seul processus. Cependant, cela vous limite à peu près exclusivement à tester Ruby CLIS avec ARUBA, car la façon dont cela fonctionne est de remplacer le comportement par défaut de bombarder une commande en appelant une méthode Ruby.

Voici à quoi cela ressemble pour moi - j'utilise Aruba pour tester une application 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top