jueves, 17 de febrero de 2011

BDD y descargas de ficheros auto-generados

La semana pasada, Tom y yo necesitábamos comprobar que un informe se descargaba correctamente desde la aplicación. Dicho informe era una hoja excel generada a partir de los datos contenidos en la base de datos. ¿Os interesa saber cómo lo hicimos? Os lo voy a contar con un ejemplo algo más simple :D

Escenario

Empecemos creando un escenario en cucumber. Queremos descargar un catálogo de productos generado por nuestra aplicación:
Given a "XBox" with a price of "250€"
When I ask for the catalogue
Then I can see in the catalogue a "XBox" with a price of "250€"
view raw file.feature hosted with ❤ by GitHub


Steps
El given simplemente crea un producto en el sistema y el when descarga el catálogo:

Given /^a "([^"]*)" with a price of "([^"]*)"$/ do |product, price|
Product.create(:name => product, :price => price)
end
When /^I ask for the catalogue$/ do
visit products_path
click_link "Catalogue"
end


Muy bien, hemos descargado el fichero al pulsar el enlace pero, ¿cómo accedemos a dicho fichero cuando estoy usando capybara y rack-test? Se me ocurren dos cosas. La primera es usar selenium en lugar de rack-test, haciendo que nuestros tests sean muuucho más lentos. La otra es obtener el bytestream del fichero descargado que, por si no lo sabíais, está en el body de la página obtenida tras hacer click en el enlace de descarga:

Then /^I can see in the catalogue a "([^"]*)" with a price of "([^"]*)"$/ do |product, price|
page.body.should =~ Regexp.new("#{product} - #{price}")
end


Esto tan simple funciona porque, en nuestro caso, estamos descargando un fichero de texto plano. Si en lugar de un texto plano tenemos, por ejemplo, un fichero Excel solo necesitamos parsear los bytes que nos llegan en el body con un objeto que entienda el formato Excel. Nosotros utilizamos la gema Spreadsheet (Cuidado con pronunciarlo spred-shit que queda muy feo :P )

Then /^I can see in the catalogue a "([^"]*)" with a price of "([^"]*)"$/ do |product, price|
first_row(page.body).should =~ Regexp.new("#{product} - #{price}")
end
def first_row(stream)
#Stuff to read an excel file
#Stuff to get the first line of the excel spreadsheet
end
view raw then_excel.rb hosted with ❤ by GitHub


¡Esto es todo, amigos! Un saludo

No hay comentarios:

Publicar un comentario