Lenguaje Ruby y su entorno Curso de Ruby IV: Rspec Pedro Navajas Modelo Laboratorio de Software Libre Escuela Politécnica Superior Universidad de Córdoba 24 de Marzo de 2011 Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 1 / 12
Tabla de contenidos 1 Tests Ejemplo de tests Rspec Rspec: ejercicio práctico Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 2 / 12
Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 3 / 12
Rspec Sección Actual: Tests 1 Tests Ejemplo de tests Rspec Rspec: ejercicio práctico Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 3 / 12
Los tests automátizados no son nada nuevo Tratan de ayudar en el desarrollo Permiten que la dificultad de mantener el código no sea directamente proporcional a la antigüedad del mismo Forman lo que se denomina en muchos casos documentación ejecutable Forman parte del paradigma Test Driven Development, que a su vez forma parte del Behaviour Driven Development Son parte esencial del patrón de diseño red/green/refactor Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 4 / 12
Los tests automátizados no son nada nuevo Tratan de ayudar en el desarrollo Permiten que la dificultad de mantener el código no sea directamente proporcional a la antigüedad del mismo Forman lo que se denomina en muchos casos documentación ejecutable Forman parte del paradigma Test Driven Development, que a su vez forma parte del Behaviour Driven Development Son parte esencial del patrón de diseño red/green/refactor Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 4 / 12
Los tests automátizados no son nada nuevo Tratan de ayudar en el desarrollo Permiten que la dificultad de mantener el código no sea directamente proporcional a la antigüedad del mismo Forman lo que se denomina en muchos casos documentación ejecutable Forman parte del paradigma Test Driven Development, que a su vez forma parte del Behaviour Driven Development Son parte esencial del patrón de diseño red/green/refactor Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 4 / 12
Los tests automátizados no son nada nuevo Tratan de ayudar en el desarrollo Permiten que la dificultad de mantener el código no sea directamente proporcional a la antigüedad del mismo Forman lo que se denomina en muchos casos documentación ejecutable Forman parte del paradigma Test Driven Development, que a su vez forma parte del Behaviour Driven Development Son parte esencial del patrón de diseño red/green/refactor Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 4 / 12
Los tests automátizados no son nada nuevo Tratan de ayudar en el desarrollo Permiten que la dificultad de mantener el código no sea directamente proporcional a la antigüedad del mismo Forman lo que se denomina en muchos casos documentación ejecutable Forman parte del paradigma Test Driven Development, que a su vez forma parte del Behaviour Driven Development Son parte esencial del patrón de diseño red/green/refactor Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 4 / 12
Los tests automátizados no son nada nuevo Tratan de ayudar en el desarrollo Permiten que la dificultad de mantener el código no sea directamente proporcional a la antigüedad del mismo Forman lo que se denomina en muchos casos documentación ejecutable Forman parte del paradigma Test Driven Development, que a su vez forma parte del Behaviour Driven Development Son parte esencial del patrón de diseño red/green/refactor Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 4 / 12
Hay una gran cantidad de frameworks para las pruebas unitarias 1 El framework de testeo más utilizado es JUnit, existente para una gran cantidad de lenguajes: Java, c++, php, python, ruby etc. Sin embargo aquí vamos a usar RSpec, que hace lo mismo pero......con una semántica diferente 1 http://en.wikipedia.org/wiki/list_of_unit_testing_frameworks Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 5 / 12
Hay una gran cantidad de frameworks para las pruebas unitarias 1 El framework de testeo más utilizado es JUnit, existente para una gran cantidad de lenguajes: Java, c++, php, python, ruby etc. Sin embargo aquí vamos a usar RSpec, que hace lo mismo pero......con una semántica diferente 1 http://en.wikipedia.org/wiki/list_of_unit_testing_frameworks Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 5 / 12
Hay una gran cantidad de frameworks para las pruebas unitarias 1 El framework de testeo más utilizado es JUnit, existente para una gran cantidad de lenguajes: Java, c++, php, python, ruby etc. Sin embargo aquí vamos a usar RSpec, que hace lo mismo pero......con una semántica diferente 1 http://en.wikipedia.org/wiki/list_of_unit_testing_frameworks Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 5 / 12
Hay una gran cantidad de frameworks para las pruebas unitarias 1 El framework de testeo más utilizado es JUnit, existente para una gran cantidad de lenguajes: Java, c++, php, python, ruby etc. Sin embargo aquí vamos a usar RSpec, que hace lo mismo pero......con una semántica diferente 1 http://en.wikipedia.org/wiki/list_of_unit_testing_frameworks Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 5 / 12
Sección Actual: Tests Ejemplo de tests 1 Tests Ejemplo de tests Rspec Rspec: ejercicio práctico Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 6 / 12
Ejemplo de tests A continuación vamos a ver el ejemplo en el que se prueba una clase User que tiene un accessor para el nombre class UserTest < Test::Unit::TestCase def setup @user = User.new def test_name_setter assert_nil @user.name, "Nombre no inicializado debe ser nulo." @user.name = "Chuck" assert_equal @user.name, "Chuck", "El nombre debería ser Chuck." Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 7 / 12
Ejemplo de tests A continuación vamos a ver el ejemplo en el que se prueba una clase User que tiene un accessor para el nombre class UserTest < Test::Unit::TestCase def setup @user = User.new def test_name_setter assert_nil @user.name, "Nombre no inicializado debe ser nulo." @user.name = "Chuck" assert_equal @user.name, "Chuck", "El nombre debería ser Chuck." Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 7 / 12
Ejemplo de tests Lo mismo, en RSpec define "User" do before(:each) do @user = User.new it "deberia asignar un valor al nombre mediante el accessor" do @user.name.should be_nil @user.name = "Chuck" @user.name.should equal "Chuck" Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 8 / 12
Ejemplo de tests Lo mismo, en RSpec define "User" do before(:each) do @user = User.new it "deberia asignar un valor al nombre mediante el accessor" do @user.name.should be_nil @user.name = "Chuck" @user.name.should equal "Chuck" Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 8 / 12
Sección Actual: Tests Rspec 1 Tests Ejemplo de tests Rspec Rspec: ejercicio práctico Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 9 / 12
Rspec Un test en Rspec trata de describir la funcionalidad de una clase con una semántica legible En los usos normales de Rspec, dentro del propio test se require la clase que queremos testear Cada fichero en Rspec, hará todas las comprobaciones de funcionalidad necesarias para una única clase Rspec tiene jerarquía dentro de las definiciones de tests, definidas mediante describe, context y it Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 10 / 12
Rspec Un test en Rspec trata de describir la funcionalidad de una clase con una semántica legible En los usos normales de Rspec, dentro del propio test se require la clase que queremos testear Cada fichero en Rspec, hará todas las comprobaciones de funcionalidad necesarias para una única clase Rspec tiene jerarquía dentro de las definiciones de tests, definidas mediante describe, context y it Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 10 / 12
Rspec Un test en Rspec trata de describir la funcionalidad de una clase con una semántica legible En los usos normales de Rspec, dentro del propio test se require la clase que queremos testear Cada fichero en Rspec, hará todas las comprobaciones de funcionalidad necesarias para una única clase Rspec tiene jerarquía dentro de las definiciones de tests, definidas mediante describe, context y it Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 10 / 12
Rspec Un test en Rspec trata de describir la funcionalidad de una clase con una semántica legible En los usos normales de Rspec, dentro del propio test se require la clase que queremos testear Cada fichero en Rspec, hará todas las comprobaciones de funcionalidad necesarias para una única clase Rspec tiene jerarquía dentro de las definiciones de tests, definidas mediante describe, context y it Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 10 / 12
Rspec Tomando como ejemplo el módulo de log desarrollado en la clase anterior, vamos a definir tests para las clases que lo incluyan Vamos a empezar por comprobar el chequeo de errores: require logger-class describe ClaseA do context "medidas de seguridad" do # Esto se ejecutará antes de cada test dentro de este contexto before(:each) do # Esto se ejecutará despues de cada test dentro de este contexto after(:each) do it "debe levantar ArgumentError si el nivel no existe" do it "debe levantar una excepcion si no hay permisos" do Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 11 / 12
Rspec Tomando como ejemplo el módulo de log desarrollado en la clase anterior, vamos a definir tests para las clases que lo incluyan Vamos a empezar por comprobar el chequeo de errores: require logger-class describe ClaseA do context "medidas de seguridad" do # Esto se ejecutará antes de cada test dentro de este contexto before(:each) do # Esto se ejecutará despues de cada test dentro de este contexto after(:each) do it "debe levantar ArgumentError si el nivel no existe" do it "debe levantar una excepcion si no hay permisos" do Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 11 / 12
Rspec Tomando como ejemplo el módulo de log desarrollado en la clase anterior, vamos a definir tests para las clases que lo incluyan Vamos a empezar por comprobar el chequeo de errores: require logger-class describe ClaseA do context "medidas de seguridad" do # Esto se ejecutará antes de cada test dentro de este contexto before(:each) do # Esto se ejecutará despues de cada test dentro de este contexto after(:each) do it "debe levantar ArgumentError si el nivel no existe" do it "debe levantar una excepcion si no hay permisos" do Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 11 / 12
Rspec Lo primero es indicar que para cada test, queremos tener una instancia de nuestra clase ClaseA que incluye el módulo require logger-class describe ClaseA do context "medidas de seguridad" do # Esto se ejecutará antes de cada test dentro de este contexto before(:each) do @obj = ClaseA.new # Esto se ejecutará despues de cada test dentro de este contexto after(:each) do it "debe levantar ArgumentError si el nivel no existe" do it "debe levantar una excepcion si no hay permisos" do Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 12 / 12
Rspec Definimos el comportamiento que esperamos de la clase cuando reciba etiquetas no válidas require logger-class describe ClaseA do context "medidas de seguridad" do # Esto se ejecutará antes de cada test dentro de este contexto before(:each) do @obj = ClaseA.new # Esto se ejecutará despues de cada test dentro de este contexto after(:each) do it "debe levantar ArgumentError si el nivel no existe" do expect { @obj.log(:warnrn, "x") }.to raise_error(argumenterror) it "debe levantar una excepcion si no hay permisos" do Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 12 / 12
Rspec Y definimos el comportamiento que esperamos cuando no se pueda abrir el fichero de logs require logger-class describe ClaseA do context "medidas de seguridad" do # Esto se ejecutará antes de cada test dentro de este contexto before(:each) do @obj = ClaseA.new # Esto se ejecutará despues de cada test dentro de este contexto after(:each) do it "debe levantar ArgumentError si el nivel no existe" do expect { @obj.log(:warnrn, "x") }.to raise_error(argumenterror) it "debe levantar una excepcion si no hay permisos" do @obj.logfile = "/fichero" expect { @obj.log(:warn, "x") }.to raise_error(exception) Pedro Navajas Modelo (UCO) Curso de Ruby Aula de Software Libre 12 / 12