Как проверить скрипт, который генерирует файлы - PullRequest
3 голосов
/ 19 февраля 2011

Я создаю Rubygem, который позволит мне создавать файлы постов jekyll.Одна из причин, по которой я разрабатываю этот проект, - это изучение TDD.Этот гем строго функционален в командной строке, и он должен выполнить серию проверок, чтобы убедиться, что он находит каталог _posts.Это зависит от двух вещей:

  1. Был ли передан параметр location
    • Допустим ли этот параметр местоположения?
  2. Aопция местоположения не была передана
    • Является ли каталог сообщений в текущем каталоге?
    • Является ли каталог сообщений текущим рабочим каталогом?

В этот момент мне действительно тяжело тестировать эту часть приложения.Поэтому у меня есть два вопроса:

  • допустимо / нормально пропустить тесты для небольших частей приложения, как описано выше?
  • Если нет, как вы тестируете манипулирование файламив рубине используя минитест?

Ответы [ 2 ]

2 голосов
/ 19 февраля 2011

Некоторые проекты, которые я видел, реализуют свои инструменты командной строки как объекты Command (например: Rubygems и мой гем перевода строки ).Эти объекты инициализируются с помощью ARGV, просто есть метод вызова или выполнения, который затем запускает весь процесс.Это позволяет этим проектам размещать свои приложения командной строки в виртуальной среде.Они могут, например, содержать объекты потока ввода и вывода в переменных экземпляра объекта команды, чтобы приложение не зависело от использования STDOUT / STDIN.И, таким образом, позволяя проверить ввод / вывод приложения командной строки.Точно так же, как я представляю, вы можете хранить ваш текущий рабочий каталог в переменной экземпляра, чтобы сделать приложение командной строки независимым от вашего реального рабочего каталога.Затем вы можете создать временный каталог для каждого теста и установить его в качестве рабочего каталога для вашего объекта Command.

А теперь некоторый код:

require 'pathname'

class MyCommand
  attr_accessor :input, :output, :error, :working_dir

  def initialize(options = {})
    @input = options[:input] ? options[:input] : STDIN
    @output = options[:output] ? options[:output] : STDOUT
    @error = options[:error] ? options[:error] : STDERR
    @working_dir = options[:working_dir] ? Pathname.new(options[:working_dir]) : Pathname.pwd
  end

  # Override the puts method to use the specified output stream
  def puts(output = nil)
    @output.puts(output)
  end

  def execute(arguments = ARGV)
    # Change to the given working directory
    Dir.chdir(working_dir) do
      # Analyze the arguments
      if arguments[0] == '--readfile'
        posts_dir = Pathname.new('posts')
        my_file = posts_dir + 'myfile'
        puts my_file.read
      end
    end
  end
end

# Start the command without mockups if the ruby script is called directly
if __FILE__ == $PROGRAM_NAME
  MyCommand.new.execute
end

Теперь в настройке вашего теста и демонтажеметоды, которые вы могли бы сделать:

require 'pathname'
require 'tmpdir'
require 'stringio'

def setup
  @working_dir = Pathname.new(Dir.mktmpdir('mycommand'))
  @output = StringIO.new
  @error = StringIO.new

  @command = MyCommand.new(:working_dir => @working_dir, :output => @output, :error => @error)
end

def test_some_stuff
  @command.execute(['--readfile'])

  # ...
end

def teardown
  @working_dir.rmtree
end

(В примере я использую Pathname, который представляет собой действительно хороший объектно-ориентированный API файловой системы из стандартной библиотеки Ruby и StringIO, который полезен для насмешки над STDOUT, посколькуобъект ввода-вывода, который превращается в простую строку)

В тесте acutal теперь можно использовать переменную @working_dir для проверки существования или содержимого файлов:

path = @working_dir + 'posts' + 'myfile'
path.exist?
path.file?
path.directory?
path.read == "abc\n"
1 голос
/ 19 февраля 2011

Исходя из моего опыта (и, следовательно, это ОЧЕНЬ субъективно), я думаю, что иногда можно пропустить модульное тестирование в некоторых областях, которые трудно проверить.Вам необходимо выяснить, что вы получите взамен, а также стоимость тестирования или нет.Мое эмпирическое правило заключается в том, что решение не тестировать класс должно быть очень необычным (примерно менее 1 на 300 классов)

Если то, что вы пытаетесь проверить, очень сложно, из-за зависимостейфайловая система, я думаю, вы могли бы попытаться извлечь все биты, которые взаимодействуют с файловой системой.

...