2011-04-13 8 views
7

¿Hay algo de malo en poner los métodos de prueba en la misma clase que la clase que está probando?¿Hay algún problema al colocar los métodos de prueba en la misma clase que está probando?

Agregue el atributo [TestFixture] a cada clase y tenga el método [Test] junto con los métodos reales.

Me gusta la idea. Mantiene todo en un solo lugar.

Pero, ¿cuáles son los inconvenientes de esto?

/Uso Nunit yC#.

+0

programación extrema? – Arseny

+2

Sí, soy extremo. gracias – arkina

+0

Si * desea * probar métodos privados, márquelos como internos y use 'InternalsVisibleTo' para permitir que sus métodos de prueba, TODAVÍA en un ensamble diferente, los llamen. Esto es útil para las pruebas de caja blanca. – Brian

Respuesta

20

Sí, este es un patrón que debe evitarse. Las pruebas deben ser una entidad completamente separada de su código de envío para al menos las siguientes razones

  • hacerse pruebas en un ensamblado independiente asegurarse de tener una API útil ya que no pueden engañar a través de private/protected construcciones. En su lugar, se ven obligados a pasar por los puntos API públicos
  • Tener pruebas en el mismo ensamblaje significa que su código de producción también incluye su código de prueba. No hay razón para enviar código para el cliente que en realidad no se utilizarán
  • Causas código de producción para tomar las dependencias en las asambleas que no necesitan (nUnit, xUnit, etc ...)
  • Muchas infraestructuras de prueba requieren métodos de prueba a ser pública, por tanto, que empuja las pruebas a la superficie pública de su API.
  • tenerlos en la misma asamblea se abre la puerta al código de producción accidentalmente poner en código de prueba y, por tanto, según afirma la diversión apareciendo en entornos de producción
+1

Buen punto sobre el problema de la dependencia. – RQDQ

+1

Nada más que buenas razones. ++ para eso. Además de la razón de todas las razones: separación de preocupaciones. – Steven

4

La desventaja más grande: tiene que enviar sus pruebas, y potencialmente se vuelven parte de su API pública.

+0

Esto es de lo que me preocuparía. Pero podría usar la compilación condicional para descartar las pruebas en la compilación de lanzamiento, y además podría acceder a las variables de miembros privados sin recurrir a trucos furtivos. Acceder a miembros privados puede o no considerarse una buena cosa. –

+0

Si solo tiene compilaciones de depuración de pruebas unitarias, ya tiene un problema ... Además, si está realizando pruebas unitarias contra variables privadas, muchos dirán que sus pruebas están probando incorrectamente. –

6

Sí. Sería romper el Principio de Responsabilidad Individual. Reducirá la legibilidad. Agrega una dependencia a su marco de prueba.

+1

+1 para el SRP. – Steven

1

El mayor problema que veo con esto fuera de mi cabeza es que no desea distribuir sus pruebas unitarias dentro de su código base como parte del producto final (de ahí también las dependencias).

Y el uso de constantes de traza para compilarlas condicionalmente se vuelve realmente feo en este caso. Fr ejemplo, una condición para el atributo de accesorio de prueba y al menos uno para el método o grupo de métodos.

hay aspectos así que puede relativos a por qué no Para ello, como se ejemplifica en la gama de respuestas ya las inundaciones en - simplemente no lo hacen.

8

Este enfoque rejillas de mi alma.

creo que tiene mucho más sentido para mantener su código de prueba independiente de su código de producción. Muchas razones:

  • Teóricamente, debe probar en la interfaz de su código y no tener acceso a elementos como los miembros privados detrás de las escenas.
  • Organización - tener todas las pruebas en un proyecto independiente significa que su aplicación principal no estar atestado de código de prueba.
  • Esto inflaría el tamaño de sus entregas.
  • Poner todo en un solo lugar hace que sea más difícil para un equipo trabajar en la base de código al mismo tiempo (una persona en las pruebas, una en el código, etc.).

sobre todo:

que sólo se siente llanuras/huele mal.

+0

De acuerdo. Mejor que mi respuesta :) –

2

Downsides?

Sus clases tendrán técnicamente más métodos de los que necesitan para su uso en un entorno de producción. También tendrá referencias a nUnit que no necesita en un entorno de producción.

También está rompiendo la separación de funciones aquí. Se supone que su clase debe hacer el trabajo, se supone que su prueba verifique que su clase pueda hacer su trabajo.

2

Una desventaja potencial es que cuando envía su código, también debe enviar todas las pruebas, lo que hace que el binario entregable sea más grande, lleno de métodos de prueba que nunca se llaman.

Una desventaja más filosófica es que, si bien mantiene todo junto, no logra separar las preocupaciones del código en sí (la lógica de negocios) de las preocupaciones del aseguramiento de la calidad (asegurándose de que funciona correctamente). Intente pensar en su código en términos de una responsabilidad única para cada clase/archivo y vea a dónde lo lleva.

0

Sí. En primer lugar, hace que sus clases sean más grandes: cada propiedad o campo utilizado por sus pruebas debe llevarse en la memoria dondequiera que se use su clase. En segundo lugar, agrega un montón de métodos y propiedades públicas a la clase, que serían visibles para cosas como sus fábricas.

Si desea que sus pruebas sean derecha junto con su clase, simplemente ponerlos en el mismo archivo:

public class Foo : IFoo 
{ 
    ... 
} 

[TestFixture] 
public class Foo_Tests 
{ 
    ... 
} 
+0

Mejor, pero seguirán en el mismo ensamblaje y seguirán causando dependencia del marco de prueba, hinchar el tamaño del ensamblaje, obstaculizar el desarrollo paralelo, etc. – RQDQ

2

Usted no quiere tomar atajos.

No desea probar métodos privados. En especial, no desea utilizar métodos privados como métodos auxiliares para las pruebas de su unidad (es decir, reutilizarlos en sus pruebas).

Es mucho mejor agrupar clases de prueba en proyectos de prueba. Estos no influyen en el código que se está probando, y es mucho más fácil mantener una visión general del código que tiene.

De la misma manera, no mezcla la IU y el código de lógica de negocios.

Por favor, por favor, por favor, ¡no mezcle las pruebas con sus sujetos bajo prueba!

1

a tirar mis dos centavos:

estaré de acuerdo con la mayoría de los puestos aquí, afirmando que la creación de métodos de ensayo/funciones para el único propósito de probar es un desperdicio y, potencialmente, estructuralmente desorganizado.

Sin embargo, en general, cuando desarrolla "con las pruebas en mente", puede diseñar su implementación para que también se pruebe. Por ejemplo, inicialmente puede diseñar una función/método para usar una variable de clase. Sin embargo, si desea probar la funcionalidad de ese método, puede diseñarlo para tener el valor de la variable de clase "pasado" como parámetro de función.

Ahora su método es funcional y comprobable, es decir, prueba funcional.

Así que en realidad, puede diseñar su clase para luego ser probado, sin sufrir todos los inconvenientes de crear un método con el único propósito de probar.

Espero que esto ayude. Este wiki ofrece una buena visión general de las pruebas en programación, en general: http://en.wikipedia.org/wiki/Software_testing

+0

Tenga en cuenta que, con mi ejemplo, no haría su base de código más grande para la clase respectiva. Simplemente lo habría diseñado con las pruebas en mente, y ese es el punto de mi enfoque. – Rick

Cuestiones relacionadas