18 Mayo 2009
Con tres kilos y seiscientos gramos repartidos a lo largo de cincuenta y un centímetros, el pasado miércoles a las doce y treinta y cinco de la mañana Iria se dejó abrazar por primera vez como si tal cosa.
Yo sin embargo no podía dejar de babear de nuevo ante semejante maravilla.
Más amor a dolor.
servido por Fernando
14 comentarios
compártelo
16 Enero 2009
Es lo que tiene ser un early-adopter: has de volver a aprender una y otra vez lo que pensabas que ya sabías.
Resulta que estas navidades me actualice la versión de Cucumber y para mi sorpresa dos cosas que me parecían muy útiles ya no estaban ahí.
La primera fue la opción de línea de comandos --line que tenía cucumber. Con ésta podías lanzar un escenario concreto facilitando su línea, la cual te devolvía el propio cucumber en su salida estándar. Es decir, que ya no podía hacer:
$ cucumber
Característica: [...]
Escenario: Saludo universal # features/saludo.feature:7
[...]
$ cucumber features/saludo.feature --line 7
optparse.rb:1443:in `complete': invalid option: --line (OptionParser::InvalidOption)
... para lanzar el escenario "Saludo universal". La aparente alternativa que tenía era utilizar la opción --scenario pasándole dicho literal ('Saludo universal') como valor. Pero me resultaba mucho más incómodo. Qué raro...
La segunda llegó poco después y estaba relacionada con la salida generada por cucumber al ejecutar las features. En la nueva versión en lugar de subrayar los parámetros de cada paso los resaltaba con el mismo color que el resto del texto, pero más brillante. Es decir, antes tenía:
Dado que tenemos dos huertos cuyas áreas son "34 y 27"
Ahora me encontraba:
Dado que tenemos dos huertos cuyas áreas son "34 y 27"
El problema que me generaba este cambio es que, al no poder destacarse los espacios en blanco, cuando tenía dos parámetros contiguos no sabía donde terminaba el primero y comenzaba el segundo. En el ejemplo anterior, no sabía si el primer parámetro era dos o dos huertos. Otra vez, qué raro... no era posible que la cosa estuviese yendo hacia atrás. Algo me estaba perdiendo.
Como estaba en plenas vacaciones decidí aparcar el asunto hasta que antes de ayer decidí investigar un poco más en el asunto.
Empecé por lo de la opción --line y la primera en la frente. Mandé un correo a la lista de usuarios RSpec (donde también están los de Cucumber) y dos personas (Matt Wynne y el propio Aslak que está al quite el tío) me dijeron lo que debería haber visto yo solito en la primera línea de la información de uso de cucumber:
$ cucumber --help
Usage: cucumber [options] [[FILE[:LINE[:LINE]*]] [...]
Es decir, ahora la línea (o líneas) se indica después del nombre del archivo precedida de dos puntos. Es decir, ahora podemos directamente copiar y pegar la salida de cucumber (en el ejemplo features/saludo.feature:7) y tirar millas. Muuucho mejor.
La segunda, la de los parámetros subrayados, por tratarse de algo que directamente consideraba un paso hacia atrás, decidí moverlo directamente como un ticket en Lighthouseapp.
En menos de una hora Aslak había respondido y cerrado el ticket:
There is no underline on Windows, so I decided to use a default formatting that works on across OSes. You can get underlines back by defining CUCUMBER_COLORS.
Y terminaba facilitándome el enlace a la página del wiki que también debería haberme leído antes de pedir por esta boquita.
Así es que he añadido la siguente línea en mi .bashrc y ya tengo lo que tenía:
export CUCUMBER_COLORS="passed_param=green,bold,underline:failed_param=red,bold,underline:skipped_param=cyan,bold,underline"
Dos "tolaaaay!" en un mismo día. Tenía que contarlo.
servido por Fernando
sin comentarios
compártelo
30 Noviembre 2008
Mi intención inicial era contar más en detalle cómo echar a correr un navegador con nuestras features de Cucumber vía Webrat y Selenium. Después de la charla en la Conferencia Rails varias personas se han puesto en contacto con nosotros para contarnos sus dificultades a la hora de conseguir dicho objetivo.
Sin embargo en este caso, por suerte, no es tan fácil como escribir un post o dar una charla sobre el asunto. Ésta misma semana Bryan Helmkamp ha estado subiendo cambios a Webrat que harán que tanto parte de lo que contamos en la conferencia como todo lo que yo pretendía contar en este post sea, si no ruido, sí, al menos, algo totalmente prescindible en una primera toma de contacto.
Dichos cambios están siendo la solución "oficial" a dichos problemas, que son básicamente tres:
- Lanzar el servidor de Selenium-RC (o Selenium Grid)
- Lanzar la versión actual de nuestra aplicación (y pararla cuando terminen los tests)
- Embeber la sesión de Selenium dentro de la API de Webrat (para que la definición de un step sea independiente del tipo de sesión)
De momento no hay (o yo no he encontrado) nada de documentación, pero echando un ojillo al código he visto que ha cambiado la dependencia de la gema del cliente de Selenium (selenium-client en lugar de Selenium como hasta ahora) y que para lanzar el servidor de Selenium-RC lo busca en vendor/selenium-server.jar.
También he visto que, por ahora, la mayoría de las opciones (navegador que queremos lanzar, puerto para nuestra apliación, ubicación del servidor de Selenium, etc.) están metidas "a fuego" sin posibilidad de alterarlas desde fuera. Pero seguro que esto último no tarda en cambiar.
Al igual que el RSpec Story Runner fue un entorno crudo en el que muchas carencias eran resueltas por cada cual a su manera, me da la sensación de que Webrat con Selenium está justo cambiando de color y que en poco tiempo estará maduro y listo para ser disfrutado sin indigestiones.
Go Brynary, Go!
http://www.brynary.com
servido por Fernando
1 comentario
compártelo
21 Noviembre 2008
Este año he tenido la suerte de participar y disfrutar "sin preocupaciones" de la Conferencia Rails. El año pasado me pilló empantanado en medio de un proyecto y no pude saborear el momento como lo he hecho en esta edición.
Si no pudisteis asistir u os perdisteis alguna ponencia aquí están los vídeos de todas las charlas. Me gustaron muchas de las que vi, pero si tuviese que recomendar sólo dos de ellas, dada mi devoción por el testing, estas serían la de CI de Calavera y la de BDD de Jorge y Luismi.
En lo que a nuestra charla respecta comentar que nos lo pasamos muy bien tanto en su preparación como en su ejecución final. Raimond y yo nos conocimos en persona el domingo anterior a la presentación y tras cuatro largas noches de risas y buenas intenciones nos dimos cuenta de que teníamos demasiado material para 40 minutos. Pero no sabíamos que quitar, así es que lo que hicimos fue poner la parte de "deseos" y la de "tips" al final de la presentación. Y mira tu por donde fueron estas justamente las que al final se quedaron fuera.
Pero la verdad es que terminado con las clásicas traspas de "Ventajas e Inconvenientes" nos quedamos muy satisfechos, sobre todo después de descubrir que... ¡nos estaban pasando las slides desde la cabina de control!.
Sin duda hubiésemos podido llegar más lejos si hubiésemos pasado las traspas nosotros mismos, ya que teníamos varias agrupadas que la idea era pasarlas rapiditas, en plan animación chuflillas. Pero vamos, que bastante bien quedó la cosa dada la situación. Aquí tenéis el vídeo por si os apetece echaros unas risas.
Y eso sí, no quiero terminar este post sin dar las gracias a todas y todos los que se lo curraron para hacer posible el evento. Otra vez, ¡gracias!
servido por Fernando
sin comentarios
compártelo
2 Octubre 2008
Intro y preámbulos
Todas las opiniones que había leído sobre Cucumber eran buenas, muy buenas. Y cuando el río suena, agua lleva... mi primer contacto con el substituto del RSpec Story Runner ha sido toda una gozada.
Utilizando como referencia su documentación oficial para uso con Rails me puse manos a la obra con un objetivo bastante sencillo: el clásico "Hola mundo", pero en su versión BDD y utilizando castellano en las especificaciones.
Antes de nada instalamos las dependencias que tiene Cucumber. Por un lado, como root, cuatro gemas:
# gem install term-ansicolor treetop diff-lcs hpricot
Y por otro cuatro plugins dentro de nuestra aplicación, a la que cariñosamente llamaremos "Saludeitor":
rails saludeitor
cd saludeitor
git clone git://github.com/aslakhellesoy/cucumber.git vendor/plugins/cucumber
git clone git://github.com/brynary/webrat.git vendor/plugins/webrat
git clone git://github.com/dchelimsky/rspec.git vendor/plugins/rspec
git clone git://github.com/dchelimsky/rspec-rails.git vendor/plugins/rspec-rails
(Si tenemos nuestra aplicación en un repositorio de git podemos incorporar los plugins como submódulos cambiando git clone por git submodule add, tal y como proponen en la documentación oficial)
Acto seguido preparamos el proyecto para que admita la definición de features (o características, como finalmente han sido traducidas en la implementación actual) con la ayuda del generador de Cucumber:
@nube01:~/src/saludeitor$ script/generate cucumber
create features/steps
create features/steps/env.rb
create features/steps/common_webrat.rb
exists lib/tasks
create lib/tasks/cucumber.rake
create script/cucumber
El fichero features/steps/common_webrat.rb implementa las interacciones de navegación típicas, pero las define para features escritas en inglés. No lleva mucho tiempo substituir dichas definiciones por sus equivalentes en castellano de tal forma que, por ejemplo:
When /^I fill in "(.*)" with "(.*)"$/ do |field, value|
When /^relleno el campo "(.*)" con "(.*)"$/ do |field, value|
(Este es mi common_webrat.rb en castellano, por si tienes prisa ;)
Cucumber "flow"
Bueno, ya lo tenemos todo listo para empezar a tirar líneas, eso sí, como esto es "BiDiDí" las tiraremos primero describiendo comportamiento... y como esto es Cucumber, lo haremos de tal forma que nuestra madre pueda participar también si le da por ahí. Creamos pues un archivo features/saludo.feature y escribimos algo como:
Característica: Saludo
Para sentirse como en su casa
Un usuario
Debería recibir un saludo
Escenario: Saludo universal
Cuando visito la portada
Entonces debería ver "¡Hola amigo!"
Bien, ya tenemos una especificación. Si le pedimos a Cucumber que compruebe si nuestra aplicación la cumple tenemos muchas posibilidades de que no lo haga. Pero vamos a hacerlo para ver por qué se queja y comenzar a sentir el "flow" ;)
Para lanzar únicamente un fichero de features utilizamos script/cucumber, y para que las interprete en castellano le metemos el parámetro --language, tal que:
$ script/cucumber --language es features/saludo.feature
A lo que, si nuestra aplicación esta "pelá-y-mondá" como el script de Rails la trajo la mundo, Cucumber responderá:
Característica: Saludo
Para sentirse como en su casa
Un usuario
Debería recibir un saludo
Escenario: Saludo universal
Cuando visito la portada
No route matches "/" with {:method=>:get} (ActionController::RoutingError)
[...]
1 step failed
1 step skipped
Con colores muy chulos a la par que apropiados: el principio en verde, justo hasta "Cuando visito la portada" que aparece en rojo junto con el volcado del error, los pasos pendientes de implementar en amarillo (para los que al final nos ofrece una plantilla de su definición que facilite su implementación) y los que se ha saltado por un error en azul.
Además tiene el detalle de subrayar lo que son los valores de los parámetros que recibirá la función que implementa el paso (en este caso "la portada"), lo que nos permite distinguirlos fácilmente de la parte fija de sus definiciones ("Cuando visito").
Bien, pues vamos modificar nuestra aplicación para que salga todo verde verde... ¡tan verde como un pepino!
Editamos el config/routes.rb y descomentamos la línea:
map.root :controller => "welcome"
Y acto seguido creamos dicho controlador con la acción index:
$ script/generate controller Welcome index
Volvemos a lanzar nuestra feature y:
$ script/cucumber --language es features/saludo.feature
Característica: Saludo
Para sentirse como en su casa
Un usuario
Debería recibir un saludo
Escenario: Saludo universal
Cuando visito la portada
Entonces debería ver "¡Hola amigo!"
expected: /¡Hola amigo!/m,
got: "<h1>Welcome#index</h1>\n<p>Find me in app/views/welcome/index.html.erb </p>\n"
[...]
¡Se resiste el bribón! Bien, ahora nos dice que no encuentra por ninguna parte "¡Hola amigo!". Editamos app/views/welcome/index.html.erb y cambiamos el contenido de su H1 por dicho saludo. Volvemos a lanzar Cucumber y...
Característica: Saludo
Para sentirse escuchado
Un usuario
Debería poder recibir un saludo
Escenario: Saludo universal
Cuando visito la portada
Entonces debería ver "¡Hola amigo!"
2 steps passed
¡todo verdecico! ¡cómo un pepino! (aunque pueda parecer lo contrario, dice Aslak que el nombre de Cucumber no significa nada y que se le ocurrió porque en el momento que comenzó a desarrollarlo su chica se estaba comiendo un sandwich de pepino).
Bien, vamos a meterle un poco más de chicha a la aplicación (lo que viene siento volver a iterar para comenzar a sentir el "flow"). Metemos un segundo escenario en saludo.feature:
Escenario: Saludo personal
Cuando visito la portada
Y completo "Nombre" con "Pepino"
Y pulso el botón "Enviar"
Entonces debería ver "¡Hola Pepino!"
Y ahora Cucumber nos dice:
Característica: Saludo
Para sentirse escuchado
Un usuario
Debería poder recibir un saludo
Escenario: Saludo universal
Cuando visito la portada
Entonces debería ver "¡Hola amigo!"
Escenario: Saludo personal
Cuando visito la portada
Y completo "Nombre" con "Pepino"
Could not find [Webrat::TextField, Webrat::TextareaField, Webrat::PasswordField]: "Nombre" (RuntimeError)
[...]
./features/steps/common_webrat.rb:13:in `Y /^completo "(.*)" con "(.*)"$/'
features/saludo.feature:12:in `Y completo "Nombre" con "Pepino"'
Y pulso el botón "Enviar"
Entonces debería ver "¡Hola Pepino!"
3 steps passed
1 steps failed
2 steps skipped
No encuentra en el HTML de la página el campo "Nombre". De hecho no tiene tampoco el botón "Enviar". Añadimos a app/views/welcome/index.html.erb el siguiente formulario (sé que no es nada Rails, pero es sólo un ejemplo):
<form action="/">
<input type="text" name="Nombre" />
<input type="submit" value="Enviar" />
</form>
Lo lanzamos y ahora Cucumber se queja en la última línea, en la que decimos que deberíamos ver "¡Hola Pepino!". En este momento nuestra aplicación muestra siempre "¡Hola amigo!". Retocamos el H1 de app/views/welcome/index.html.erb y lo dejamos tal que:
<h1>¡Hola <%= params[:Nombre] || 'amigo' %>!</h1>
Y ahora sí que sí, lo lanzamos y Cucumber nos dice que tenemos... ¡todo un pepino!:
Característica: Saludo
Para sentirse como en su casa
Un usuario
Debería recibir un saludo
Escenario: Saludo universal
Cuando visito la portada
Entonces debería ver "¡Hola amigo!"
Escenario: Saludo personal
Cuando visito la portada
Y completo "Nombre" con "Pepino"
Y pulso el botón "Enviar"
Entonces debería ver "¡Hola Pepino!"
6 steps passed
Fit tables
Las Fit tables fueron inventadas allá por 2002 por (ni más ni menos que) Ward Cunningham y han sido implementadas en Cucumber para evitar la repetición de escenarios.
En nuestra aplicación podríamos, por ejemplo, añadir una Fit tables en el segundo escenario que agilizase la especificación de nuevos comportamientos. Simplemente añadimos después del escenario su tabla. En nuestro caso:
Característica: Saludo
Para sentirse como en su casa
Un usuario
Debería recibir un saludo
Escenario: Saludo universal
Cuando visito la portada
Entonces debería ver "¡Hola amigo!"
Escenario: Saludo personal
Cuando visito la portada
Y completo "Nombre" con "Pepino"
Y pulso el botón "Enviar"
Entonces debería ver "¡Hola Pepino!"
| lugar | campo | valor | botón | mensaje |
| la portada | Nombre | Nando | Enviar | ¡Melenas! |
La primera fila de la tabla sólo sirve para poner un nombre descriptivo a cada uno de los parámetros manejados en el escenario (qué son los que Cucumber nos ha subrayado al interpretarlo). Al ver esta tabla Cucumber volvería a comprobar los pasos del escenario pero pasándoles los valores indicados en la tabla en lugar de los utilizados en el mismo (y tal y como tenemos el Saludeitor en este momento fallaría porque a "Nando" le responde con "¡Hola Nando!" y no con "¡Melenas!").
Tuneando la tarea de rake
Por último, comentar que para que la tarea de rake cucumber interprete las features en castellano tenemos que modificar el lib/tasks/cucumber.rake añadiéndole en las cucumber_ops el parámetro --language tal y como hacemos al lanzarlo desde la línea de comandos. Quedaría algo como:
...
t.cucumber_opts = "--format pretty --language es"
...
Esto es todo, suerte con él y consumirlo con moderación para que no os repita ;)
¡Salud!
servido por Fernando
7 comentarios
compártelo
14 Agosto 2008
Si lo llega a hacer premeditadamente seguro que no le sale. El pasado jueves día 7, coincidiendo con el día en el que cumplía mis treinta y cinco agostos, Aslak mandaba el siguiente correo a la lista de desarrollo de RSpec:
[ANN] Cucumber
Nice vegetable, nice tool.
It's my reimplementation of the story runner, addressing several
shortcomings of the current one. And I'm calling them features instead
of stories now, because that is what they are.
http://github.com/aslakhellesoy/cucumber/ (The home page)
http://gojko.net/2008/08/06/cucumber-next-generation-ruby-bdd-tool/
(Thanks Gojko)
Take a look - it's taking shape.
Aslak
Una de la principales virtudes del Cucumber de Aslak frente al Story Runner de RSpec es la posibilidad de escribir las "plain text stories" en cualquier idioma.
Lo cachondo del asunto es que Aslak tiene asignada la implementación de dicha funcionalidad dentro de RSpec desde que la solicité a primeros de año junto con el parche para la versión de aquel momento y, como no, su "plain text story" asociada:
Story: Writting stories in other languages
As a non-english RSpec developer
I want to write stories in my mother tongue
So that I don't have to make an extra effort to know what's going on
Scenario: Pending
Given the file stories/plain_text_story_in_spanish.rb
When I run it with the ruby interpreter
Then the exit code should be 0
And the stdout should match /1 scenarios: 0 succeeded, 0 failed, 1 pending/m
And the stdout should match /4\) La portada de Mi Sitio en La Red/
Scenario: Succeed
Given the file stories/plain_text_story_in_spanish_with_steps.rb
When I run it with the ruby interpreter
Then the exit code should be 0
And the stdout should match /1 scenarios: 1 succeeded, 0 failed, 0 pending/m
Era muy excitante ver como la versión sin el parche fallaba al ejecutarla y la parcheada campaba triunfal. Adiós TODO ambiguo. Hola Spec-ificación formal.
Sin embargo la realidad es que ha llovido bastante desde aquello, y viendo que seguramente Aslak escribirá sus historias en noruego utilizando Cucumber, me da la sensación de que seguirá lloviendo durante mucho más hasta que dicha posibilidad exista en la versión oficial de RSpec.
Espero probar Cucumber pronto, pero mientras tanto no me queda más remedio que mantener el legado que tenemos actualmente utilizando el Story Runner de RSpec. Para ello me he creado una rama de RSpec y le he metido los cambios para el soporte multilenguaje.
En cualquier caso lo que está claro es que Aslak ha resuelto mi deseo y me lo ha presentado justo el día de mi cumple... Takk så mye!
blog.aslakhellesoy.com
servido por Fernando
3 comentarios
compártelo
17 Julio 2008
Llevaba tiempo con ganas de probar JRuby y Glassfish. También de jugar con Merb y de darle un poquito de alegría a la FreeBSD que tengo para trastear.
Hace algún tiempo me encontré con este post de Nodeta que parecía servirme para matar tres de los mencionados pájaros de un tiro.
Sólo me faltaba la información necesaria para mi cuarto y último deseo: hacerlo en FreeBSD. El post de Nodeta lo resolvía en Ubuntu, pero en principio lograrlo en FreeBSD no tenía porque ser demasiado complicado.
Pues la primera en la frente: los binarios de Glassfish estaban disponibles para un buen puñado de plataformas (Solaris, AIX, Window, MacOS y GNU/Linux) pero no para FreeBSD. Eso sí, para los más valientes Sun ofrece el repositorio de CVS con los fuentes.
Se me hacía la cosa un poco cuesta arriba pero no tardé en descubrir un post de Homer Yau, un empleado de Sun, que comentaba como se podía hacer la cosa.
Para instalar Merb, además de las gemas mencionadas en el post de Nodeta tuve que instalar las siguientes:
- mongrel
- builder
- haml
- ruby2ruby
Respecto a la instalación de GlassFish comentar que perdí bastante tiempo por no tener en cuenta la nota 4 del post de Homer. En la misma se menciona la posibilidad de establecer la versión concreta de los fuentes de GlassFish que nos vamos a bajar de Sun (la etiquetada como SJSAS90_FCS_BRANCH). Al bajarse una versión más modernas aparecian dependencias no resueltas no mencionadas en el post al hacer el paso 4 (maven build, en particular con el HK2 que parece ser la nueva base del nuevo GlassFish para hacerlo ligero ligero).
Ah! Por cierto, unas cuantas versiones, que nunca está de más:
- FreeBSD 7.0-RC3 (i386)
- Java 1.5.0 (diablo-jdk1.5.0-b01)
- JRuby 1.1.2 (metido a mano en /usr/local/jruby-1.1.2)
servido por Fernando
1 comentario
compártelo
20 Mayo 2008
O un poquito más castellano: "be_indexed: matcher de RSpec para el is_indexed de Ultrasphinx".
Con él podemos especificar como debe estar indexado nuestro modelo tal que:
describe MiModeloIndexadoConUltrasphinx do
include Spec::Ultrasphinx::Matchers
it do
MiModeloIndexadoConUltrasphinx.should be_indexed.using_fields([:campo_uno, :campo_dos]).with_delta
end
end
De momento sólo contempla sus opciones :fields y :delta (son las únicas que he necesitado por ahora).
Para utilizarlo colocar be_indexed a modo de plugin en vendor/plugins e incluirlo en nuestra spec como en el ejemplo de arriba.
Para utilizarlo en más de una spec podemos meterlo en nuestro spec_helper.rb así:
Spec::Runner.configure do |config|
config.include Spec::Ultrasphinx::Matchers
end
Para más ejemplos de uso ver su propia spec.
Descarga/download vía...
git clone git://github.com/nando/be_indexed.git
... desde su línea-de-comandos/command-line favorita.
servido por Fernando
sin comentarios
compártelo