2008-12-07 17 views
117

¿Desea realizar pruebas unitarias en el mismo proyecto por comodidad o las coloca en un ensamblaje por separado?¿Pones pruebas unitarias en el mismo proyecto u otro proyecto?

Si los coloca en un ensamblaje por separado como lo hacemos, terminamos con una serie de proyectos adicionales en la solución. Es ideal para pruebas unitarias durante la codificación, pero ¿cómo se libera la aplicación sin todos estos ensamblajes adicionales?

Respuesta

82

En mi opinión, las pruebas unitarias se deben colocar en un conjunto separado del código de producción. A continuación, presentamos algunos inconvenientes de realizar pruebas unitarias en el mismo conjunto o ensamblaje que el código de producción:

  1. Las pruebas unitarias se envían con el código de producción. Lo único que se envía con el código de producto es el código de producción.
  2. Los conjuntos se verán innecesariamente hinchados por las pruebas unitarias.
  3. Las pruebas unitarias pueden afectar los procesos de compilación, como la compilación automática o continua.

Realmente no conozco ningún profesional. Tener un proyecto extra (o 10) no es una estafa.

Edición: Más información sobre proyectos de construcción y el envío

recomendaría, además, que cualquier proceso de construcción automatizado de producción y pruebas unitarias lugar en diferentes lugares. Idealmente, el proceso de compilación de pruebas unitarias solo se ejecuta si el código de producción se genera y copia los archivos del producto en el directorio de pruebas de la unidad. Hacerlo de esta manera da como resultado que los bits reales se separen para el envío, etc. Además, es bastante trivial ejecutar pruebas unitarias automatizadas en este momento en todas las pruebas en un directorio particular.

En resumen, aquí es la idea general de una acumulación diaria y las pruebas y el envío de bits y otros archivos:

  1. Producción construir carreras, la colocación de archivos de producción en un directorio "producción" específica.
    1. Genere proyectos de producción solamente.
    2. Copie los bits compilados y otros archivos en un directorio de "producción".
    3. Copie los bits y otros archivos en un directorio de versión de candidato, también conocido como un directorio de lanzamiento de Navidad sería "Release20081225".
  2. Si la compilación de producción se realiza correctamente, se ejecuta la compilación de pruebas unitarias.
    1. Copie el código de producción al directorio "tests".
    2. Pruebas de unidades de compilación en el directorio "pruebas".
    3. Ejecutar pruebas unitarias.
  3. Enviar notificaciones de compilación y resultados de pruebas de unidades a los desarrolladores.
  4. Cuando se acepta un release candidate (como Release20081225), envíe estos bits.
+11

IMO, los contras su lista no son siempre aplicables. Un profesional para el mismo proyecto es la agrupación más fácil de las pruebas de clase + probadas: estas pequeñas comodidades son fundamentales para escribir pruebas. Las preferencias personales ganan aquí, y algunas veces tus puntos son relevantes, pero no todo el tiempo. – orip

+0

, pero ¿cómo se eliminan estos proyectos cuando se desea enviar – leora

+5

? Primero debe preguntar si necesita eliminar las pruebas al enviar. Si es así, necesitas un proyecto separado. Si no, usa los otros pros y contras para decidir. Las personas que asumen que no pueden implementar las pruebas siempre llegarán a la conclusión de "proyecto separado" de forma predeterminada. – orip

9

Mis pruebas de unidad siempre van en un proyecto separado. De hecho, por cada proyecto que tengo en mi solución, hay un proyecto de prueba separado que lo acompaña.El código de prueba no es un código de aplicación y no debe mezclarse con él. Una ventaja de mantenerlos en proyectos separados, al menos usando TestDriven.Net, es que puedo hacer clic derecho en un proyecto de prueba y ejecutar todas las pruebas en ese proyecto, probando una biblioteca completa del código de la aplicación con un solo clic.

+1

¿Entonces cómo pruebas las clases internas? ¿O solo pruebas las clases públicas? – user19371

+7

si es necesario, aunque normalmente solo pruebo las interfaces públicas. – tvanfosson

88

Proyecto separado, pero en la misma solución. (He trabajado en productos con soluciones independientes para la prueba y el código de producción - que es horrible Uno siempre está cambiando entre los dos..)

Las razones para proyectos independientes son las establecidas por otros. Tenga en cuenta que si está utilizando pruebas basadas en datos, puede terminar con una cantidad bastante grande de hinchazón si incluye las pruebas en el ensamblaje de producción.

Si necesita acceso a los miembros internos del código de producción, el uso InternalsVisibleTo.

+0

+1: Acabo de encontrar pruebas unitarias en el mismo proyecto que el código principal y es difícil encontrar las pruebas entre el código real, incluso aunque se haya seguido una convención de nomenclatura. – Fenton

+19

+1 para el atributo 'InternalsVisibleTo'. – hIpPy

+0

InternalsVisibleTo !!! ¡Increíble! –

3

Fluctivo entre el mismo proyecto y diferentes proyectos.

Si está liberando una biblioteca liberando el código de prueba con el código de producción es un problema, si no lo encuentro por lo general no es (aunque hay una fuerte barrera psicológica antes de tratar).

Al poner pruebas en el mismo proyecto me resulta más fácil cambiar entre las pruebas y el código que ponen a prueba, y más fácil de refactorizar/moverlos.

3

Los puse en proyectos separados. El nombre de la asamblea refleja el de los espacios de nombres, como regla general para nosotros. Entonces, si hay un proyecto llamado Company.Product.Feature.sln, tiene un resultado (nombre de conjunto) de Company.Product.Feature.dll. El proyecto de prueba es Company.Product.Feature.Tests.sln, que produce Company.Product.Feature.Tests.dll.

desea mantener mejor en una sola solución y controlar la salida a través del Administrador de configuración. Tenemos una configuración con nombre para cada una de las ramas principales (Desarrollo, Integración, Producción) en lugar de utilizar la depuración y publicación predeterminadas. Una vez que tenga configurada la configuración, puede incluirla o excluirla haciendo clic en la casilla de verificación "Generar" en Configuration Manager. (Para obtener Configuration Manager, haga clic con el botón derecho en la solución y vaya a Configuration Manager). Tenga en cuenta que, en ocasiones, creo que el CM en Visual Studio tiene errores. En un par de ocasiones, tuve que ir al proyecto o a los archivos de la solución para limpiar los objetivos que creó.

Además, si está utilizando Generar equipo (y estoy seguro de que otras herramientas .NET empleados son de la misma) a continuación, puede asociar la construcción con una configuración llamada. Esto significa que si no construyes las pruebas de tu unidad para tu compilación de "Producción", por ejemplo, el proyecto de compilación también puede tener en cuenta esta configuración y no construirlas ya que fueron marcadas como tales.

Además, solíamos hacer XCopy se cae de la máquina de compilación. La secuencia de comandos simplemente omitirá copiar algo llamado * .Tests.Dll de desplegarse. Fue simple, pero funcionó.

53

No entiendo la objeción frecuente a la implementación de pruebas con el código de producción. Dirigí un equipo en un pequeño microcap (creció de 14 a 130 personas). Contamos con media docena de aplicaciones Java y encontramos MUY valioso implementar pruebas en el campo para ejecutarlas en una máquina específica que mostraba un comportamiento inusual. Se producen problemas aleatorios en el campo y ser capaz de lanzar miles de pruebas unitarias en el misterio sin costo fue invaluable y a menudo se diagnosticaron problemas en minutos ... incluyendo problemas de instalación, problemas de RAM escamosa, problemas específicos de la máquina, problemas de red escamosa, etc., etc. Creo que es increíblemente valioso poner pruebas en el campo. Además, surgen problemas aleatorios en momentos aleatorios y es bueno tener las pruebas unitarias sentadas allí esperando a ser ejecutadas en cualquier momento. El espacio en el disco duro es barato.Al igual que tratamos de mantener juntos los datos y las funciones (diseño OO), creo que hay algo fundamentalmente valioso en mantener juntos el código y las pruebas (función + pruebas que validan las funciones).

Me gustaría poner mis pruebas en el mismo proyecto en C# /. NET/Visual Studio 2008, pero todavía no he investigado esto lo suficiente para lograrlo.

Una gran ventaja de mantener Foo.cs en el mismo proyecto que FooTest.cs es que a los desarrolladores se les recuerda constantemente cuando a una clase le falta una prueba de hermanos. Esto fomenta mejores prácticas de codificación basadas en pruebas ... los agujeros son más evidentes.

+12

¿Puedo ver cómo sería valioso con las pruebas de integración, pero para las pruebas unitarias? Si los escribe correctamente, no deberían tener dependencias en la máquina. – jcmcbeth

+2

¿Cómo le permitieron las pruebas unitarias diagnosticar RAM escamosa? – jwg

+1

+1, totalmente de acuerdo. –

-2

Proyectos separados, aunque debato conmigo mismo si deberían compartir el mismo svn. Por el momento, estoy dando repositorios SVN separados, uno llamado

"MiProyecto" - para el proyecto en sí

y uno llamado

"MyProjectTests" - para las pruebas asociadas con MiProyecto.

Esto es bastante limpio y tiene la ventaja de que se compromete con el proyecto y se compromete con las pruebas. También significa que puede entregar el svn del proyecto si es necesario, sin tener que liberar sus pruebas. También significa que puede tener directorios de ramificación/troncal/etiqueta para sus pruebas y para su proyecto.

Pero cada vez me siento más inclinado a tener algo como lo siguiente, en un único repositorio de svn, para cada proyecto.

 
MyProject 
|\Trunk 
| |\Code 
| \Tests 
|\Tags 
| |\0.1 
| | |\Code 
| | \Tests 
| \0.2 
| |\Code 
| \Tests 
\Branches 
    \MyFork 
    |\Code 
    \Test 

Estaría interesado en saber lo que otras personas piensan de esta solución.

+4

No debería necesitar confirmaciones por separado para el código de prueba y aplicación. Deben ir de la mano y comprometer involucrar a ambos, especialmente si se utiliza el diseño de estilo * DD. – eddiegroves

0

Estoy realmente inspirado por el marco de pruebas unitarias del Flood NN library de Robert Lopez. Utiliza un proyecto diferente para cada clase probada de unidad, y tiene una solución que contiene todos estos proyectos, así como un proyecto principal que compila y ejecuta todas las pruebas.

Lo bueno es también el diseño del proyecto. Los archivos fuente están en una carpeta, pero luego la carpeta del proyecto VS está debajo. Esto le permite crear diferentes subcarpetas para diferentes compiladores. Todos los proyectos de VS se envían con el código, por lo que es muy fácil para cualquiera ejecutar cualquiera o todas las pruebas unitarias.

+0

enlace Actualización de "biblioteca de Alimentos NN" -> http://www.cimne.com/flood/default.asp – Fil

10

Ponga las pruebas de unidades en el mismo proyecto que el código para lograr una mejor encapsulación.

Puede probar fácilmente los métodos internos, lo que significa que no hará públicos los métodos que deberían haber sido internos.

También es muy agradable tener las pruebas de la unidad cerca del código que está escribiendo. Cuando escribe un método, puede encontrar fácilmente las pruebas unitarias correspondientes porque está en el mismo proyecto. Cuando construyes un ensamblado que incluye unitTests, cualquier error en UnitTest te dará un compilereerror, por lo que debes mantener tu prueba unificada actualizada, solo para compilar. Tener una prueba unitaria en un proyecto separado, puede hacer que algunos desarrolladores olviden construir el proyecto de prueba unitario, y perder las pruebas rotas por un tiempo.

Y puede eliminar las pruebas unitarias del código de producción, mediante el uso de etiquetas de compilación (IF #Debug).

Las pruebas de integración automática (realizadas en iNUnit) deben estar en un proyecto separado, ya que no pertenecen a ningún proyecto.

+1

Pero eso significa que no puede ejecutar pruebas en la puesta en circulación 'construir y pocos "heisenbug" puede caer a través. Con – hIpPy

+0

asambleas amigo (https://msdn.microsoft.com/en-us/library/0tke9fxk.aspx) usando 'InternalsVisibleTo' le permite probar los métodos internos de un proyecto de prueba independiente – ParoX

+0

@hlpPy - puede configurar la compilación condicional arbitraria símbolos, y puede tener más de 2 configuraciones de compilación. P.ej; es posible que tenga 'Debug',' Approval' y 'Release'; y compilar la aprobación con todas las optimizaciones de versión. Además, en general las pruebas unitarias no son excelentes para detectar heisenbugs en primer lugar (en mi experiencia). Suele necesitar pruebas de regresión de integración específicas para esas personas, y puede ubicarlas una al lado de la otra. –

1

Yo diría que los mantengan separados.

Además de los otros motivos mencionados, tener códigos y pruebas juntos sesga los números de cobertura de prueba. Cuando informa sobre la cobertura de prueba unitaria: la cobertura informada es más alta porque las pruebas están cubiertas cuando realiza pruebas unitarias. Cuando informa sobre la cobertura de prueba de integración, la cobertura informada es menor porque las pruebas de integración no ejecutan pruebas unitarias.

+0

¿Eso no depende de la tecnología utilizada para cubrir las pruebas? Quiero decir, OpenCover considera las líneas de código cubiertas si son ejecutadas por una prueba, _incluyendo las líneas de la prueba en sí misma_ de modo que si las pruebas tienen excepciones inesperadas, también se marcan como descubiertas. –

6

Si se usa NUnit marco, existe un motivo adicional para colocar las pruebas en el mismo proyecto. Considere el ejemplo siguiente del código de producción mezclado con pruebas de unidad:

public static class Ext 
{ 
    [TestCase(1.1, Result = 1)] 
    [TestCase(0.9, Result = 1)] 
    public static int ToRoundedInt(this double d) 
    { 
     return (int) Math.Round(d); 
    } 
} 

Las pruebas de unidad aquí sirven como documentación y la especificación para el código que está siendo probado. No sé cómo lograr este efecto de auto-documentación, con las pruebas ubicadas en un proyecto separado. El usuario de la función tendría que buscar las pruebas para ver esos casos de prueba, lo que es poco probable.

Actualización: Sé que tal uso del atributo TestCase no era lo que los desarrolladores de NUnit estaban interesados, ¿pero por qué no?

Cuestiones relacionadas