Enlaces e información

Comenta lo que creas oportuno.


Otros posts
Un WTF para variar
Document-oriented Databases

Testeo paranóico de JSON con Cucumber

Escrito por Roberto M. Oliva en Julio 30th, 2009

Estoy aprendiendo Cucumber y se que no esta pensado directamente para lo que aquí voy a exponer pero me resultó muy gratificante ver como de una manera muy sencilla se puede testear cualquier JSON devuelto por nuestros servicios REST. Se puede testear, con una sintáxis muy efectiva y clara hasta la última entrada de datos.

Por ejemplo, de manera muy sencilla, quiero testear un servicio que me devuelve una lista de registros de una tabla denominada ‘datos’ que contiene dos campos: ‘id’ y ‘nombre’. Si metemos dos registros el servicio REST de listarlos nos va a devolver un JSON como el siguiente:

[
{datos:{nombre:"Prueba1",id:"1"},
{datos:{nombre:"Prueba2",id:"2"},
]

No tiene mucho misterio, es un array con dos elementos. Pero lo que sí es sorprendente, si nos lo montamos bien, es lo claro que puede llegar a ser la definición de la feature de Cucumber:

	Scenario: Listing elements of type Datos
		Given a data with name "Prueba1"
		And a data with name "Prueba2"
		When I list "datos"
		Given the json reponse
			Then the json must contain "2" elements
			Given the "1" element of the json array
				Then the json element should contain the "datos" key
				Given the "datos" key of the json hash
					Then the json element should contain the keys: "id, nombre"
					And the json element should contain the key "id" with value "1"
					And the json element should contain the key "nombre" with value "Prueba1"
		Given the json reponse
			And the "2" element of the json array
				Then the json element should contain the "datos" key
				Given the "datos" key of the json hash
					Then the json element should contain the keys: "id, nombre"
					And the json element should contain the key "id" with value "2"
					And the json element should contain the key "nombre" with value "Prueba2"

Lo único que se puede advertir aquí es que no tiene mucho sentido testear los id’s ya que van a cambiar seguro de testeo a testeo, pero lo dejo como ejemplo de que se pueden testear más campos.
Como se ve queda un feature totalmente legible y que testea completamente el JSON devuelto.

La clave de todo esto está en los steps definidos para testear el JSON. De manera genérica un JSON contiene sólo arrays y hashes. Los primeros contienen elementos y los segundos claves de elementos. Los elementos a su vez pueden ser arrays o hashes también y así indefinidamente. Por lo tanto los pasos se reducen a:
- Seleccionar un elemento de un array o de un hash.
- Contar cuantos elementos tiene un array o un hash.
- Ver si un hash tiene una clave determinada.
- Ver el valor de la clave del hash.

Un ejemplo de dichos steps es el código siguiente:

Given /^the json reponse$/ do
  @json_sel_element = ActiveSupport::JSON.decode(@response.body)
end

Given /^the "([^"]*)" key of the json hash$/ do |key|
  @json_sel_element = @json_sel_element[key]
end

Then /^the json must contain "([^"]*)" elements$/ do |num_elements|
  @json_sel_element.size.should == num_elements.to_i
end

Given /^the "([^"]*)" element of the json array$/ do |num_element|
  @json_sel_element = @json_sel_element[num_element.to_i-1]
end

Then /^the json element should contain the "([^"]*)" key$/ do |key|
  @json_sel_element.keys.should include(key)
end

Then /^the json element should contain the key "([^"]*)" with value "([^"]*)"$/ do |key, value|
  @json_sel_element[key].should == value
end

Then /^the json element should contain the key "([^"]*)" with a null value$/ do |key|
  @json_sel_element[key].should be_nil
end

Then /^the json element should contain the key "([^"]*)" with a not null value$/ do |key|
  @json_sel_element[key].should_not be_nil
end

Then /^the json element should contain the keys: "([^"]*)"$/ do |keys|
  k = keys.split(",")
  k.each do |key|
    And %{the json element should contain the "#{key.strip}" key}
  end
end

Al final he escrito esto un poco rápido (me cuesta encontrar un hueco) lo remataré en breve. Pero para abrir boca no está nada mal…



Escriba un comentario

Dediquele un momento a comentar lo que piensa. Esta permitido usar HTML básico para formatear el escrito.

Comentarios de los lectores

Sea el primero en dejar un comentario.