Pregunta

Tengo una aplicación que necesita bastante información (miles de registros) para realizar las pruebas apropiadas. La única forma que encontré para obtener un conjunto decente de datos comprobables y razonables es usar un subconjunto de mi base de datos de producción . He convertido esto en dispositivos YAML en la ubicación normal de `prueba / dispositivos '.

Esto funciona, pero ahora tengo un montón de pruebas y afirmaciones aparentemente frágiles que dependen de que sean un número particular de registros que cumplan con la condición X ...

ejemplo

def test_children_association
  p = Parent.find(1)
  assert_equal 18, p.children.count, "Parent.children isn't providing the right records"
end

Esto no me parece una buena idea, pero no estoy seguro de si existe una forma mejor / aceptada de probar una aplicación que necesita una gran jerarquía de datos.

¿Fue útil?

Solución

Los números mágicos en las pruebas no son un anti-patrón. Sus pruebas deben ser tan simples que no necesita probar . Esto significa que tendrás algunos números mágicos. Esto significa que sus pruebas se interrumpirán cuando cambie pequeños bits de funcionalidad. Esto es bueno.

Los accesorios tienen algunos problemas , pero hay algunas cosas simples que puede hacer para que sea más fácil trabajar con ellas:

  1. Solo tenga datos de línea de base en sus dispositivos, el tipo de datos que la mayoría de sus pruebas necesitan pero no les importa. Esto implicará una inversión de tiempo por adelantado, pero es mejor tomar el dolor temprano que escribir pruebas de unidad deficientes durante la vida del proyecto.

  2. Agregue los datos a probar en el contexto de la prueba. Esto mejora la legibilidad de sus pruebas y evita que escriba " asegúrese de que nadie arruinó los accesorios " controles de integridad al comienzo de sus pruebas de unidad.

Otros consejos

Lo primero que diría es: ¿qué estás probando en ese ejemplo? Si se trata de una asociación común de AR, muchas personas no me molestaría en escribir una prueba. Todo lo que estás haciendo es probar que AR funciona.

Un mejor ejemplo podría ser si tuvo una consulta muy complicada o si hubo otro proceso involucrado para obtener la lista de registros secundarios. Cuando los recuperas, en lugar de probar un recuento, puedes recorrer la lista devuelta y verificar que los hijos coincidan con los criterios que estás utilizando.

lo que he encontrado más útil en esta situación es no usar dispositivos en absoluto, sino construir los objetos de la base de datos sobre la marcha como

def test_foo
   project = Project.create valid_project.merge(....)
   *do assertions here*
end

y en mis test_helpers tendría muchos métodos:

def valid_project
   { :user_id => 23, :title => "My Project" }
end

def invalid_project
   valid_project.merge(:title => nil)
end

Encontré que el dolor de tener que construir colecciones masivas de objetos de prueba me ha llevado naturalmente a diseñar estructuras de clase más simples y versátiles.

Cameron tiene razón: ¿Qué estás probando?

¿Qué tipo de sistema necesita miles de registros presentes para probar? Recuerde, sus pruebas deben ser lo más pequeñas posible y deben probar el comportamiento de la aplicación. No hay forma de que necesite miles de registros para la gran mayoría de esas pruebas.

Para pequeños fragmentos de pruebas de comportamiento en las que necesita relaciones de objetos, considere simular objetos. Solo especulará la cantidad mínima exacta de comportamiento necesaria para que se apruebe su prueba, y no alcanzarán el DB en absoluto, lo que equivaldrá a una gran ganancia de rendimiento en su conjunto de pruebas. Cuanto más rápido se ejecute, más a menudo la gente lo ejecutará.

Es posible que tenga una situación única aquí, pero realmente necesitaba bastantes registros para probar esta aplicación (la tengo en aproximadamente 150). Estoy analizando datos históricos y tengo numerosos niveles de has_many . Algunos de mis métodos realizan consultas SQL personalizadas en varias tablas que podría modificar para usar ActiveRecord.find pero necesitaba realizar primero la prueba.

De todos modos, terminé usando un código de ruby ?? para crear los accesorios . El código se incluye en mi test_helper ; comprueba la base de datos de prueba para ver si los datos están obsoletos (según una condición de tiempo) y borra y vuelve a crear los registros de manera procesal . En este caso, crearlo de manera procedimental me permite saber cuáles son los datos que estoy probando para DEBERÍA , lo que es más seguro que usar un subconjunto de datos de producción y esperar los números Cálculo que la primera vez es lo que debería probar en el futuro.

También pasé a usar Shoulda que, junto con muchas otras cosas útiles, hace que la Asociación ActiveRecord tan fácil como:

should_have_many :children
should_belong_to :parent
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top