如何在测试中用模拟可执行文件替换可执行文件?

时间:2010-01-28 03:45:47

标签: ruby multithreading testing

我是否可以使用可执行文件替换可执行文件(通过来自ruby的system调用访问),该可执行文件需要某些输入并在一致的时间内提供预期的输出?我主要在Mac OSX 10.6(Snow Leopard)上运行,但我也可以访问Linux和Windows。我正在使用MRI红宝石1.8.7。

背景:我正在寻找几个DNA序列比对,每个线程一个。当我尝试使用BioRuby时,无论是BioRuby还是ruby的标准库的临时文件sometimes都会提升exceptions(这比默默地失败更好!)。

我设置了test来重现问题,但只有部分时间。我假设测试之间的主要变化来源是线程,临时文件系统和用于对齐的可执行文件(ClustalW)。由于ClustalW可能没有发生故障,但可能是变异的来源,我认为消除它可能有助于重复性。

对于那些思考select isn't broken的人 - 这也是我想知道的。然而,according to the changelog,2009年8月对tempfile的线程安全性存在担忧。此外,我已经检查了BioRuby邮件列表是否正确调用了BioRuby代码,而且情况确实如此。

3 个答案:

答案 0 :(得分:1)

我真的不明白问题是什么,或者你到底是什么,你不能只写一些像

#!/bin/sh
#Test for input (syntax might be wrong, but you get the idea)
if [ $* ne "expected input" ]; then
    echo "expected output for failure"
    exit -1
fi
#have it work in a consistent amount of time 
$CONSISTENT_AMOUNT_OF_TIME = 20
sleep $CONSISTENT_AMOUNT_OF_TIME
echo "expected output"

答案 1 :(得分:1)

你可以。在我正在为程序A编写功能测试的情况下,我可能需要“模拟”程序B,即A通过系统运行。我所做的是使程序B的路径名可配置,默认值为:

class ProgramA

  def initialize(argv)
    @args = ParseArgs(argv)
    @config = Config.new(@args.config_path || default_config_path)
  end

  def run
    command = [
      program_b_path,
      '--verbose',
      '--do_something_wonderful',
    ].join(' ')
    system(command)
    ...
  end

  def program_a_path
    @config.fetch('program_b_path', default_program_b_path)
  end

end

程序A接受一个开关“--config PATH”,它可以覆盖默认的配置文件路径。该测试在/ tmp:

中设置配置文件
program_b_path: /home/wayne/project/tests/mock_program_b.rb

并传递给程序A该配置文件:

program_a.rb --config /tmp/config.yaml

现在程序A不会运行真正的程序B,而是运行模拟程序。

答案 2 :(得分:0)

你尝试过摩卡宝石吗?它用于测试,你完美地描述它。它“伪造”对象的方法调用(其中包含ruby中的任何内容),并返回所需的结果而不实际运行该方法。以此示例文件:

# test.rb
require 'rubygems'
require 'mocha'

self.stubs(:system).with('ls').returns('monkey')

puts system('ls')

运行此脚本会输出“monkey”,因为我删除了系统调用。您可以使用它来绕过您不想测试的应用程序的某些部分,以分解出不相关的部分。