Pregunta

Estoy creando una Rubygem que me permitirá generar jekyll publicar archivos.Uno de los motivos por los que estoy desarrollo de este proyecto es aprender TDD.Esta joya es estrictamente funcional en la línea de comandos, y se tiene que hacer una serie de comprobaciones para asegurarse de que se encuentra el _posts directorio.Esto depende de dos cosas:

  1. Si o no location la opción fue aprobada
    • Es que la ubicación de la opción válida?
  2. Una opción de ubicación no fue aprobada
    • Es los puestos de directorios en el directorio actual?
    • Es los puestos de directorios el directorio de trabajo actual?

En ese momento, realmente estoy teniendo un momento difícil de la prueba de que parte de la aplicación.Así que tengo dos preguntas:

  • es aceptable/bueno saltarse las pruebas para las pequeñas partes de la aplicación, como la descrita anteriormente?
  • Si no, ¿cómo se prueba la manipulación de archivos en ruby utilizando minitest?
¿Fue útil?

Solución

Algunos de los proyectos que he visto aplicar sus herramientas de línea de comandos como objetos de Comando (por ejemplo: Rubygems y mi salto de línea gema).Estos objetos se inicializa con la ARGV simplemente tener una llamada o un método de ejecución que a continuación se inicia todo el proceso.Esto permite a estos proyectos para poner sus aplicaciones de línea de comandos en un entorno virtual.Podrían, por ejemplo, celebrar la entrada y salida de los objetos de flujo en las variables de instancia del objeto de comando para hacer que la aplicación independiente de la utilización de STDOUT/STDIN.Y así, haciendo posible la prueba de la entrada/salida de la línea de comandos de la aplicación.De la misma manera que yo imagino, puedes mantener tu directorio de trabajo actual en una variable de instancia para hacer su aplicación de línea de comandos independiente de su real directorio de trabajo.Luego puede crear un directorio temporal para cada prueba, y configurar este como el directorio de trabajo para su objeto de Comando.

Y ahora algo de código:

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

Ahora en su prueba de la instalación y desmontaje de los métodos que usted puede hacer:

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

(En el ejemplo, estoy usando la Ruta de acceso, que es un muy lindo orientado a objetos del sistema de archivos de la API de Rubí de la biblioteca estándar y StringIO, que es útil para para burlarse de STDOUT como es un IO objeto que fluye en una simple Cadena de caracteres)

En el acutal prueba ahora usted podría utilizar el @working_dir variable para la prueba de la existencia o contenido de los archivos:

path = @working_dir + 'posts' + 'myfile'
path.exist?
path.file?
path.directory?
path.read == "abc\n"

Otros consejos

Desde mi experiencia (y por lo tanto esto es MUY subjetivo), creo que está bien, a veces para saltar de la unidad de pruebas en algunas áreas que son difíciles de probar.Usted necesita saber lo que usted consigue en el retorno y el costo de la prueba o no.Mi regla de oro es que la decisión de no probar una clase debe ser muy raro (menos de 1 en 300 clases)

Si lo que estás tratando de probar, es muy difícil, debido a las dependencias con el sistema de archivos, creo que se podría tratar de extraer todos los bits que interactúan con el sistema de archivos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top