7 days of WordPress plugins, themes & templates - for free!* Unlimited asset downloads! Start 7-Day Free Trial
Advertisement
  1. Code
  2. Ruby

Ruby para Novatos: Probando con Rspec

Scroll to top
Read Time: 9 mins
This post is part of a series called Ruby for Newbies.
Ruby for Newbies: Missing Methods

Spanish (Español) translation by Valeria Angulo (you can also view the original English article)

Ruby es uno de los lenguajes más populares usados en la web. Estamos llevando a cabo una sesión aquí en Nettuts + que te presentará a Ruby, así como también los excelentes frameworks y herramientas que acompañan al desarrollo de Ruby. En este episodio, aprenderás a probar tu código Ruby con Rspec, una de las mejores bibliotecas de prueba del mercado.


Prefieres un Screencast?


Te parece Familiar?

Si has leído mi reciente tutorial sobre JasmineJS, probablemente notarás varias similitudes en Rspec.  En realidad, las similitudes están en Jasmine: Jasmine se creó con Rspec en mente. Vamos a ver cómo se puede usar Rspec para hacer TDD en Ruby. En este tutorial, crearemos algunas clases artificiales de Ruby para familiarizarnos con la sintaxis de Rspec.   Sin embargo, el próximo episodio de "Ruby for Newbies" incluirá el uso de Rspec junto con algunas otras bibliotecas para probar aplicaciones web ... ¡así que mantente atento! 


Configurando

Es bastante fácil de instalar Rspec. Pop abre esa línea de comando y ejecuta esto: 

Así de fácil. 

Ahora, configuremos un pequeño proyecto.  Vamos a crear dos clases: Book y library. Nuestros objetos de Book solo almacenarán un título, autor y categoría. Nuestro objeto Library almacenará una lista de libros, los guardará en un archivo y nos permitirá buscarlos por categoría. 

Este es el aspecto que debería tener el directorio de su proyecto: 

Project DirectoryProject DirectoryProject Directory

Ponemos las especificaciones (o specs) en una carpeta spec ; tenemos un archivo de especificaciones para cada clase. Observe el archivo spec_helper.rb. Para que se ejecuten nuestras especificaciones, debemos solicitar con requirelas clases de Ruby que estamos probando. Eso es lo que estamos haciendo dentro del archivo spec_helper:

(¿Ya conociste require_relative?  ¿No? Bueno, require_relative es como require, excepto que en lugar de buscar tu ruta de Ruby, busca en relación con el directorio actual).

Es posible que no estés familiarizado con el módulo YAML; YAML es una base de datos de texto simple que usaremos para almacenar datos. Verás cómo funciona, y hablaremos sobre eso más adelante. 

Entonces, ahora que estamos listos, ¡analicemos algunas especificaciones! 


La Clase Book

Comencemos con las pruebas para la clase Book.

Así es como comenzamos: con un bloque describe. Nuestro parámetro para describe explica lo que estamos probando: esto podría ser una cadena, pero en nuestro caso estamos usando el nombre de la clase.

Entonces, ¿qué vamos a poner dentro de este bloque describe?

Comenzaremos haciendo una llamada a before; pasamos el símbolo :each para especificar que queremos que este código se ejecute antes de cada prueba (también podríamos hacer :all para ejecutarlo una vez antes de todas las pruebas). ¿Qué estamos haciendo exactamente antes de cada prueba?  Estamos creando una instancia de Book. Observe cómo lo estamos convirtiendo en una variable de instancia, anteponiendo el nombre de la variable con @. Necesitamos hacer esto para que nuestra variable sea accesible desde dentro de nuestras pruebas.  De lo contrario, obtendremos una variable local que solo es válida dentro del bloque before... lo cual no es bueno en absoluto.

Continuando, 

Aquí está nuestra primera prueba. Estamos usando un bloque describe anidado aquí para decir que estamos describiendo las acciones de un método específico. Notarás que he usado la cadena "#new"; es una convención en Ruby para hablar referente a métodos de instancia como este:ClassName#methodName Dado que tenemos el nombre de la clase en nuestra descripción de nivel superior, aquí solo estamos poniendo el nombre del método.

Nuestra prueba simplemente confirma que, de hecho, estamos haciendo un objeto Book. 

Observe la gramática que usamos aquí: object.should do_something. El noventa y nueve por ciento de sus pruebas tomarán esta forma: usted tiene un objeto y comienza llamando al should o should_not sobre el objeto. Luego, pasa a ese objeto la llamada a otra función.  En este caso, eso es be_an_instance_of (que toma Book como su único parámetro). En conjunto, esto hace una prueba perfectamente legible.  Está muy claro que @book debería ser una instancia de la clase Book. Entonces, ejecútelo.

Abra su terminal, escriba cd en el directorio del proyecto y ejecute la especificación rspec spec. La spec es la carpeta en la que rspec encontrará las pruebas. Deberías ver el resultado que dice algo sobre "Objeto constante sin iniciar Object::Book"; esto solo significa que no está la clase Book.  Arreglemos eso.

De acuerdo con TDD, solo queremos escribir suficiente código para solucionar este problema. En el archivo book.rb, sería esto:

Vuelve a ejecutar la prueba (rspec spec), y verá que está pasando bien. No tenemos un método initialize, así que llamar a Ruby#new no tiene ningún efecto en este momento. Pero, podemos crear objetos Book(aunque sean huecos). Normalmente, seguiríamos este proceso durante el resto de nuestro desarrollo: escribir una prueba (o algunas pruebas relacionadas), verla fallar, hacerla pasar, refactorizar, repetir.  Sin embargo, para este tutorial, solo te mostraré las pruebas y el código, y los discutiremos. 

Así, más pruebas para Book:

Todo debería ser muy directo para ti. Pero observa cómo estamos comparando en la prueba: con eql. Hay tres maneras de probar la igualdad con Rspec: utilizando el operador == o el método eql ambos devuelven truesi los dos objetos tienen el mismo contenido. Por ejemplo, ambos son cadenas o símbolos que dicen lo mismo.  Luego está equal, que solo devuelve "true" en los dos objetos que son realmente y verdaderamente iguales, lo que significa que son el mismo objeto en la memoria. En nuestro caso, eql (o ==) es lo que queremos.

Estos fallarán, así que aquí está el código paraBook para hacerlos pasar:

Pasemos a Library!


Especificando la clase Library

Esto será un poco más complicado.  Así que comencemos con esto:

Todo está configurado: estamos usando dos bloques before: uno para :each y uno para :all En el bloque before: all, creamos una matriz de libros. Luego abrimos el archivo "books.yml" (en el modo "w"rite) y usamos YAML para volcar la matriz en el archivo.

Usamos "Short rabbit-trail" para explicar YAML un poco mejor: YAML es, de acuerdo con el sitio "un estándar de serialización de datos amigable para todos los lenguajes de programación." Es como una base de datos basada en texto, algo así como JSON. Estamos importando YAML en nuestro spec_helper.rb. El módulo YAML tiene dos métodos principales que utilizará: dump, que genera los datos serializados como una cadena. Luego, load toma la cadena de datos y la vuelve a convertir en objetos Ruby.

Por lo tanto, hemos creado este archivo con algunos datos. Antes de cada :each prueba, vamos a crear un objeto Library, pasándole el nombre del archivo YAML.  Ahora veamos las pruebas: 

Comenzamos con un bloque interno describe  especialmente para el método Library#new. Estamos presentando otro bloque aquí: context Esto nos permite especificar un contexto para las pruebas dentro de él, o especificar diferentes resultados para diferentes situaciones. En nuestro ejemplo, tenemos dos contextos diferentes: "sin parámetros" y "con un parámetro de archivo yaml"; estos muestran los dos comportamientos para usar Library#new.

Además, observe los evaluadores de prueba que estamos usando en estas dos pruebas: lib.should have(0).books y @ lib.should have(5).books. La otra forma de escribir esto sería lib.books.length.should == 5, pero esto no es tan legible. Sin embargo, muestra que necesitamos tener una propiedad books que sea una matriz de los libros que tenemos.

Luego, tenemos otras tres pruebas para probar la funcionalidad de obtener libros por categoría, agregar un libro a la biblioteca y guardar la biblioteca. Todos están fallando, así que vamos a escribir la clase ahora.

Podríamos escribir más pruebas y agregar muchas otras funcionalidades a esta clase Library, pero nos detendremos allí. Ahora ejecutando rspec spec, verás que todas las pruebas pasan.

Sin embargo, esto no nos da mucha información sobre las pruebas.  Si desea ver más, use el parámetro de formato anidado:  rspec spec --format nested.  Verás esto: 


Unos pocos últimos Igualadores 

Antes de concluir, déjame mostrarte un par de otros igualadores

  • obj.should be_trueobj.should be_false, obj.should be_nilobj.should be_empty - los primeros tres de estos podrían hacerse por == true, etc. be_empty podría ser verdadero si obj.empty? es verdadero.
  • obj.should exist - ¿este objeto existe aún?
  • obj.should have_at_most(n).items object.should have_at_least(n).items - como have, pero pasará si hay más o menos de n artículos, respectivamente.
  • obj.should include (a [, b, ...]) - ¿hay uno o más elementos en una matriz?
  • obj.should match (string_or_regex) - ¿el objeto coincide con la cadena o con la expresión regular?
  • obj.should raise_exception (error) - ¿Este método genera un error cuando se llama? 
  • obj.should respon_to (method_name) - ¿este objeto tiene este método? Puedes tomar más de un nombre de método, ya sea en cadenas o símbolos.

¿Quieres Aprender Más?

Rspec es uno de los mejores frameworks para probar en Ruby, y hay mucho que puedes hacer con él.  Para obtener más información, consulte el sitio web de Rspec. También está el libro The Rspec, que enseña más que solo Rspec: se trata de TDD y BDD en Ruby. Lo estoy leyendo ahora, y es extremadamente minucioso y profundo. 

Bueno, ¡eso es todo por esta lección! La próxima vez, veremos cómo podemos usar Rspec para probar las interfaces en una aplicación web. 

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.