Pruebas unitarias para código C ++ - Herramientas y metodología [cerrado]

134

Estoy trabajando en un gran sistema c ++ que ha estado en desarrollo durante algunos años. Como parte de un esfuerzo por 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?

¿Alguien puede dar buenos consejos sobre la metodología de escribir pruebas unitarias para módulos que fueron escritos sin tener en cuenta las pruebas unitarias?

Sakin
fuente
1
Echa un vistazo a esta pregunta: stackoverflow.com/questions/3150/…
Aardvark

Respuestas:

83

La aplicación de pruebas unitarias al código heredado fue la razón por la que se escribió Trabajar eficazmente con código heredado . Michael plumas es el autor - como se ha mencionado en otras respuestas, se vio involucrado en la creación tanto CPPUnit y CppUnitLite .

texto alternativo

Joe Schneider
fuente
44
Se agregó una miniatura: se votó. El libro ayuda más que cualquier herramienta.
Gishu
2
Creo que CPPUnit podría simplificar la escritura de pruebas. Usamos CPPUnit, pero no estoy satisfecho. Necesito actualizar dos archivos para cada prueba y, en mi opinión, una prueba debe ser tan simple de escribir como: 'TEST ("testname") {ASSERT (1 == 1);}' El libro, por otro lado, es imprescindible para todos, no solo para quienes trabajan con código heredado, sino también para quienes lo crean;)
daramarak
9
¿Desde cuándo es legado de C ++?
Nils
9
No es que C ++ sea heredado; si no recuerdo mal, ese libro define un proyecto heredado como uno para el que no hay ninguno o muy pocas pruebas unitarias. Dichos proyectos tienden a ser / difíciles / para escribir pruebas unitarias, porque el desarrollo impulsado por pruebas nunca ha influido en la base del código, de modo que es trivial escribirlos.
Arafangion
77
@Nils: Como menciona uno de los revisores de Amazon del libro, "el código heredado es código sin pruebas unitarias", que es exactamente de lo que trata esta pregunta.
David Johnstone
40

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

Proyecto en Google Code

agnul
fuente
1
¿es posible usar esto con VC ++
yesraaj
Parece bastante bien, especialmente la forma en que tienen que agregar una descripción a cada afirmación. En el lado negativo, personalmente prefiero tener una clase de Prueba de Unidad en lugar de macros que realmente no se parecen a las clases.
Wernight
3
Otro buen punto son las posibilidades de burlarse: code.google.com/p/googlemock
Philipp
Me parece MUCHO mejor que CPPUNIT, que requiere toneladas de macros y archivos mágicos para que las pruebas funcionen
Paul
30

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

Lo que más me gusta de esto (aparte del hecho de que maneja bien las excepciones, etc.) es que hay una cantidad muy limitada de "administración" en torno a los casos de prueba y la definición de los accesorios de prueba.

andreas buykx
fuente
2
¿No es esa nuestra falacia fundamental? Tiene una buena idea de los proyectos disponibles, pero en lugar de mejorarlos, comienza el suyo.
peterchen
@peterchen: sí; pero UnitTest ++ es tan pequeño y ligero que tiene valor para ser un proyecto separado: es muy fácil de poner en marcha.
TimStaley
24

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

Jonas
fuente
44
Puedo recomendar este excelente kit de herramientas.
Rob
1
Sí, impulsar es el camino a seguir. Sin gastos generales, solo prueba y listo. En realidad, estaba trabajando en mi propio marco en la desesperación cuando el impulso vino a mi rescate. Gracias impulso (por todo!)
daramarak
Puede consultar un artículo que escribí Introducción Boost Unit Testing beroux.com/english/articles/boost_unit_testing
Wernight
21

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

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

He usado soluciones de cosecha propia, CxxTest (que requiere Perl) y boost :: test. Cuando implementé las pruebas unitarias aquí en mi trabajo actual, 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 pesado. Especialmente no me gustó que requiera (AFAIK) implementar el programa 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 admitir este tipo de escenario.

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

Brian Stewart
fuente
17

Estoy usando la excelente biblioteca Boost.Test junto con una biblioteca Turtle mucho menos conocida pero increíble : 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 calculatorobjeto que funciona en una viewinterfaz (ese 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 );
}

¿Ves lo fácil y detallado que es declarar expectativas sobre el objeto simulado? Obviamente, la prueba falla si no se cumplen las expectativas.

crimen de hielo
fuente
14

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

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

También tiene enlaces Objective-C.

philsquared
fuente
44
doctest es mi reimplementación de Catch con un gran enfoque en la velocidad de compilación - consulte las preguntas frecuentes para ver cómo son diferentes
onqtam
9

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

David Sykes
fuente
6

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 saben, la lista de marcos de pruebas unitarias para c ++ es larga, por lo que apliqué algunos filtros para reducirla a un nivel completo que se pueda ver 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 de trabajo burlones porque necesitas uno si quieres 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 contribuyentes y utilizados por el propio Google. Esto probablemente estará aquí por algún tiempo y recibirá actualizaciones. Para mi base de código privada, cambiaré a esta combinación con la esperanza de subirme al tren más rápido.

  • BoostTest + Turtle: No se actualiza 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 tiene actividad resentida, 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 desde 2008 hasta 2015 y tiene bastante actividad reciente. Este hallazgo fue una pequeña sorpresa porque muchos proyectos con una actividad significativamente menor surgen con más 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): Recientemente probé esto y descubrí que este marco es un poco torpe y "elegante", especialmente cuando uso las clases simuladas. También parecía tener una menor variedad de afirmaciones que otros marcos. Creo que su principal fortaleza es que se puede usar con proyectos C puros.

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

  • Captura: tiene actividad reciente pero es desarrollada principalmente por un tipo. Lo bueno de este marco es el enfoque de fijación alternativa que le permite escribir código de fijación reutilizable en la prueba misma. También le permite establecer nombres de prueba como cadenas, lo cual es bueno cuando tiende a escribir oraciones completas como nombres de prueba. Quisiera que este estilo sea arrancado y puesto en googleTest ;-)

Marcos simulados

El número de marcos simulados es mucho menor que el número de marcos 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 desde 2013 unitl ahora pero más o menos desarrollado por un tipo.

Conclusión

Si su código base está listo para el largo plazo, elija entre BoostTest + Turtle y GoogleTest + GoogleMock . Creo que esos dos tendrán mantenimiento a largo plazo. Si solo tiene una base de código de corta duración, puede probar Catch, que tiene una buena sintaxis. Luego, deberá elegir adicionalmente un marco burlón. Si trabaja con Visual Studio, puede descargar adaptadores de test-runner para BoostTest y GoogleTest, que le permitirán ejecutar las pruebas con la GUI de runner de prueba que está integrada en VS.

Knitschi
fuente
3

Consulte también las respuestas a la pregunta estrechamente relacionada "elegir una herramienta / marco de prueba de unidad c ++", aquí

TonJ
fuente
3

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

Encontrarás un ejemplo de prueba unitaria escrita con TUT aquí.

philant
fuente
2
Puse una biblioteca de solo encabezado que proporciona macros que ajustan los TUT para garantizar la función y probar el código de declinación para simplificarlo y proporcionar información de archivos y números de línea en caso de fallas. Aquí hay un enlace a una publicación con ejemplos de la diferencia en la salida y el código, así como un enlace al proyecto en github: codecrafter.wordpress.com/2012/12/19/tutadapter1
Josh Heitzman
2

Probé CPPunit y no es muy fácil de usar.

La única alternativa que conozco es usar C ++. NET para ajustar sus clases de C ++ y escribir pruebas unitarias con uno de los marcos de pruebas unitarias .NET (NUnit, MBUnit, etc.)

Dror Helper
fuente
2

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

Ratkok
fuente
1

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

Ahora recomienda CppUnitLite

Seb Rose
fuente
1

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

Dushara
fuente
1

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 las pruebas de unidad de modo de núcleo.

Johannes pasando
fuente
Gracias por compartir. Recientemente comencé a usar cfix con fines de prueba. Estaba buscando una manera de ver la pila de llamadas tanto en caso de casos de prueba aprobados como fallidos. ¿Hay alguna manera en cfix para lograr esto?
tryingToLearn el
1

Si está en Visual Studio 2008 SP1, le recomiendo utilizar MSTest para escribir las pruebas unitarias. Luego uso el simulacro de Google para escribir los simulacros. La integración con el IDE es ideal y permite y no conlleva la sobrecarga de CPPunit en términos de edición de tres lugares para la adición de una prueba.

Jared
fuente
1

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

Ohad Horesh
fuente