2012-03-13 15 views
7

Quiero entender la mejor manera de diseñar aplicaciones comprobables en C++, quizás en comparación con C# (porque su mi fondo y grande para las pruebas)Diseño de la capacidad de prueba en C++

Estoy acostumbrado a la codificación de las interfaces, inyección de dependencia, inversión de marcos de control y objetos simulados. Como C# tiene muchas características de lenguaje diferentes, no estoy seguro de cuánto de los patrones se deben aplicar. También me imagino que las características/limitaciones únicas de C++ podrían prestar a diferentes estrategias de prueba.

He examinado los marcos de prueba de unidades, y me gusta Google Test, pero también es importante escribir mi nuevo código para poder probarlo.

  • ¿Hay proyectos de código abierto que podría ser recomendado como prueba de C++ bien hecho?
  • ¿Algún libro o artículo que aborde este tema con mayor detalle?
  • Recomendaciones para marcos/librerías adicionales

, gracias

Respuesta

3

Estoy exactamente en la misma situación, en este momento. Procedente de un entorno C#, ahora estoy escribiendo aplicaciones C++ nuevas (y en expansión heredadas).

Supongo que el fondo compartido nos deja con preguntas comunes en el futuro. Me sorprendió cuán estrechamente dependían las dependencias de nuestras clases en las aplicaciones heredadas.

La preocupación, como parece haber resaltado, es que tal vez la mejor práctica en C# no es la mejor manera en C++. Después de mucha investigación, algunas preguntas sobre el desbordamiento de pila y algunos prototipos, terminé con una arquitectura en C++ que de muchas maneras refleja lo que creí que funcionaba mejor en C#.

Éstos son los principales directores que estoy usando:

  • inyección de dependencias

    constructores para nuestras clases tienen las interfaces para las dependencias que lo que se quiere burlarse como parámetros. En algunos casos, esto significó escribir wrappers para dependencias, como boost :: filesystem, por ejemplo, que se implementa principalmente en encabezados con plantillas. Merece la pena el pequeño esfuerzo, en mi opinión, ya que nos relaciona de forma más flexible con bibliotecas que pueden cambiar o ser intercambiadas por nosotros, y nos permite realizar pruebas unitarias con implementaciones simuladas.

  • ¡Prueba mientras avanzas!

    Esto no hace falta decirlo, pero escribir pruebas mientras escribe la clase le permite comprobar con cordura su diseño en lo que respecta a la capacidad de prueba. No me importa que pruebe primero, haga TDD, o como lo llame, mi filosofía es simplemente escribir sus pruebas antes de comenzar a consumir la clase en su base de códigos.

  • Google prueba como nuestro marco de prueba de unidad

    Hasta ahora, he utilizado CxxTest (aplicaciones heredadas) y la Prueba de Google.Google Test proporciona una gran cantidad de opciones flexibles en el momento de la ejecución para determinar qué conjunto de pruebas se ejecutan. Dividimos nuestra convención de nombres de clase a UnitTest_xxxx y IntegrationTest_xxxx. Luego, en la línea de comando, puedo decirle a gtest que solo ejecute pruebas con un nombre, el otro o ambos. Entonces mi servidor de compilación puede ejecutar las pruebas de larga duración en todo el conjunto de pruebas por la noche, pero la unidad lo prueba en cada check in. Cxxtest podría hacer lo mismo, pero con más trabajo, y generalmente es torpe por muchas razones.

  • Google Mock de objetos simulados en tiempo de prueba

    El beneficio obvio de la inyección de dependencia está utilizando objetos burlaron durante la prueba. Uno podría simplemente escribir implementaciones falsas de cada interfaz, pero Google Mock permite un giro rápido de objetos falsos y proporciona las comprobaciones típicas que cabría esperar de un buen marco de burla .NET como Moq o RhinoMock.

1

En algunas ocasiones he visto todas las técnicas que mencionas (que codifica a las interfaces, la inyección de dependencias, la inversión de los marcos de control y objetos simulados) víctima de abuso y, finalmente, hacer las cosas más difíciles. Aunque se puede dar un buen uso a estas técnicas, a veces las he visto predicadas como si fueran el único camino hacia la calidad. Estoy en desacuerdo.

Desde mi punto de vista, la técnica de desarrollo más importante para garantizar la calidad del código en C++ está utilizando técnicas orientadas a objetos como modularidad, el principio de Abierto Cerrado, la auto-documentación, Separación de comandos de consulta, etc.

En particular, dos técnicas que me parece esencial son Diseño por contrato (ver las preguntas y What is the best way of implementing assertion checking in C++?Design by Contract in C++?) y Unidad de Pruebas (ver preguntas relacionadas 1, 2, 3). Para ambos, tienes herramientas razonables en C++, como muestran las preguntas vinculadas.

+0

La inyección de dependencias de las interfaces es la herramienta principal que hace posible las pruebas unitarias. –

+0

@DanBryant Bueno, C++ no tiene interfaces, pero las personas hacen pruebas unitarias en él. –

+1

Buenos contrapuntos. No pretendo que haya una sola forma de diseñar y probar correctamente. +1 para proporcionar ideas frescas. Design by Contract es en realidad una práctica que he utilizado con éxito si C#, y me olvidé en mi nuevo entorno. Parcialmente porque .NET Code Contracts lo hace tan fácil en C#. – Evan

0

puedo recomendar UnitTest++ y AMOP para hacer desarrollo basado en pruebas. Ambos son muy simples de configurar y son muy potentes. Si no necesita todas las características en Google Test, esta es una buena opción.

Puede parecer como que están fechadas, ya que no se han actualizado desde hace tiempo, pero no he tenido un solo problema con ellos.

Cuestiones relacionadas