Pruebas unitarias para código C ++ – Herramientas y metodología

Estoy trabajando en un gran sistema de c ++ que ha estado en desarrollo desde hace unos años. Como parte de un esfuerzo para mejorar la calidad del código existente, participamos en un gran proyecto de refactorización a largo plazo.

¿Conoces una buena herramienta que pueda ayudarme a escribir pruebas unitarias en C ++? Tal vez algo similar a Junit o Nunit?

¿Puede alguien dar un buen consejo sobre la metodología de escribir pruebas unitarias para módulos que se escribieron sin tener en cuenta las pruebas unitarias?

La aplicación de pruebas unitarias al código heredado fue la razón por la que se escribió Working Effectively with Legacy Code . Michael Feathers es el autor, como se menciona en otras respuestas, participó en la creación de CppUnit y CppUnitLite .

texto alternativo http://sofes.miximages.com/refactoring/51RCXGPXQ8L._SL160_AA115_.jpg

Google lanzó recientemente su propia biblioteca para pruebas unitarias de aplicaciones C ++, llamada Google Test.

Proyecto en Google Code

Vea una excelente comparación entre varias suites disponibles. El autor de ese artículo desarrolló más tarde UnitTest ++ .

Lo que particularmente me gusta (aparte del hecho de que maneja excepciones, etc.) es que hay una cantidad muy limitada de ‘administración’ alrededor de los casos de prueba y la definición de los accesorios de prueba.

Boost tiene una biblioteca de pruebas que contiene soporte para pruebas unitarias. Vale la pena echarle un vistazo.

Noel Llopis de Games From Within es el autor de Explorando el Jungle Testing Unit Jungle de C ++ , una evaluación exhaustiva (pero ahora anticuada) de los diversos frameworks de C ++ Unit Testing, así como un libro sobre progtwigción de juegos.

Utilizó CppUnitLite durante bastante tiempo, reparando varias cosas, pero finalmente se unió a otro autor de la biblioteca de pruebas unitarias, y produjo UnitTest ++ . Usamos UnitTest ++ aquí, y me gusta mucho, hasta ahora. Tiene (para mí) el equilibrio exacto de poder con una huella pequeña.

He usado soluciones propias, CxxTest (que requiere Perl) y boost :: test. Cuando implementé las pruebas unitarias aquí en mi trabajo actual, prácticamente todo se redujo a UnitTest ++ vs boost :: test.

Realmente me gusta la mayoría de las bibliotecas de impulso que he usado, pero en mi humilde opinión, boost :: test es un poco demasiado torpe. Especialmente no me gustó que requiera que usted (AFAIK) implemente el progtwig principal del arnés de prueba usando una macro boost :: test. Sé que no es TDD “puro”, pero a veces necesitamos una forma de ejecutar pruebas desde una aplicación GUI, por ejemplo cuando se pasa un indicador de prueba especial en la línea de comando, y boost :: test no puede soportar este tipo de escenario.

UnitTest ++ fue el marco de prueba más simple para configurar y usar que he encontrado en mi experiencia (limitada).

Estoy usando la excelente biblioteca Boost.Test junto con una biblioteca Turtle mucho menos conocida pero tan impresionante: una biblioteca de objetos simulados basada en boost.

Como un ejemplo de código habla mejor que las palabras, imagine que le gustaría probar un objeto de calculator que funciona en una interfaz de view (que es el ejemplo introductorio de Turtle):

 // declares a 'mock_view' class implementing 'view' MOCK_BASE_CLASS( mock_view, view ) { // implements the 'display' method from 'view' (taking 1 argument) MOCK_METHOD( display, 1 ) }; BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero ) { mock_view v; calculator c( v ); // expects the 'display' method to be called once with a parameter value equal to 0 MOCK_EXPECT( v, display ).once().with( 0 ); c.add( 0, 0 ); } 

Vea qué fácil y detallado es declarar expectativa sobre el objeto simulado? Obviamente, la prueba falla si no se cumplen las expectativas.

Acabo de sacar mi propio marco, CATCH , por ahí. Todavía está en desarrollo, pero creo que ya supera a la mayoría de los otros marcos. Diferentes personas tienen diferentes criterios, pero he tratado de cubrir la mayor parte del terreno sin demasiadas concesiones. Eche un vistazo a mi entrada de blog vinculada para una prueba. Mis cinco principales características son:

  • Solo encabezado
  • Registro automático de funciones y pruebas basadas en métodos
  • Descompone las expresiones estándares de C ++ en LHS y RHS (por lo que no necesita una familia completa de macros assert).
  • Soporte para secciones anidadas dentro de un accesorio basado en función
  • Pruebas de nombres usando lenguaje natural – se generan nombres de funciones / métodos

También tiene enlaces de Objective-C.

CxxTest es un framework ligero, fácil de usar y multiplataforma JUnit / CppUnit / xUnit para C ++.

CppUnit es el camino. Ver el enlace a continuación:

http://cppunit.sourceforge.net/cppunit-wiki

http://en.wikipedia.org/wiki/CppUnit

UnitTest ++ , pequeño y simple.

Actualmente estoy buscando una prueba unitaria y un marco simulado que se pueda utilizar en nuestra empresa para una base de código de larga duración. Como usted sabe, la lista de marcos de pruebas unitarias para c ++ es larga, así que apliqué algunos filtros para reducirla a una mano completa que se puede examinar más de cerca. El primer criterio de filtro fue que debe ser gratis. El segundo criterio fue la actividad del proyecto. También busqué marcos burlones porque necesitas uno si deseas escribir pruebas unitarias.

Se me ocurrió la siguiente lista (aproximadamente) ordenada por actividad, la actividad más alta en la parte superior:

  • GoogleTest / GoogleMock: muchos contribuidores y utilizados por Google. Esto probablemente estará aquí por un tiempo y recibirá actualizaciones. Para mi base de código privada voy a cambiar a esta combinación con la esperanza de saltar en el tren más rápido.

  • BoostTest + Turtle: no se actualizó con tanta frecuencia, pero el marco de prueba es parte del impulso, por lo que debe mantenerse. La tortuga, por otro lado, es mantenida principalmente por un hombre, pero ha resentido la actividad por lo que no está muerta. Hice casi toda mi experiencia de prueba con esta combinación porque ya usamos la biblioteca de impulso en mi trabajo anterior y actualmente la uso para mi código privado.

  • CppUTest: proporciona pruebas y burlas. Este proyecto ha estado activo de 2008 a 2015 y tiene una actividad bastante reciente. Este hallazgo fue una pequeña sorpresa porque muchos proyectos con mucha menos actividad aparecen con mayor frecuencia cuando se busca en la web (como CppUnit, que tuvo su última actualización en 2013). No he profundizado en esto, así que no puedo decir nada sobre los detalles. Editar (16.12.2015): Hace poco probé y encontré que este marco es un poco torpe y “C-elegante”, especialmente cuando se usan las clases simuladas. También parecía tener una menor variedad de afirmaciones y otros marcos. Creo que su principal fortaleza es que se puede usar con proyectos de C puro.

  • QTest: la biblioteca de prueba que se envía con el marco de Qt. El mantenimiento debe garantizarse por algún tiempo, pero lo uso más bien como una biblioteca de apoyo, porque el registro de prueba es IMO más torpe que en otros marcos. Por lo que yo entiendo, te obliga a tener un test-exe por dispositivo de prueba. Pero las funciones de ayuda de prueba pueden ser de gran utilidad cuando se prueba el código Qt-Gui. No tiene burlas.

  • Captura: tiene actividad reciente, pero la desarrolla principalmente un hombre. Lo bueno de este marco es el enfoque de dispositivo alternativo que le permite escribir código de dispositivo reutilizable en la prueba en sí. También le permite establecer nombres de prueba como cadenas, lo que es bueno cuando tiende a escribir oraciones completas como nombres de prueba. Me gustaría que este estilo sea copiado y puesto en googleTest 😉

Marcos falsos

El número de frameworks simulados es mucho más pequeño que el número de frameworks de prueba, pero estos son los que encontré que tienen actividad reciente.

  • Hippomock : Activo desde 2008 unitl ahora pero solo con baja intensidad.

  • FakeIt : activo a partir de 2013 unitl ahora pero más o menos desarrollado por un chico.

Conclusión

Si su base de código está en el largo plazo, elija entre BoostTest + Turtle y GoogleTest + GoogleMock . Creo que esos dos tendrán mantenimiento a largo plazo. Si solo tienes una base de códigos de corta duración, puedes probar Catch, que tiene una syntax agradable. Entonces necesitarías elegir un marco de burla adicional. Si trabaja con Visual Studio, puede descargar los adaptadores de prueba-corredor para BoostTest y GoogleTest, que le permitirán ejecutar las pruebas con la GUI del corredor de prueba que está integrada en VS.

Consulte también las respuestas a la pregunta estrechamente relacionada “elegir una herramienta / marco de prueba de unidades de C ++”, aquí

También existe el TUT , Template-Unit-Test, un marco basado en plantillas. Su syntax es incómoda (algunos lo llamaron abuso de plantillas), pero su principal ventaja es que todo está contenido en un solo archivo de encabezado .

Aquí encontrará un ejemplo de prueba unitaria escrita con TUT .

He probado CPPunit y no es muy fácil de usar.

La única alternativa que conozco es el uso de C ++ .NET para ajustar tus clases de C ++ y las pruebas de unidad de escritura con uno de los frameworks de prueba de unidades .NET (NUnit, MBUnit, etc.)

CppUTest es un marco excelente y liviano para pruebas de unidades C y C ++.

Michael Feathers de ObjectMentor fue fundamental en el desarrollo de CppUnit y CppUnitLite.

Ahora recomienda CppUnitLite

Eche un vistazo a CUnitWin32 . Está escrito para MS Visual C. Incluye un ejemplo.

Eche un vistazo a cfix ( http://www.cfix-testing.org ), está especializado para el desarrollo de Windows C / C ++ y es compatible tanto con el modo de usuario como con la prueba de unidad de modo kernel.

Si está en Visual Studio 2008 SP1, le recomendaría usar MSTest para escribir las pruebas unitarias. A continuación, utilizo el simulacro de Google para escribir los simulacros. La integración con el IDE es ideal y permite y no implica la sobrecarga de CPPunit en términos de edición de tres lugares para la adición de una prueba.

Creo que VisualAssert está haciendo un gran trabajo en la integración de VS. Le permite ejecutar y depurar las pruebas de VS y no necesita crear un ejecutable para ejecutar las pruebas.

Vea fructosa: http://sourceforge.net/projects/fructose/

Es un marco muy simple, que contiene solo archivos de cabecera y por lo tanto fácil de transportar.

Estoy usando MS Test con Typemock Isolator ++ . ¡Darle una oportunidad!