2012-07-20 7 views
12

mi actual forma de organización de las pruebas unitarias se reduce a lo siguiente:¿Cómo organizar pruebas unitarias y no hacer que la refactorización sea una pesadilla?

  • Cada proyecto tiene su propio proyecto dedicado con pruebas unitarias. Para un proyecto BusinessLayer, existe un proyecto de prueba BusinessLayer.UnitTests.
  • Para cada clase que quiero probar, hay una clase de prueba separada en el proyecto de prueba dentro de la misma estructura de carpetas exactamente en el mismo espacio de nombres que la clase bajo prueba. Para una clase CustomerRepository desde un espacio de nombres BusinessLayer.Repositories, hay una clase de prueba CustomerRepositoryTests en un espacio de nombres BusinessLayerUnitTests.Repositories.

Los métodos de cada clase de prueba siguen la convención de nomenclatura simple MethodName_Condition_ExpectedOutcome. Así la clase CustomerRepositoryTests que contiene las pruebas para una clase CustomerRepository con un método definido Get tiene el siguiente aspecto:

[TestFixture] 
public class CustomerRepositoryTests 
{ 
    [Test] 
    public void Get_WhenX_ThenRecordIsReturned() 
    { 
     // ... 
    } 

    [Test] 
    public void Get_WhenY_ThenExceptionIsThrown() 
    { 
     // ... 
    } 
} 

Este enfoque me ha servido bastante bien, porque hace que la localización de las pruebas por alguna pieza de código muy simple. En el sitio opuesto, hace la refactorización de código realmente más difícil de lo que debería ser:

  • Cuando decido dividir un proyecto en varios más pequeños, también necesito dividir mi proyecto de prueba.
  • Cuando quiero cambiar el espacio de nombres de una clase, debo recordar cambiar también un espacio de nombres (y una estructura de carpetas) de una clase de prueba.
  • Cuando cambio el nombre de un método, tengo que pasar por todas las pruebas y cambiar el nombre allí, también. Claro, puedo usar Search & Reemplazar, pero eso no es muy confiable. Al final, aún necesito verificar los cambios de forma manual.

¿Hay alguna forma inteligente de la organización de pruebas de unidad que todavía me permite localizar pruebas para un código específico de forma rápida y al mismo tiempo, se presta más a la refactorización?

Alternativamente, ¿hay alguna, uh, tal vez la extensión de Visual Studio, que permitiría a mí decir de alguna manera que "oye, estos pruebas son para que método, por lo que cuando el nombre de los cambios de método, por favor sea tan amable y cambiar las pruebas también "? Para ser sincero, estoy considerando seriamente escribir algo como eso :)

+0

¿Cómo nombras tus métodos de prueba? ¿Contienen el nombre del método que está probando? –

+0

@ UfukHacıoğulları Sí, lo hacen. En la pregunta menciono la convención exacta que siguen estos nombres. –

Respuesta

4

Después de trabajar mucho con las pruebas, me he dado cuenta de que (al menos para mí) tener todas esas restricciones trae muchos problemas en el largo plazo, en lugar de cosas buenas. Entonces, en lugar de usar "Nombres" y convenciones para determinar eso, comenzamos a usar el código. Cada proyecto y cada clase pueden tener cualquier cantidad de proyectos de prueba y clases de prueba. Todo el código de prueba se organiza en función de lo que se está probando desde una perspectiva de funcionalidad (o qué requisito implementa, o qué error se reproduce, etc.). A continuación, para encontrar las pruebas para una pieza de código que hacemos esto:

[TestFixture] 
public class MyFunctionalityTests 
{ 
    public IEnumerable<Type> TestedClasses() 
    { 
     // We can find the tests for a class, because the test cases references in some special method. 
     return new []{typeof(SomeTestedType), typeof(OtherTestedType)}; 
    } 

    [Test] 
    public void TestRequirement23423432() 
    { 
     // ... test code. 
     this.TestingMethod(someObject.methodBeingTested); //We do something similar for methods if we want to track which methods are being tested (we usually don't) 
     // ... 
    } 
} 

podemos utilizar herramientas como ReSharper "usos" para encontrar los casos de prueba, etc ... Y cuando eso no es suficiente, hacemos un poco de magia por reflexión y LINQ cargando todas las clases de prueba, y ejecutando algo como allTestClasses.where(testClass => testClass.TestedClasses().FindSomeTestClasses()); También puede usar TearDown para reunir información sobre qué métodos son probados por cada método/clase y hacer lo mismo.

+0

Gracias por brindarme algunas ideas interesantes sobre el seguimiento de métodos. No estoy seguro de si deseo abandonar todas las convenciones. Probablemente intentaré desarrollar alguna herramienta que sincronice automáticamente los proyectos de prueba con sus contrapartes "reales". –

+0

¡Es como una base de datos de prueba! ¡Me gusta! –

0

Un proyecto de prueba de una unidad por proyecto es el camino a seguir. Hemos intentado con un proyecto de prueba mega unidad, pero esto aumentó el tiempo de compilación.

Para ayudarlo a refactorizar use un producto como resharper o code rush.

+0

Sí, ya estoy usando Resharper, pero ayuda solo parcialmente al renombrar métodos. Intenta encontrar lugares en una solución donde cree que se usa el método, pero todavía hay muchos falsos positivos, especialmente con nombres de métodos comunes.Estoy buscando algo más automático y menos lento. –

+0

Resharper y VS pueden ayudarlo a cambiar el nombre de espacios de nombres; consulte: http://stackoverflow.com/questions/3360320/refactor-namespace-in-visual-studio –

+0

Correcto. Pero en mi caso, solo cambiaría el nombre de un espacio de nombres de, p. 'CustomerRepository' y no' CustomerRepositoryTests', que es exactamente lo que estoy buscando. –

0

¿Hay alguna forma inteligente de la organización de pruebas de unidad que sigue me permitan localizar pruebas para un código específico de forma rápida

ReSharper tener algunos buenos atajos que le permite archivo o código de búsqueda

Como usted ha dicho para CustomerRepository clase su es una prueba CustomerRepositoryTests

R # acceso directo muestra Inpput cuadro de lo que se encuentra en que caso se puede CRT acaba de introducir y lo hará s ¿Cómo están todos los archivos que comienzan con el nombre primero tener como capital C, entonces R y T

También le permite hacer una búsqueda por comodines tales como CR * le mostrará la lista de CustomerRepository archivo y CustomerRepositoryTests

+0

Gracias por la sugerencia. Sin embargo, realmente no veo cómo podría ayudarme con mis problemas; la frase que está citando continúa con * y al mismo tiempo se prestará más a la refactorización? * - y eso es lo que necesito resolver :) –

1

Uno manera de mantener posiciones de clase y de prueba en sincronía al mover el código:

  • mover el código a un espacio de nombres temporal con un nombre único
  • Búsqueda de referencias a ese espacio de nombres en sus pruebas para identificar las pruebas que deben ser movido
  • mover las pruebas para la nueva ubicación adecuada
  • Una vez que todas las referencias al espacio de nombres temporal de las pruebas están en el lugar correcto, a continuación, pasar el código original a su objetivo previsto

Una fuerza de extremo-a- Las pruebas finales o de comportamiento son las pruebas agrupadas por requisitos y no por códigos, por lo que se evita el problema de mantener las ubicaciones de prueba sincronizadas con el código correspondiente.

1

En cuanto a las extensiones de VS que asocian el código a las pruebas, eche un vistazo a Test Impact de Visual Studio. Ejecuta las pruebas en un generador de perfiles y crea una base de datos compacta que mapea los puntos de secuencia IL en pruebas unitarias. En otras palabras, cuando cambia el código, Visual Studio sabe qué pruebas se deben ejecutar.

+0

Gracias por eso, ciertamente lo echaré un vistazo. –

Cuestiones relacionadas