Advertisement
  1. Code
  2. Ruby
  3. Ruby on Rails

Probando tu código Ruby con Guard, RSpec y Pry: Parte 2

Scroll to top
Read Time: 20 min

() translation by (you can also view the original English article)

¡Bienvenido de nuevo! Si te perdiste la primera parte de nuestro viaje hasta ahora, entonces es posible que quieras volver y ponerte al día primero.

Hasta ahora, hemos aplicado un proceso de Desarrollo Dirigido por Pruebas para construir nuestra aplicación, junto con la utilización del popular marco de pruebas RSpec. A partir de aquí, vamos a investigar algunas otras características de RSpec, así como mirar en el uso de la gema Pry para ayudarte a depurar y escribir tu código.

Otras características de RSpec

Tomemos un momento para revisar algunas otras características de RSpec que no hemos necesitado en esta sencilla aplicación de ejemplo, pero que puedes encontrar útiles trabajando en tu propio proyecto.

Declaración pendiente

Imagina que escribes una prueba pero te interrumpen, o tienes que irte a una reunión y aún no has completado el código necesario para que la prueba pase.

Podrías borrar la prueba y reescribirla más tarde, cuando puedas volver a tu trabajo. O, alternativamente, podrías comentar el código, pero eso es bastante feo y definitivamente no es bueno cuando se utiliza un sistema de control de versiones.

Lo mejor que podemos hacer en esta situación es definir nuestra prueba como 'pendiente' para que cada vez que se ejecuten las pruebas, el marco de pruebas ignore la prueba. Para ello es necesario utilizar la palabra clave pending:

1
describe "some method" do
2
  it "should do something"
3
    pending
4
  end
5
end

Montaje y desmontaje

Todos los buenos frameworks de pruebas permiten ejecutar código antes y después de la ejecución de cada prueba. RSpec no es diferente.

Nos proporciona métodos before y after que nos permiten establecer un estado específico para que nuestra prueba se ejecute, y luego limpiar ese estado después de que la prueba se haya ejecutado (esto es para que el estado no se filtre y afecte el resultado de las pruebas posteriores).

1
describe "some method" do
2
  before(:each) do
3
    # some set-up code

4
  end
5
6
  after(:each) do
7
    # some tear-down code

8
  end
9
10
  it "should do something"
11
    pending
12
  end
13
end

Bloques de contexto

Ya hemos visto el bloque describe; pero hay otro bloque que es funcionalmente equivalente llamado context. Puedes utilizarlo en todos los casos en los que usarías describe.

La diferencia entre ellos es sutil pero importante: context nos permite definir un estado para nuestra prueba. Sin embargo, no de forma explícita (en realidad no establecemos el estado definiendo un bloque de context, sino que es por motivos de legibilidad para que la intención del siguiente código sea más clara).

Aquí hay un ejemplo:

1
describe "Some method" do
2
  context "block provided" do
3
    it "yields to block" do
4
      pending
5
    end
6
  end
7
8
  context "no block provided" do
9
    it "calls a fallback method" do
10
      pending
11
    end
12
  end
13
end

Rellenos

Podemos utilizar el método stub para crear una versión falsa de un objeto existente y hacer que devuelva un valor predeterminado.

Esto es útil para evitar que nuestras pruebas toquen las APIs de servicios en vivo, y para guiar nuestras pruebas dando resultados predecibles de ciertas llamadas.

Imagina que tenemos una clase llamada Person y que esta clase tiene un método speak. Queremos comprobar que ese método funciona como esperamos. Para ello haremos un stub del método speak usando el siguiente código:

1
describe Person do
2
  it "speak()" do
3
    bob = stub()
4
    bob.stub(:speak).and_return('hello')
5
    Person.any_instance.stub(:initialize).and_return(bob)
6
    
7
    instance = Person.new
8
    expect(instance.speak).to eq('hello')
9
  end
10
end

En este ejemplo, decimos que "cualquier instancia" de la clase Person debe tener su método de initialize bloqueado para que devuelva el objeto bob.

Verás que bob es en sí mismo un talón que está configurado para que cada vez que el código intente ejecutar el método speak devuelva "hola".

Luego procedemos a crear una nueva instancia de Person y pasamos la llamada de instance.speak a la sintaxis expect de RSpec.

Le decimos a RSpec que esperamos que esa llamada dé como resultado la cadena "hola".

Valores de retorno consecutivos

En los ejemplos anteriores hemos utilizado la función RSpec and_return para indicar lo que nuestro stub debe devolver cuando es llamado.

Podemos indicar un valor de retorno diferente cada vez que se llame al stub especificando múltiples argumentos al método and_return:

1
obj = stub()
2
obj.stub(:foo).and_return(1, 2, 3)
3
4
expect(obj.foo()).to eq(1)
5
expect(obj.foo()).to eq(2)
6
expect(obj.foo()).to eq(3)

Choques

Los mocks son similares a los Stubs en el sentido de que estamos creando versiones falsas de nuestros objetos, pero en lugar de devolver un valor predefinido estamos guiando más específicamente las rutas que deben seguir nuestros objetos para que la prueba sea válida.

Para ello utilizamos el método mock:

1
describe Obj do
2
  it "testing()" do
3
    bob = mock()
4
    bob.should_receive(:testing).with('content')
5
6
    Obj.any_instance.stub(:initialize).and_return(bob)
7
8
    instance = Obj.new
9
    instance.testing('some value')
10
  end
11
end

En el ejemplo anterior creamos una nueva instancia de Objetc y luego llamamos a su método de testing.

Detrás de ese código esperamos que el método de testing sea llamado con el valor 'content'. Si no es llamado con ese valor (que en el ejemplo anterior no lo es) entonces sabemos que alguna parte de nuestro código no ha funcionado correctamente.

Bloque temático

La palabra clave subject puede utilizarse de un par de maneras diferentes. Todas ellas están diseñadas para reducir la duplicación de código.

Puedes utilizarlo implícitamente (fíjate en que nuestro bloque it no hace referencia al subject en absoluto):

1
describe Array do
2
  describe "with 3 items" do
3
    subject { [1,2,3] }
4
    it { should_not be_empty }
5
  end
6
end

Puedes utilizarlo explícitamente (fíjate en que nuestro bloque it hace referencia al subject directamente):

1
describe MyClass do
2
  describe "initialization" do
3
    subject { MyClass }
4
    it "creates a new instance" do
5
      instance = subject.new
6
      expect(instance).to be_a(MyClass)
7
    end
8
  end
9
end

En lugar de referenciar constantemente un subject dentro de tu código y pasar diferentes valores para la instanciación, por ejemplo:

1
describe "Foo" do
2
  context "A" do
3
    it "Bar" do
4
      baz = Baz.new('a')
5
      expect(baz.type).to eq('a')
6
    end
7
  end
8
9
  context "B" do
10
    it "Bar" do
11
      baz = Baz.new('b')
12
      expect(baz.type).to eq('b')
13
    end
14
  end
15
16
  context "C" do
17
    it "Bar" do
18
      baz = Baz.new('c')
19
      expect(baz.type).to eq('c')
20
    end
21
  end
22
end

En su lugar, puedes utilizar subject junto con let para reducir la duplicación:

1
describe "Person" do
2
  subject { Person.new(name) } # Person has a get_name method

3
4
  context "Bob" do
5
    let(:name) { 'Bob' }
6
    its(:get_name) { should == 'Bob' }
7
  end
8
9
  context "Joe" do
10
    let(:name) { 'Joe' }
11
    its(:get_name) { should == 'Joe' }
12
  end
13
14
  context "Smith" do
15
    let(:name) { 'Smith' }
16
    its(:get_name) { should == 'Smith' }
17
  end
18
end

Hay muchas más características disponibles para RSpec, pero hemos visto las más importantes que se encontrarán usando mucho al escribir pruebas con RSpec.

Pruebas aleatorias

Puedes configurar RSpec para ejecutar tus pruebas en un orden aleatorio. Esto te permite asegurarte de que ninguna de tus pruebas tiene ninguna dependencia o dependencia de las otras pruebas a tu alrededor.

1
RSpec.configure do |config|
2
  config.order = 'random'
3
end

Puedes establecerlo a través del comando utilizando la bandera/opción --order. Por ejemplo: rspec --order random.

Cuando se utiliza la opción --order random RSpec mostrará el número aleatorio que utilizó para sembrar el algoritmo. Puedes usar este valor de 'semilla' de nuevo cuando creas que has descubierto un problema de dependencia dentro de tus pruebas. Una vez que hayas arreglado lo que crees que es el problema, puedes pasar el valor de la semilla a RSpec (por ejemplo, si la semilla era 1234, entonces ejecuta --order random:1234) y utilizará esa misma semilla aleatoria para ver si puede replicar el error de dependencia original.

Configuración global

Has visto que hemos añadido un conjunto de objetos de configuración específicos del proyecto dentro de nuestro Rakefile. Pero puedes establecer opciones de configuración de forma global añadiéndolas a un archivo .rspec dentro de tu directorio principal.

Por ejemplo, dentro de .rspec:

1
--color --format nested

Depuración con Pry

Ahora estamos listos para empezar a ver cómo podemos depurar nuestra aplicación y nuestro código de prueba utilizando la gema Pry.

Es importante entender que aunque Pry es realmente bueno para depurar tu código, en realidad está pensado como una herramienta mejorada de Ruby REPL (para reemplazar a irb) y no estrictamente para propósitos de depuración; así que, por ejemplo, no hay funciones incorporadas como: step into, step over o step out, etc. que típicamente encontrarías en una herramienta diseñada para depuración.

Pero como herramienta de depuración, Pry está muy centrada y limpia.

Volveremos a la depuración en un momento, pero primero revisemos cómo usaremos Pry inicialmente.

Ejemplo de código actualizado

Con el propósito de demostrar Pry voy a añadir más código a mi aplicación de ejemplo (este código extra no afecta a nuestra prueba de ninguna manera)

1
class RSpecGreeter
2
  attr_accessor :test
3
4
  @@class_property = "I'm a class property"
5
6
  def greet
7
    binding.pry
8
    @instance_property = "I'm an instance property"
9
    pubs
10
    privs
11
    "Hello RSpec!"
12
  end
13
14
  def pubs
15
    test_var = "I'm a test variable"
16
    test_var
17
  end
18
19
  private
20
21
  def privs
22
    puts "I'm private"
23
  end
24
end

Verás que hemos añadido algunos métodos adicionales y propiedades de instancia y de clase. También hacemos llamadas a dos de los nuevos métodos que hemos añadido desde nuestro método greet.

Por último, te darás cuenta del uso de binding.pry.

Configuración de puntos de ruptura con binding.pry

Un punto de interrupción es un lugar dentro de tu código donde la ejecución se detendrá.

Puedes tener múltiples puntos de ruptura establecidos dentro de tu código y los creas usando binding.pry.

Cuando ejecutes tu código notarás que la terminal se detendrá y te colocará dentro del código de tu aplicación en el punto exacto en el que se colocó tu binding.pry.

A continuación se muestra un ejemplo de cómo debería verse...

1
    8: def greet
2
=>  9:   binding.pry
3
   10:   pubs
4
   11:   privs
5
   12:   "Hello RSpec!"
6
   13: end

A partir de este punto, Pry tiene acceso al ámbito local, por lo que puedes usar Pry como lo harías en irb y empezar a escribir, por ejemplo, variables para ver qué valores tienen.

Puedes ejecutar el comando exit para salir de Pry y que tu código siga ejecutándose.

Encontrando dónde estás: whereami

Cuando se utilizan muchos puntos de ruptura de binding.pry puede ser difícil entender en qué parte de la aplicación se encuentra.

Para obtener un mejor contexto de dónde te encuentras en cualquier punto, puedes utilizar el comando whereami.

Cuando se ejecuta por sí solo, verás algo similar a cuando utilizaste binding.pry (verás la línea en la que se estableció el punto de ruptura y un par de líneas por encima y por debajo de ella). La diferencia es que si pasas un argumento numérico extra como whereami 5 verás cinco líneas adicionales por encima de donde se colocó el binding.pry. Podrías solicitar ver 100 líneas alrededor del punto de ruptura actual, por ejemplo.

Este comando puede ayudarte a orientarse dentro del archivo actual.

Rastreo de pila: wtf

El comando wtf significa "que caraj***" y proporciona un seguimiento completo de la pila de la excepción más reciente que se ha lanzado. Puede ayudarte a entender los pasos que conducen al error que se ha producido.

Inspeccionando: ls

El comando ls muestra qué métodos y propiedades están disponibles para Pry.

Cuando se ejecuta te mostrará algo como...

1
RSpecGreeter#methods: greet  pubs  test  test=
2
class variables: @@class_property
3
locals: _  __  _dir_  _ex_  _file_  _in_  _out_  _pry_

En el ejemplo anterior podemos ver que tenemos cuatro métodos públicos (recordemos que actualizamos nuestro código para incluir algunos métodos adicionales y luego se crearon test y test= al usar el atajo de attr_accessor de Ruby).

También muestra otras variables de clase y locales a las que puede acceder Pry.

Otra cosa útil que puedes hacer es grep (buscar) en los resultados solo lo que te interesa. Tendrás que tener conocimientos de Expresiones Regulares pero puede ser una técnica muy útil. Aquí tienes un ejemplo...

1
ls -p -G ^p
2
=> RSpecGreeter#methods: privs

En el ejemplo anterior estamos usando las opciones/banderas -p y -G que le dicen a Pry que solo queremos ver los métodos públicos y privados y usamos el regex ^p (que significa coincidir con cualquier cosa que comience con p) como nuestro patrón de búsqueda para filtrar los resultados.

La ejecución de ls --help también te mostrará todas las opciones disponibles.

Cambio de ámbito: cd

Puedes cambiar el ámbito actual utilizando el comando cd.

En nuestro ejemplo si ejecutamos cd ../pubs nos llevará al resultado de esa llamada al método.

Si ahora ejecutamos whereami verás que mostrará inside "Soy una variable de prueba".

Si ejecutamos self entonces verás que nos devuelve "I'm a test variable".

Si ejecutamos self.class veremos que devuelve String.

Puedes ascender en la cadena del ámbito utilizando cd .. o puedes volver al nivel superior del ámbito utilizando cd /.

Nota: podríamos añadir otro binding.pry dentro del método pubs y entonces nuestro ámbito estaría dentro de ese método en lugar del resultado del método.

Ver lo profundo que eres: nesting

Consideremos el ejemplo anterior de ejecutar cd pubs. Si ejecutamos el comando de nesting obtendremos una mirada de nivel superior sobre el número de contextos/niveles que tiene actualmente Pry:

1
Nesting status:
2
--
3
0. # (Pry top level)

4
1. "I'm a test variable"

Desde ahí podemos ejecutar exit para volver al contexto anterior (por ejemplo, dentro del método greet)

Ejecutar exit de nuevo significará que estamos cerrando el último contexto que tiene Pry y así Pry termina y nuestro código continúa ejecutándose.

Localizar cualquier método: find-method

Si no estás seguro de dónde encontrar un método en particular, puedes utilizar el comando find-method para mostrar todos los archivos dentro de tu base de código que tienen un método que coincide con lo que estás buscando:

1
find-method priv
2
=> Kernel
3
   Kernel#private_methods
4
   Module
5
   Module#private_instance_methods
6
   Module#private_constant
7
   Module#private_method_defined?
8
   Module#private_class_method
9
   Module#private
10
   RSpecGreeter
11
   RSpecGreeter#privs

También puedes utilizar la opción/bandera -c para buscar en el contenido de los archivos:

1
find-method -c greet
2
=> RSpecGreeter
3
   RSpecGreeter: def greet
4
   RSpecGreeter#privs:   greet

Depuración clásica: next, step, continue

Aunque las técnicas anteriores son útiles, no se trata realmente de "depuración" en el mismo sentido al que probablemente estés acostumbrado.

Para la mayoría de los desarrolladores su editor o navegador les proporcionará una herramienta de depuración integrada que les permitirá recorrer su código línea por línea y seguir la ruta que sigue el código hasta su finalización.

Como Pry está desarrollado para ser usado como un REPL eso no quiere decir que no sea útil para depurar.

Una solución ingenua sería establecer múltiples sentencias binding.pry a través de un método y utilizar ctrl-d para moverse a través de cada punto de ruptura establecido. Pero eso no es suficiente.

Para depurar paso a paso puedes cargar la gema pry-nav...

1
source "https://rubygems.org"
2
3
gem 'rspec'
4
5
group :development do
6
  gem 'guard'
7
  gem 'guard-rspec'
8
  gem 'pry'
9
10
  # Adds debugging steps to Pry

11
  # continue, step, next

12
  gem 'pry-remote'
13
  gem 'pry-nav'
14
end

Esta gema extiende Pry para que entienda los siguientes comandos:

  • Next (pasar a la siguiente línea)
  • Step (pasar a la siguiente línea y si es un método, entonces pasar a ese método)
  • Continuar (Ignorar cualquier otro punto de interrupción en este archivo)

Integración continua con Travis-CI

Como un bono adicional vamos a integrar nuestras pruebas con el servicio de CI (integración continua) en línea Travis-CI.

El principio de CI es confirmar/empujar temprano y con frecuencia para evitar conflictos entre el código y la rama maestra. Cuando lo hagas (en este caso, estamos confirmando en GitHub), debería iniciarse una "compilación" en tu servidor CI que ejecute las pruebas pertinentes para garantizar que todo funciona como debería.

Ahora bien, con TDD como metodología principal de desarrollo, es menos probable que se produzcan errores cada vez que se ejecuta la aplicación, ya que las pruebas son una parte integral del flujo de trabajo de desarrollo y, por tanto, antes de ejecutar la aplicación, ya se conocen los errores o las regresiones. Pero esto no necesariamente te protege de los errores que se producen en las pruebas de integración (donde todo el código a través de múltiples sistemas se ejecutan juntos para asegurar que el sistema 'como un todo' está funcionando correctamente)

En cualquier caso, el código nunca debe ser empujado directamente a tu servidor de producción en vivo de cualquier manera; siempre debe ser empujado primero a un servidor de CI para ayudar a detectar cualquier error potencial que surja de las diferencias entre su entorno de desarrollo y el entorno de producción.

Muchas empresas tienen más entornos por los que debe pasar su código antes de llegar al servidor de producción en vivo.

Por ejemplo, en BBC News tenemos:

  • CI
  • Prueba
  • Escenario
  • En vivo

Aunque cada entorno debe ser idéntico en su configuración, el objetivo es aplicar diferentes tipos de pruebas para garantizar que se detecten y resuelvan el mayor número de errores antes de que el código llegue al "vivo".

Travis-CI

Travis CI es un servicio de integración continua alojado para la comunidad de código abierto. Está integrado con GitHub y ofrece soporte de primera clase para múltiples lenguajes

Esto significa que Travis-CI ofrece servicios de CI gratuitos para proyectos de código abierto y también tiene un modelo de pago para empresas y organizaciones que quieren mantener su integración de CI en privado.

Utilizaremos el modelo gratuito de código abierto en nuestro repositorio GitHub de ejemplo.

El proceso es este:

  • Registra una cuenta en GitHub
  • Inicia sesión en Travis-CI con tu cuenta de GitHub
  • Ve a tu página de "Cuentas"
  • ''Activa'' los repositorios en los que deseas ejecutar CI
  • Crea un archivo .travis.yml dentro del directorio raíz de tu proyecto y envíalo a tu repositorio de GitHub

El último paso es el más importante (la creación de un archivo .travis.yml) ya que determina los ajustes de configuración para Travis-CI para que sepa cómo manejar la ejecución de las pruebas para tu proyecto.

Echemos un vistazo al archivo .travis.yml que estamos utilizando para nuestro repositorio GitHub de ejemplo:

1
language: ruby
2
cache: bundler
3
4
rvm:
5
  - 2.0.0
6
  - 1.9.3
7
8
script: 'bundle exec rake spec'
9
10
bundler_args: --without development
11
12
branches:
13
  only:
14
    - master
15
16
notifications:
17
  email:
18
    - you@example.com

Vamos a desglosar esto pieza por pieza...

Primero especificamos qué lenguaje estamos usando en nuestro proyecto. En este caso estamos usando Ruby: language: ruby.

Como la ejecución de Bundler puede ser un poco lenta y sabemos que nuestras dependencias no van a cambiar tan a menudo, podemos optar por almacenar en caché las dependencias, por lo que establecemos cache: bundler.

Travis-CI utiliza RVM (Ruby Version Manager) para instalar Rubies en sus servidores. Así que tenemos que especificar contra qué versiones de Ruby queremos ejecutar nuestras pruebas. En este caso hemos elegido la 2.0 y la 1.9.3 que son dos versiones populares de Ruby (técnicamente nuestra aplicación utiliza Ruby 2 pero es bueno saber que nuestro código pasa en otras versiones de Ruby también):

1
rvm:
2
  - 2.0.0
3
  - 1.9.3

Para ejecutar nuestras pruebas sabemos que podemos utilizar el comando rake o rake spec. Travis-CI por defecto ejecuta el comando rake pero debido a cómo se instalan las Gemas en Travis-CI usando Bundler tenemos que cambiar el comando por defecto: script: 'bundle exec rake spec'. Si no hiciéramos esto, Travis-CI tendría un problema para localizar el archivo rspec/core/rake_task que está especificado en nuestro Rakefile.

Nota: si tienes algún problema con Travis-CI, puedes unirte al canal #travis en IRC freenode para obtener ayuda para responder a cualquier pregunta que puedas tener. Ahí es donde descubrí la solución a mi problema con Travis-CI que no era capaz de ejecutar mis pruebas utilizando su comando rake por defecto y la sugerencia de sobrescribir el valor por defecto con bundle exec rake resolvió ese problema.

A continuación, como solo nos interesa ejecutar nuestras pruebas, podemos pasar argumentos adicionales a Travis-CI para filtrar las gemas que no queremos molestarnos en instalar. Así que para nosotros queremos excluir la instalación de las gemas agrupadas como desarrollo: bundler_args: --without development (esto significa que estamos excluyendo las gemas que solo se utilizan realmente para el desarrollo y la depuración como Pry y Guard).

Es importante señalar que originalmente estaba cargando Pry dentro de nuestro archivo spec_helper.rb. Esto causó un problema al ejecutar el código en Travis-CI, ahora que estaba excluyendo las gemas de "desarrollo". Así que tuve que ajustar el código de esta manera:

1
require 'pry' if ENV['APP_ENV'] == 'debug'

Puedes ver que ahora la gema Pry solo es require si una variable de entorno de APP_ENV se establece como debug. De esta manera podemos evitar que Travis-CI arroje algún error. Esto significa que cuando ejecutes tu código localmente tendrás que establecer la variable de entorno si quieres depurar tu código usando Pry. Lo siguiente muestra cómo se podría hacer esto en una línea:

1
APP_ENV=debug && ruby lib/example.rb

Hubo otros dos cambios que hice y fue a nuestro Gemfile. Uno era para dejar más claro qué gemas eran necesarias para las pruebas y cuáles para el desarrollo, y el otro era requerido explícitamente por Travis-CI:

1
source "https://rubygems.org"
2
3
group :test do
4
  gem 'rake'
5
  gem 'rspec'
6
end
7
8
group :development do
9
  gem 'guard'
10
  gem 'guard-rspec'
11
  gem 'pry'
12
13
  # Adds debugging steps to Pry

14
  # continue, step, next

15
  gem 'pry-remote'
16
  gem 'pry-nav'
17
end

Mirando el Gemfile actualizado de arriba podemos ver que hemos movido la gema RSpec a un nuevo grupo de test, así que ahora debería estar más claro el propósito de cada gema. También hemos añadido una nueva gem 'rake'. La documentación de Travis-CI indica que es necesario especificar esto explícitamente.

La siguiente sección es opcional y te permite hacer una lista blanca (o negra) de ciertas ramas en tu repositorio. Así que por defecto Travis-CI ejecutará las pruebas contra todas tus ramas a menos que le digas lo contrario. En este ejemplo le estamos diciendo que solo queremos que se ejecute contra nuestra rama master:

1
branches:
2
  only:
3
    - master

Podríamos decirle que ejecute todas las ramas "excepto" una rama en particular, así:

1
branches:
2
  except:
3
    - some_branch_I_dont_want_run

La sección final le dice a Travis-CI a dónde enviar las notificaciones cuando una construcción falla o tiene éxito:

1
notifications:
2
  email:
3
    - you@example.com

Si lo deseas puedes especificar varias direcciones de correo electrónico:

1
notifications:
2
  email:
3
    - you@example.com
4
    - them@example.com
5
    - others@example.com

Puedes ser más específico y especificar lo que quieres que ocurra en caso de fallo o de éxito (por ejemplo, a más gente le interesará solo si las pruebas fallan en lugar de recibir un correo electrónico cada vez que pasen):

1
notifications:
2
  email:
3
    recipients:
4
      - you@example.com
5
    on_failure: change
6
    on_success: never

El ejemplo anterior muestra que el destinatario nunca recibirá un correo electrónico si las pruebas pasan, pero será notificado si el estado de fallo cambia (el valor por defecto para ambos es always, lo que significa que siempre será notificado independientemente del resultado del estado).

Nota: cuando se especifica explícitamente un on_failure o un on_success es necesario mover la(s) dirección(es) de correo electrónico dentro de la clave de recipients.

Conclusión

Este es el final de nuestra segunda parte sobre RSpec, TDD y Pry.

En la primera parte logramos escribir nuestra aplicación utilizando el proceso TDD y el framework de pruebas RSpec. En esta segunda parte también hemos utilizado Pry para mostrar cómo podemos depurar más fácilmente una aplicación Ruby en ejecución. Por último, hemos podido configurar nuestras pruebas para que se ejecuten como parte de un servidor de integración continua utilizando el popular servicio Travis-CI.

Esperemos que esto te haya dado una idea suficiente para que tenga ganas de investigar más a fondo cada una de estas técnicas.

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.