Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Rspec
Code

Pruebas RSpec para principiantes, Parte 3

by
Length:LongLanguages:
This post is part of a series called RSpec Testing for Beginners.
RSpec Testing for Beginners, Part 2

Spanish (Español) translation by Elías Nicolás (you can also view the original English article)

En este artículo final sobre los fundamentos de RSpec, cubrimos algunas partes dudosas que puede y debe evitar, cómo debe componer sus pruebas, por qué debe evitar la base de datos tanto como sea posible y cómo acelerar su suite de pruebas.

Temas

  • Prueba de velocidad
  • Cuellos de botella de la base de datos
  • Precargador Spring
  • Las comodidades dudosas RSpec
  • Mystery Guests
  • Código en línea
  • Métodos de extracción

Ahora que usted tiene lo básico bajo su cinturón, debemos tomar el tiempo para discutir algunas partes dudosas de RSpec y TDD—algunos problemas que pueden ser fácilmente utilizados y algunas desventajas de usar partes de RSpec DSL no refleja. Quiero evitar rellenar un montón de conceptos avanzados en sus cerebros TDD recién nacidos, pero siento que algunos puntos deben hacerse antes de ir a su primera juerga de pruebas. Además, la creación de una suite de prueba lenta debido a los malos hábitos que son fácilmente evitables es algo que puede mejorar como principiante.

Claro, hay bastantes cosas que usted necesita para tener más experiencia con antes de que usted se sienta cómodo y eficaz con las pruebas, pero apuesto a que también se sentirá mejor desde el principio si usted quita algunas de las mejores prácticas que mejorarán su Especificaciones múltiples sin estirar sus habilidades demasiado ahora mismo. También es una pequeña ventana en los conceptos más avanzados que tendrá que recoger con el tiempo para "dominar" las pruebas. Siento que no debería molestarte demasiado al principio con estos porque podría apenas sentirse confuso y enrevesado antes de que usted haya desarrollado el cuadro más grande que ata todo junta cuidadosamente.

Prueba de velocidad

Vamos a empezar con la velocidad. Una suite rápida no es nada que suceda por accidente; Es una cuestión de mantenimiento "constante". Escuchar tus pruebas con mucha frecuencia es muy importante—al menos si estás a bordo con TDD y has estado bebiendo el Kool-Aid por un tiempo—y las suites de prueba rápidas hacen que sea mucho más razonable prestar atención a donde las pruebas están guiando tú.

La velocidad de la prueba es algo que debes cuidar. Es esencial hacer de la prueba un hábito regular y mantenerlo divertido. Desea ser capaz de ejecutar rápidamente sus pruebas para que obtenga comentarios rápidos mientras se está desarrollando. Cuanto más tiempo se tarda en ejercitar el conjunto de pruebas, más probable es que se saltea la prueba más y más hasta que sólo lo hacen al final antes de que desee enviar una nueva función.

Eso podría no sonar tan mal al principio, pero esto no es una cuestión trivial. Uno de los principales beneficios de una suite de pruebas es que guía el diseño de su aplicación—para mí esta es probablemente la mayor victoria de TDD. Los ensayos más largos hacen esta parte casi imposible porque es muy probable que no los ejecute para no romper su flujo. Las pruebas rápidas garantizan que no tienes ninguna razón para no ejecutar las pruebas.

Puede ver este proceso como un diálogo entre tu y tu conjunto de pruebas. Si esta conversación se vuelve demasiado lenta, es realmente doloroso continuar. Cuando su editor de código ofrece la posibilidad de ejecutar también sus pruebas, definitivamente debe hacer uso de esta característica. Esto aumentará drásticamente la velocidad y mejorará su flujo de trabajo. Cambiar cada vez entre su editor y una shell para ejecutar sus pruebas molesta. Pero ya que estos artículos están dirigidos a los programadores novatos, no espero que configurar sus herramientas como estas de inmediato. Hay otras maneras en que puede mejorar este proceso sin necesidad de jugar con su editor de inmediato. Es bueno saber, sin embargo, y recomiendo hacer que estas herramientas formen parte de su flujo de trabajo.

Además, tenga en cuenta que ya aprendió a dividir sus pruebas y que no necesita ejecutar la suite de pruebas completa todo el tiempo. Puede ejecutar fácilmente archivos individuales o incluso bloques it—todo dentro de un editor de código capaz sin tener que dejarlo para el terminal. Te puedes enfocar en la prueba de la línea bajo prueba, por ejemplo. Eso se siente mágico, para ser franco—nunca se vuelve aburrido.

Cuellos de botella de la base de datos

Escribir demasiado a la base de datos—a menudo muy innecesariamente así—es una forma segura de ralentizar rápidamente su suite de pruebas de manera significativa. En muchos escenarios de prueba, puede falsificar los datos que necesita para configurar una prueba y centrarse sólo en los datos que están directamente bajo prueba. No es necesario que accedas a la base de datos durante todo el tiempo la mayor parte del tiempo—especialmente para las partes que no están bajo prueba directamente y sólo soportan la prueba de alguna manera: un usuario conectado mientras estás probando la cantidad a pagar en un Checkout, por ejemplo. El usuario es como un extra que se puede falsificar.

Debes intentar alejarte de acceder a la base de datos tanto como sea posible porque ralentiza una suite de prueba. Además, trate de no configurar demasiados datos si no lo necesitas en absoluto. Eso puede ser muy fácil de olvidar especialmente con las pruebas de integración. Las pruebas unitarias suelen estar mucho más enfocadas por definición. Esta estrategia resultará muy eficaz para evitar que las series de prueba se desaceleren con el tiempo. Elija sus dependencias con mucho cuidado y vea cuál es la cantidad más pequeña de datos que hace que sus pruebas pasen.

No quiero entrar en detalles más específicos por ahora—probablemente es un poco demasiado temprano en su trayectoria para hablar de trozos, espías, falsificaciones y cosas así. Confundirlo aquí con conceptos tan avanzados parece contraproducente, y te encontrarás en estos pronto. Hay muchas estrategias para las pruebas rápidas que también implican otras herramientas que RSpec. Por ahora, trate de entender RSpec y las pruebas en general.

También quiere apuntar a probar todo sólo una vez—si es posible. No volver a probar lo mismo una y otra vez—eso es sólo un derroche. Esto ocurre principalmente por accidente y / o malas decisiones de diseño. Si empezó a tener pruebas que son lentas, este es un lugar fácil de refactorizar para obtener un aumento de velocidad.

La mayoría de sus pruebas también deben estar en el nivel de unidad, probando sus modelos. Esto no sólo mantendrá las cosas rápidas sino que también le proporcionará la mayor explosión por dólar. Las pruebas de integración que prueban flujos de trabajo completos—imitando el comportamiento del usuario hasta cierto punto al reunir un montón de componentes y probarlos de forma sincrónica—deberían ser la parte más pequeña de su pirámide de pruebas. Estos son bastante lentos y "caros". Tal vez el 10% de sus pruebas generales no es poco realista para apuntar—pero esto depende, supongo.

Ejercicio de la base de datos lo menos posible puede ser difícil, porque usted necesita aprender un buen número de herramientas y técnicas para lograr que con eficacia, pero es esencial para crecer suites de prueba que son razonablemente rápido—rápido suficiente para realmente ejecutar sus pruebas con frecuencia.

Precargador Spring

El servidor Spring es una característica de Rails y precarga su aplicación. Esta es otra estrategia sencilla para aumentar la velocidad de su prueba de forma significativa—Incorporada, debo añadir. Lo que hace es simplemente mantener la aplicación en ejecución en segundo plano sin necesidad de arrancar con cada prueba de ejecución. Lo mismo se aplica a las tareas y migraciones de Rake; Éstos funcionarán más rápidamente también.

Desde Rails 4.1, Spring se ha incluido en Rails—agregado al Gemfile automáticamente—y no es necesario hacer mucho para iniciar o detener este preloader. En el pasado tuvimos que conectar nuestras propias herramientas de elección para esto—que todavía puedes hacer, por supuesto, si tienes otras preferencias. Lo que es realmente agradable y reflexivo es que se reiniciará automáticamente si cambia algunas gemas, inicializadores o archivos de configuración—un toque agradable y práctico porque es fácil olvidarse de cuidarlo.

De forma predeterminada, está configurado para ejecutar únicamente los comandos rails y rake. Por lo tanto, tenemos que configurarlo para que también se ejecute con el comando rspec para ejecutar nuestras pruebas. Puedes preguntar por el estado de spring así:

Terminal

Salida

Dado que la salida nos dijo que Spring no se está ejecutando, simplemente inicie con spring server. Cuando ahora ejecute spring status, debería ver algo similar a esto:

Salida

Ahora debemos comprobar lo que Spring está configurado para precargar.

Terminal

Salida

Esto nos dice que Spring está precargando Rails para comandos de rake y rails, y nada más hasta ahora. Que debemos ocuparnos. Tenemos que añadir el gem spring-commands-rspec, y nuestras pruebas están listas para ser precargadas.

Gemfile

Terminal

Te ahorro la salida de bundle install; Estoy seguro de que ya has visto algo más que tu parte justa. Ejecución de bundle exec spring binstub rspec rspec, por otro lado, genera un archivo bin/rspec que básicamente lo añade para ser precargado por Spring. Veamos si esto funcionó:

Terminal

Esto creó algo llamado un binstub—una envoltura para ejecutables como rails, rake, bundle, rspec y tales—de modo que cuando se utiliza el comando rspec se utilizará Spring. Como un aparte, tales binstubs se aseguran de que estes ejecutando estos ejecutables en el ambiente correcto. También te permiten ejecutar estos comandos desde todos los directorios de tu aplicación—no sólo desde la raíz. La otra ventaja de binstubs es que usted no tiene que prepend bundle exec con todo.

Salida

¡Se ve bien! Vamos a detener y reiniciar el servidor de Spring antes de seguir adelante:

Terminal

Así que ahora ejecuta el servidor de primavera en una ventana de terminal dedicada, y ejecuta sus pruebas con una sintaxis ligeramente diferente en otro. Simplemente necesitamos prefijar cada prueba con el comando spring:

Terminal

Esto ejecuta todos sus archivos de spec, por supuesto. Pero no hay necesidad de detenerse allí. También puede ejecutar archivos individuales o pruebas marcadas a través de la primavera—¡no hay problema! Y todos ellos serán relámpagos ahora; En suites de prueba más pequeñas que realmente parecen casi instantáneas. Además de eso, puede usar la misma sintaxis para los comandos rails y rake. Bonito, ¿eh?

Terminal

Así que usamos Spring incorporado para acelerar las cosas en Rails, pero no debemos olvidar añadir esta pequeña joya para que Spring sepa jugar con RSpec.

Las comodidades dudosas de RSpec

Las cosas mencionadas en esta sección son probablemente buenas para evitar, siempre y cuando usted puede encontrar otra solución para ellos. El uso excesivo de algunas de las conveniencias RSpec puede conducir a desarrollar malos hábitos de prueba—por lo menos dudosos. Lo que discutiremos aquí es conveniente en la superficie, pero podría molestar un poco más adelante en el camino.

No deben ser considerados AntiPatrones—cosas que se deben evitar de inmediato—sino más bien considerarse como "olores", cosas que debes tener cuidado y que podrían introducir un costo significativo que a menudo no quieres pagar. El razonamiento para esto implica unas pocas ideas más y conceptos que como un principiante es probable que no estés familiarizado—y francamente podría ser un poco más de su cabeza todavía en este punto—pero debería por lo menos enviar a casa con unas pocas Banderas rojas para pensar y comprometerse a la memoria por ahora.

  • let

Tener un montón de let que las referencias pueden parecer muy conveniente al principio—especialmente porque DRY las cosas un poco. Parece como una extracción razonablemente buena en primer lugar para tenerlos en la parte superior de sus archivos, por ejemplo. Por otro lado, pueden fácilmente darle un tiempo difícil entender su propio código si visita pruebas específicas de una cantidad significativa de tiempo más tarde. No tener los datos establecidos dentro de sus bloques let no ayuda a la comprensión de sus pruebas. Eso no es tan trivial como puede sonar al principio, especialmente si están involucrados otros desarrolladores que necesitan leer su trabajo también.

Este tipo de confusión se vuelve mucha más cara, si más desarrolladores están involucrados. No sólo es mucho tiempo si tienes que cazar las referencias let una y otra vez, también es estúpido porque habría sido evitable con muy poco esfuerzo. La Claridad es la reina, no hay duda al respecto. Otro argumento para mantener estos datos en línea es que el conjunto de pruebas será menos quebradizo. Usted no quiere construir una casa de tarjetas que se vuelve más inestable con cada let que oculta detalles de cada prueba. Probablemente aprendiste que usar variables globales no es una buena idea. En ese sentido, let es un semi-global dentro de sus archivos de especificaciones.

Otro problema es que tendrá que probar un montón de diferentes variaciones, diferentes estados para escenarios similares. Pronto saldrá de las declaraciones de nombre razonablemente nombradas let para cubrir todas las versiones diferentes que pueda necesitar—o terminará con un pajar de toneladas de variaciones de estado con nombres similares. Cuando configura los datos en cada prueba directamente, no tiene ese problema. Las variables locales son baratas, altamente legibles y no se meten con otros ámbitos. De hecho, pueden ser aún más expresivo porque no es necesario considerar toneladas de otras pruebas que podrían tener un problema con un nombre en particular. Desea evitar la creación de otro DSL sobre el marco que todo el mundo necesita para descifrar para cada prueba que se utiliza let. Espero que se sienta como una pérdida de tiempo de todos.

  • before & after

Guarde cosas como before, after y sus variaciones para ocasiones especiales y no la utilice todo el tiempo, por todas partes. Verlo como una de las grandes armas para buscar meta. La limpieza de sus datos es un buen ejemplo que es demasiado meta para cada prueba individual a tratar. Quieres extraer eso, por supuesto.

Mystery Guests

A menudo se pone let en la parte de la información en la parte superior de un archivo y ocultar estos detalles de otras pruebas que los utilizan bajando el archivo. Desea disponer de la información y los datos pertinentes lo más cerca posible de la parte en la que realmente ejerce la prueba—no a kilómetros de distancia, haciendo que las pruebas individuales sean más oscuras.

Al final, se siente como demasiada cuerda para colgar, ya que let introduce accesorios ampliamente compartidos. Que básicamente se rompe a los datos de prueba ficticia cuyo alcance no es lo suficientemente comprimido.

Esto conduce fácilmente a un olor importante llamado "mystery guest". Eso significa que tiene datos de prueba que aparecen de la nada o simplemente se asume. A menudo necesitarás buscarlos primero para entender una prueba—especialmente si ha pasado algún tiempo desde que escribiste el código o si eres nuevo en una base de código. Es mucho más eficaz definir los datos de la prueba en línea exactamente donde se necesita—en la configuración de una prueba en particular y no en un ámbito mucho más amplio.

Agent Spec

Cuando miras esto, se lee muy bien, ¿verdad? Es sucinto, una línea, muy limpio, ¿no? No nos engañemos a nosotros mismos. Esta prueba no nos dice mucho sobre el agent en cuestión, y no nos dice toda la historia. Los detalles de implementación son importantes, pero no estamos viendo nada de eso. El agente parece haber sido creado en otro lugar, y tendríamos que buscarlo primero para entender completamente lo que está pasando aquí. Así que tal vez se ve elegante en la superficie, pero viene con un precio considerable.

Sí, sus pruebas no pueden terminar siendo super DRY todo el tiempo en ese sentido, pero este es un pequeño precio a pagar por ser más expresivo y más fácil de entender, creo. Seguro que hay excepciones, pero que realmente debe ser simplemente aplicado a circunstancias excepcionales después de haber agotado las opciones que Ruby ofrece.

Con un mystery guest, usted tiene que averiguar de dónde provienen los datos, por qué es importante y cuáles son sus especificaciones realmente. No ver los detalles de la implementación en una prueba en sí solo hace que su vida más difícil de lo que necesita ser. Quiero decir, haz que se sientas si trabaja en tus propios proyectos, pero cuando otros desarrolladores están involucrados, sería mejor pensar en hacer su experiencia con su código tan suave como sea posible.

Como ocurre con muchas cosas, por supuesto, lo esencial reside en los detalles, y no quieres mantenerte a ti mismo y a los demás en la oscuridad acerca de ellos. La legibilidad, concisión y la conveniencia de let no debe venir en el coste de perder claridad sobre detalles de la puesta en práctica y dirección errónea . Quieres que cada prueba individual cuente la historia completa y proporcione todo el contexto para entenderlo de inmediato.

Código en línea

Larga historia acortada, quieres tener pruebas que son fáciles de leer y más fácil de razonar sobre una base de prueba por prueba. Trate de especificar todo lo que necesita en la prueba real—y no más que eso. Este tipo de residuos comienza a "oler" como cualquier otro tipo de basura. Eso también implica que debe agregar los detalles que necesita para pruebas específicas tan tarde como sea posible—al crear datos de prueba en general, dentro del escenario real y no en algún lugar remoto. El uso sugerido de let ofrece un tipo diferente de conveniencia que parece oponerse a esta idea.

Vamos a otra vez con el ejemplo anterior y ponerlo en práctica sin la cuestión de mystery guest . En la siguiente solución, encontraremos toda la información relevante para la prueba en línea. Podemos quedarnos en esta especificación si falla y no necesita buscar información adicional en algún otro lugar.

Agent Spec

Sería bueno si le let permite configurar los datos crudos de prueba que usted podría mejorar en una base de necesidad de saber en cada prueba específica, pero esto no es cómo let funciona. Así es como usamos fábricas a través de Factory Girl en estos días.

Les voy a ahorrar los detalles, sobre todo porque he escrito algunas piezas ya. Aquí están mis artículos 101 y 201 sobre lo que Factory Girl tiene para ofrecer—si ya tienes curiosidad de eso. Está escrito para desarrolladores sin toneladas de experiencia también.

Veamos otro ejemplo sencillo que hace buen uso de los datos de prueba de soporte que se configuran en línea:

Agent Spec

Como puede ver, tenemos toda la información que necesita esta prueba en un lugar y no es necesario que busque ningún detalle en otro lugar. Cuenta una historia y no es oscura. Como se mencionó, esta no es la mejor estrategia para código DRY. La recompensa es buena, sin embargo. La claridad y la legibilidad superan a este pedacito de código repetitivo por un tiro largo—especialmente en bases de código grandes.

Por ejemplo, digamos que escribes algo nuevo, aparentemente sin relación, y de repente esta prueba comienza a fallar como daño colateral y no has tocado este archivo de especificaciones en edades.

¿Crees que estarás feliz si necesitas descifrar primero los componentes de configuración para poder entender y corregir esta prueba fallida antes de poder continuar con una característica completamente diferente en la que estás trabajando? ¡Yo creo que no! Quieres salir de esta especificación "sin relación" tan pronto como sea posible y volver a terminar la otra característica.

Cuando encuentres todos los datos de prueba allí donde tus pruebas te dicen dónde falla, aumentas tus probabilidades por una larga toma de arreglar esto rápidamente sin "descargar" una parte completamente diferente de la aplicación en tu cerebro.

Métodos de extracción

Puede limpiar y DRY su código de manera significativa escribiendo sus propios métodos de ayuda. No hay necesidad de usar RSpec DSL para algo tan barato como un método Ruby.

Digamos que usted encontró un par de accesorios repetitivos que están comenzando a sentir un poco sucio. En lugar de ir con un let o subject, defina un método en la parte inferior de un bloque de describir—una convención—y extraiga los elementos comunes en él. Si se utiliza un poco más ampliamente dentro de un archivo, también puede colocarlo en la parte inferior del archivo.

Un buen efecto secundario es que no estás tratando con ninguna variable semi-global de esa manera. También se ahorrará de hacer un montón de cambios en todo el lugar si es necesario ajustar los datos un poco. Ahora puede ir a un lugar central donde se define el método y afectar todos los lugares que se utiliza de una vez. ¡No está mal!

Agent Spec

Como se puede ver, hay un poco de código de configuración repetitiva, y queremos evitar escribir esto una y otra vez. En su lugar, sólo queremos ver lo esencial para esta prueba y tener un método para construir el resto del objeto para nosotros.

Agent Spec

Ahora nuestro método extraído se encarga de sectión y license_to_kill y por lo tanto no nos distrae de lo esencial de la prueba. Por supuesto, este es un ejemplo falso, pero usted puede escalar su complejidad tanto como usted necesita. La estrategia no cambia. Es una técnica de refactorización muy simple—por eso la introduje tan pronto—pero una de las más efectivas. Además, hace casi imposible evitar las herramientas de extracción que RSpecs ofrece.

Lo que también debe prestar atención es lo expresivo que estos métodos de ayuda puede ser sin pagar ningún precio extra.

Consideraciones finales

Evitar algunas partes de RSpec DSL y hacer un buen uso de los principios de Ruby y Programación orientada a objetos son una buena manera de acercarse a escribir sus pruebas. Usted puede utilizar libremente lo esencial, describe, context y it, por supuesto.

Encuentra una buena razón para usar otras partes de RSpec y evitarlas todo el tiempo que pueda. Sólo porque las cosas pueden parecer convenientes y la fantasía no es una razón suficiente para usarlas—es mejor mantener las cosas más sencillas.

Simple es bueno; Mantiene sus pruebas sanas y rápidas.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.