Skip to content

Instantly share code, notes, and snippets.

@brenes
Last active April 3, 2019 14:54
Show Gist options
  • Save brenes/7b138e69443ca417a74502c0ec3f5614 to your computer and use it in GitHub Desktop.
Save brenes/7b138e69443ca417a74502c0ec3f5614 to your computer and use it in GitHub Desktop.
ideas charlas

Formación de crear gemas

¿Qué es una gema?

  • Librería de código
  • Relación con los proyectos
  • ¿Porqué trabajar con gemas?
  • ¿Cómo desarrollar con gemas?

Estructura básica de una gema

  • Metadatos y dependencias
  • Organización de código

    [ ] requires

Trabajo con gemas

  • Gem build
  • Bundle local
  • Manejo de dependencias
  • Ramas
  • Versionado
  • Rubygems

Testing

  • Aplicación Dummy
  • ¿Qué tests caen en una gema?
  • Soporte a versiones

Engines

  • Estructura
  • Generación (rails g engine)
  • Generadores y migraciones
  • Assets
  • Configuración e initializers

Contenidos

¿Porqué testing?

  • Aplicación predecible

    [ ] Te permiten saber si tu cambio está perdiendo una funcionalidad [ ] Te permiten detectar bugs que se reabren [ ] No vas a ciegas. Puedes saber como está la aplicación.

  • Ciencia Vs Fé

    [ ] Tu código es la teoría [ ] Los tests son los experimentos [ ] La realidad… es la realidad [ ] Como en ciencia, la idea es que se rompa

¿Porqué no testing?

  • Testing paralisis

    [ ] No toda funcionalidad merece ser testeada [ ] Testea el dinero [ ] Testea los puntos clave [ ] Decide qué merece la pena probar [ ] Involucra al cliente y sus prioridades

  • Suites de tests inmanejables

    [ ] Tengo 2.000 tests ¿y hacen falta? [ ] Unos tests que tardan 10 minutos, ¿son buenos? [ ] Poda de tests ¿Merece la pena testear relaciones entre modelos?

¿Cuando testing?

  • Tests localizados Vs Generales

    [ ] Durante el desarrollo testea ese desarrollo [ ] Durante la integración, testealo todo

¿Cómo testing?

  • TDD: Tests rápidos, manejables, incompletos.

    [ ] Se testean las piezas pequeñas [ ] Son tests normalmente rápidos [ ] El scope es pequeño, son más sencillos (no siempre) [ ] Las piezas pueden funcionar, pero el puzzle no. [ ] Al cliente le importa el puzzle

  • BDD: Tests completos, lentos, no fiables.

    [ ] Se testea la aplicación al completo [ ] Son tests tan lentos como tu aplicación (y algo más) [ ] Su scope es amplio y puede llevar más tiempo encontrar los errores [ ] Si el puzzle funciona, todo está bien [ ] Javascript, Capybara, Poltergeist

  • Cobertura de código

    [ ] Métrica engañosa [ ] Una línea cubierta no es una línea segura [ ] Una línea no cubierta sí que no es segura [ ] El porcentaje no debe bajar

  • Típicas recomendaciones

    [ ] Un test por método [ ] Un fichero por clase [ ] Un requisito por test

  • No sabemos arquitecturizar los tests

    [ ] Aplicaciones mantenibles [ ] Patrones de diseño [ ] Las suite de tests son un punto negro [ ] Lo primero en dejar de ser mantenido [ ] Lo hecho más aprisa

No hacemos tests

  • Y es culpa nuestra

    [ ] Los tests no son un extra [ ] Los tests no son una obligación [ ] Los tests también son código [ ] Si no tiene JS no está terminado [ ] Si no está testeado tampoco

  • Mis recomendaciones

    [ ] No sobretesteis [ ] Pero cuando haga falta, defendedlo a muerte [ ] Una carpeta por clase/funcionalidad [ ] Un fichero por contexto general de test [ ] Los requisitos necesarios por tests, no más, no menos.

RSPEC

  • DSL de testing

    [ ] Enfoque distinto a otros testing (JUnit) [ ] Se abstrae de métodos, clases, etc. [ ] Maneja contextos y escenarios de código (no de la aplicación entera)

  • Define contextos para los tests (describe/context)

    [ ] Tiene una descripción [ ] Describen un contexto, normalmente en la forma “when X is happening”, “when the user does Y”, “when we Z” [ ] Son anidables [ ] No llevan código a testear [ ] Normalmente, un describe con context anidados

  • Define escenarios (it)

    [ ] Tienen otra descripción [ ] Describen lo que se espera que suceda, normalmente algo como “should notify X”, “should show Y to the user”, “should create Z” [ ] No son anidables [ ] Llevan el código a testear [ ] Puede haber varios en un mismo context [ ] Es el punto de ejecución

  • Tests iterativos (rspec-steps)

    [ ] Dos its son dos ejecuciones [ ] Puede tener sentido ejecutar un test tras otro, no en paralelo [ ] En un funnel, testear paso a paso la ejecución normal [ ] Fallos más granulares [ ] Te echo de menos cucumber [ ] Escenarios muy particulares en un único paso

  • Define requisitos (expect)

    [ ] Pueden tener un mensaje asociado al error [ ] Especifican una condición a nivel de código y datos que debe cumplirse [ ] expect(…).to condition [ ] expect(UserNotification.last.message).to eq message [ ] expect(page).to have_content message [ ] expect(Z.count) to eq 1

  • Define datos (let, let! y subject)

    [ ] let: Memoiza ejecución de código [ ] Se usa para definir objetos que tendrán relevancia en el test [ ] Se ejecuta la primera vez que se le llama [ ] let!: Fuerza la ejecución antes de empezar el test [ ] Permite cargar datos en la BD sin tener que llamar a muchos lets [ ] subject: Define el sujeto del test [ ] Antes permitía definir escenarios y requisitos más fácilmente [ ] Te permite dejar claro el foco del test

  • Define código de inicialización y finalización

    [ ] before/after: Código que se ejecuta antes/después del escenario [ ] :each/:all: Una vez por escenario / Una vez en global [ ] con let! se minimiza su uso

  • Define metadatos

    [ ] Meta información para contextos y escenarios [ ] Se puede leer en before/afters [ ] Caso UE: Tests responsive

  • Y con todo esto

    [ ] Ejemplo de test [ ] Ejemplo de ejecución

FactoryGirl y Faker

  • Permite definir datos de ejemplo

    [ ] Define campos “normales” [ ] Define relaciones [ ] Define campos únicos, con iteradores [ ] Te permite aislar la definición de datos, desde el test solo pides “un hotel con habitaciones y fotos”

  • Afinamiento de las factorías

    [ ] Distintos escenarios necesitan distintos datos [ ] Crear ‘n’ factorias para los distintos casos (hotel, hotel con habitaciones, hotel con fotos, hotel con habitaciones y fotos) [ ] Las factorías pueden heredar [ ] Crear una factoria y “traits” (hotel, con habitaciones, con fotos)

  • build, create, attributes_for

    [ ] build: crea el objeto, no lo guarda [ ] create: Crea el objeto y lo guarda [ ] attributes_for: Hash de atributos

  • Factory.create <> Model.create

    [ ] No sigue los pasos normales de ActiveRecord [ ] En ciertos casos puede no interesar

Mocks

  • Permiten falsear la respuesta de un método

    [ ] allow(class_or_instance).to receive(a_method).with(some_parameters).and_return(something) [ ] Puedes mockear la clase, una instancia en particular o todas las instancias [ ] mockeas método a método [ ] Los parámetros son opcionales. Permite devolver cosas distintas según el parámetro de entrada [ ] Te permite devolver lo que quieras

    allow(Product).to receive(:get_by_filters).with({:product_code=>product_code},true).and_return([product_2,product_3])

  • Permiten exigir la ejecución de un método

    [ ] expect(class_or_instance).to receive(a_method).with(some_parameters).and_return(something) [ ] Igual que el allow pero exige que se llame el método [ ] Permite especificar número de llamadas [ ] Útil para probar, por ejemplo, caché de fragmentos

  • Facilitan testear cajas negras

    [ ] No tienes que preocuparte de la otra parte [ ] Se necesita una interfaz definida entre las cajas [ ] Tests más rápidos [ ] Cambios en un lado no rompen el otro

  • Dependencias al crear los mocks

    [ ] Cambios en un lado no rompen el otro [ ] ¿Deberían? Falsos positivos [ ] Definición de interfaz entre cjas en muchos sitios

  • Mocks especiales

    [ ] Delorean o Timecop: Mock de Time.now para viajar en el tiempo

VCR

  • Mocks para peticiones de red

    [ ] Librería de mocks especializada en peticiones de red [ ] “Mockea” Net::HTTP [ ] Graba peticiones HTTP en JSON o YAML y luego las reproduce

  • Se graba una primera petición, luego se reproduce

    [ ] Exige una primera iteración sin mock [ ] Los ficheros vcr se generan y se meten al repo [ ] Los ficheros VCR se pueden crear o tocar a mano

  • Criteros de matching de requests

    [ ] Criterio de path [ ] Criterio de parámetros [ ] Criterio custom

  • Información enmascarada

    [ ] Passwords en peticiones [ ] Hace un find and replace de cadenas

  • Cómo grabar

    [ ] Se puede especificar dentro del it: VCR.use_cassette cassete_name { … } [ ] En los metadatos del contexto o el escenario

  • ¿Y si cambian los requisitos de la petición?

    [ ] Caso especial de problema de dependencias de mock [ ] Su parte puede cambiar sin previo aviso [ ] Desactivar mock [ ] Tenemos la prueba de que antes funcionaba

Reutilización de código (shared examples)

  • Ejemplo

    [ ] Permite definir un conjunto de contextos y escenarios reutilizables [ ] Puede recibir parámetros [ ] Lee datos de lets externos

CircleCI

  • circle.yml

    [ ] Ramas a testear [ ] Hooks para ejecutar procesos [ ] Caso clásico: secrets [ ] Personalización de tests a ejecutar ¿Suite de desarrollo? ¿Suite de integración?

  • Gestión en CircleCI

    [ ] Alta de repositorios [ ] Ejecuciones

  • Integración continua

    [ ] Testing en PR [ ] Ramas a testear

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment