2008-10-22 12 views
5

Tengo una aplicación que necesita un poco de datos (miles de registros) para hacer las pruebas adecuadas. La única forma que he encontrado para obtener un conjunto decente de datos testables y sensibles es usar un subconjunto de mi DB de producción. Lo convertí en accesorios YAML en la ubicación normal de "prueba/fijaciones".Comprobación de rieles: accesorios, fábricas y números mágicos

Esto funciona, pero ahora tengo un montón de pruebas aparentemente frágiles y afirmaciones que dependen de su ser un número determinado de registros que cumplen 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 tiene Me parece una buena idea, pero No estoy seguro de si hay una forma mejor/aceptada para probar una aplicación que necesita una gran jerarquía de datos.

Respuesta

8

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

accesorios tienen some problems, pero hay algunas cosas simples que usted puede hacer para que sean más fáciles de trabajar con:

  1. sólo tienen datos de referencia en sus instalaciones, el tipo de datos que la mayor parte de sus pruebas Necesito pero no me importa Esto implicará una inversión de tiempo por adelantado, pero es mejor tomar el dolor antes que escribir pruebas de unidades pobres durante la vida del proyecto.

  2. Agregue los datos que se probarán en el contexto de la prueba. Esto mejora la legibilidad de sus pruebas y le evita escribir "asegúrese de que nadie arruine los controles de cordura" al comienzo de las pruebas de su unidad.

+1

Esto en combinación con el plugin de thinkbot rails Shoulda, hace que sea bastante fácil ejecutar una configuración y desmontaje en un subgrupo de métodos de prueba, manteniendo el código de prueba SECO. –

0

Lo primero que diría es: ¿qué está probando en ese ejemplo? Si se trata de una RA ordinaria, hay muchas asociaciones, entonces no me molestaría en escribir una prueba para ello. Todo lo que estás haciendo es probar que AR funciona.

Un mejor ejemplo podría ser si tenía una consulta muy complicada o si había otro proceso involucrado en obtener la lista de registros de niños. Cuando los recupere, en lugar de probar el recuento, puede recorrer la lista devuelta y verificar que los niños coinciden con los criterios que está utilizando.

+0

Sí, en ese ejemplo era sólo una Asociación ActiveRecord. Empecé a usar Shoulda, que proporciona ayudantes como should_have_many: children, esto lo hace mucho más fácil. –

0

lo que he encontrado más útil en esta situación no está utilizando los accesorios en absoluto, sino más bien la construcción de los objetos de la base sobre la marcha como

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

y en mis test_helpers que tendría un montón de métodos:

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

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

me encontré con que el dolor de tener que construir colecciones masivas de objetos de prueba me ha llevado de forma natural para diseñar las estructuras de clase más simples y más versátiles.

+0

Esto sería equivalente a (pero un poco menos elegante que) el uso de dispositivos y luego 'Model.update_attributes' en la prueba, que es lo que sugiere DHH: http://david.heinemeierhansson.com/2014/test-induced-design -damage.html – Magne

0

Cameron's right: Qué estás haciendo?

¿Qué tipo de sistema necesita miles de registros 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ñas pruebas de comportamiento en las que necesita relaciones de objeto, considere la simulación de objetos. Solo especificará la cantidad mínima exacta de comportamiento necesaria para que la prueba pase, y no afectarán en absoluto al DB, lo que representará un gran aumento en el rendimiento en su conjunto de pruebas. Cuanto más rápido sea para correr, más a menudo las personas lo ejecutarán.

+0

Después de un poco de optimización, obtuve los requisitos hasta solo 150 registros en 5 tablas. Es una aplicación de análisis de datos. –

0

Puede que aquí tenga una situación única, pero realmente necesitaba bastantes registros para probar esta aplicación (la reduje a 150 aproximadamente). 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 terminar modificando para usar ActiveRecord.find, pero necesitaba ejecutar la prueba primero.

De todos modos, terminé usando un código ruby ​​para crear los accesorios. El código está incluido en mi test_helper; comprueba el DB de prueba para ver si los datos están obsoletos (según una condición de tiempo) y toallitas y recrea los registros procesalmente. En este caso, crearlo procedimentalmente me permite saber cuáles son los datos que estoy probando ,, que es más seguro que usar un subconjunto de datos de producción y esperar que los números que calculo la primera vez sean lo que debería probar para en el futuro

que también se trasladó a la utilización de Shoulda que junto con muchas otras cosas útiles hace que las pruebas Asociación ActiveRecord tan fácil como:

should_have_many :children 
should_belong_to :parent 
+0

Entonces, recreó los registros basados ​​en datos de producción cada vez que se ejecutaron las pruebas? ¿Fue un éxito? – Magne

Cuestiones relacionadas