Tester une application de ligne de commande avec Cucumber / Aruba / TimeCop: comment injecter le contexte
-
14-11-2019 - |
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
La solution
Je vois 2 options ici.
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à.
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 pourriezinstance_eval "puts Time.now"
. Plus réaliste, vous pourriezrequire
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 duputs
Méthode, et justerequire
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