2009-11-05 8 views
11

¿Debería diseñar su código para facilitar las pruebas? Y si es así, ¿cómo diseñar C++ código para que sea fácil de probar.Patrones para hacer que el código de C++ sea fácil de probar

  • ¿Cómo se aplica la inyección de dependencia en C++?
  • ¿Debo implementar las clases usando una clase de interfaz pura como base para simplificar la creación de objetos de prueba falsos?
    • Eso me obligaría a hacer un montón de métodos virtuales. ¿Eso afectará el rendimiento?
  • ¿Qué más debería pensar al diseñar para probar en C++?
+0

El diseño para la capacidad de prueba realmente es imprescindible. Sin embargo, también debe tener en cuenta que solo el 'límite' debe poder probarse de manera independiente, es perfectamente razonable que los componentes internos dependan unos de otros y no se prueben de forma aislada. –

+0

Puede que le interese [Propuesta de intercambio de pila] (http://area51.stackexchange.com/proposals/11464/code-review?referrer=aWNm_PdciyFqjFW8CUacGw2 "revisión de código"). Está casi listo para comenzar la versión beta, solo necesita algunos más. – greatwolf

Respuesta

9

¿Debo implementar las clases usando una clase de interfaz pura como base para simplificar la creación de objetos de prueba falsos?

  • Eso me obligaría a hacer una gran cantidad de métodos virtuales. ¿Eso afectará el rendimiento?

Una solución que utilizo a menudo es crear plantillas de la clase en lugar de ocultarlo detrás de una interfaz. Luego, puedo pasar los objetos de prueba/simulación como parámetros de plantilla cuando los pruebo, y los objetos reales de lo contrario. De esta forma, se evita el golpe de rendimiento de las funciones virtuales.

Editar
Ok, un ejemplo sencillo:

Con programación orientada a objetos e interfaces, puede escribir una función como esta:

void Foo(IBar& someBar) { ... } 

Esta función toma un parámetro que implementa la interfaz IBar y hace algo con eso Si desea pasar una implementación falsa simulada, simplemente escriba un objeto simulado que hereda de IBar y páselo a Foo. Simple y directo.

Pero se puede lograr lo mismo con las plantillas:

template <typename BarType> 
void Foo(BarType& someBar) { ... } 

... y eso es todo. El cuerpo de Foo puede ser casi sin cambios. Siempre que el tipo pasado a la función exponga todos los miembros que necesitamos, funcionará, sin tener que heredar formalmente de una clase de interfaz, y sin la sobrecarga de las funciones virtuales y el polimorfismo de tiempo de ejecución.

+0

¿Dónde puedo leer más sobre cómo las clases de temple? ¿Hay algún patrón que describa esto? –

+0

¿Por qué quieres un patrón para todo? jalf le ha mostrado una idea para dejar la herencia (virtual/polimorfismo) solo y usar en su lugar las plantillas de C++ (programación genérica). Dar un simulacro genérico (código de plantilla) cubriría "todos" los tipos posibles que usaría alguna vez (con una función, en su lugar, muchos "métodos virtuales"). – bua

+3

Por supuesto, la plantilla puede hacer que las dependencias en tiempo de compilación sean más difíciles ya que su implementación va al encabezado. –

0

Creo que la principal preocupación debería ser ...

  1. Funcionalidades El logro de
  2. Código extensibilidad
  3. Código Resuablity
  4. Código mantenibilidad
4

no diseñan demasiado desde el inicio, a continuación, escribir una prueba, a continuación, hacen pasar, pero no más que eso. Mantenga sus funciones muy corto. Mira lo que has hecho y refactor. Si va a escribir un comentario, mejor ponga el código en cuestión en una función separada con un buen nombre.

Y no pase mucho tiempo pensando en patrones, eso es mucha ciencia y poco resultado, simplemente escriba primero una prueba y mantenga su código simple; entonces, sorprendentemente, no necesita escribir pruebas para ello, ya lo has hecho Y tu código funciona

+1

"Si va a escribir un comentario, mejor ponga el código en cuestión en una función separada con un buen nombre" Este es un muy buen consejo. –

Cuestiones relacionadas