使用ruby进行操作系统特定测试

时间:2016-04-27 14:50:05

标签: ruby unit-testing testing operating-system tdd

我有以下Rakefile

require 'bundler/gem_tasks'
require 'rake/testtask'

Rake::TestTask.new do |task|
  task.libs << %w(test lib)
  task.pattern = 'test/**/*_test.rb'
end

task default: :test

测试用minitest定义:

require 'test_helper'
require 'certmanager'

class CertificateTest < Minitest::Test
  context 'settings' do
    should 'retrieve settings' do
      assert_equal 'test123', Certmanager::Settings.key_passphrase
    end
  end
end

现在还有一些特定于操作系统的代码,例如Linux上的FileUtils.ln_s和Windows上的FileUtils.cp。此代码需要不同的测试。在这种情况下, assert_equal filepath, File.readlink(linkpath)(Linux)与assert File.exist?(filepath)(windows)

区分操作系统类型的最佳做法是什么? 我是否必须以Linux可以测试特定于Windows的代码的方式编写测试,反之亦然? 是否有可能在测试中区分“内联”? 是否有必要使用两个不同的测试集并在Rakefile中决定需要执行哪个集合?甚至可以在Rakefile中使用吗?

1 个答案:

答案 0 :(得分:0)

为了能够在不考虑当前操作系统的情况下运行每个测试,我编写了一个模块TestHelper

包含几个方法
  • 为测试假装一个窗口或posix环境
  • 在实际操作系统上未实现(或以不同方式工作)的方法设置存根 - 目前我只在Windows上找到这些方法
  • 检查实际操作系统是否为Windows(如果有必要知道)

在测试中,只要必须是特定于操作系统的,就可以使用TestHelper.setup_windows_envTestHelper.setup_posix_env

require 'rbconfig'
require 'fileutils'
module TestHelper
  extend self

  def setup_windows_env
    is_windows?
    RbConfig::CONFIG.stubs(:[]).with('host_os').returns('windows')
    ENV.stubs(:[]).with('OS').returns('Windows_NT')
  end

  def setup_stubs_for_windows_in_posix_env
    class << FileUtils
      def ln_s(src, dest, options = {})
        File.open(dest, 'w') { |file| file.write src }
        return 0
      end
    end

    class << File
      def readlink(file_name)
        return File.read(file_name)
      end
    end
  end

  def setup_posix_env
    setup_stubs_for_windows_in_posix_env if is_windows?
    RbConfig::CONFIG.stubs(:[]).with('host_os').returns('darwin')
    ENV.stubs(:[]).with('OS').returns('OSX')
  end

  def is_windows?
    @is_windows ||= ApplicationToTest::Util::OS.is_windows?
  end
end

完整性ApplicationToTest::Util::OS.is_windows?

require 'rbconfig'
module ApplicationToTest
  module Util
    module OS
      def self.is_windows?
        begin
          env_os = ENV['OS']
        rescue NameError
          return false
        end
        if RbConfig::CONFIG['host_os'] =~ /^mingw2$|^mingw$|^mswin$|^windows$/
            true
        elsif env_os  == 'Windows_NT'
            true
        else
            false
        end
      end
    end
  end
end