c++ - Unidad de prueba de clases no exportadas en una DLL
visual-studio unit-testing (4)
Desarrollamos una aplicación C ++ utilizando Visual Studio 2008 y una prueba unitaria utilizando Boost.Test. Por el momento, tenemos una solución separada que contiene nuestras pruebas unitarias.
Muchos de nuestros proyectos en la solución central producen DLL. Estamos limitados en la cobertura de pruebas porque no podemos probar clases no exportadas.
Tengo dos ideas sobre cómo estos podrían ser probados:
- Exportar todo
- Coloque las pruebas dentro de la DLL (mismo proyecto y solución) y use el corredor externo de Boost.Test
No estoy del todo seguro de cuáles serían los inconvenientes. El número 1 anterior rompe la encapsulación a nivel de módulo, y el número 2 podría resultar en una DLL mucho más grande, a menos que sea posible incluir solo el código de prueba en ciertas configuraciones.
Entonces, ¿hay algún inconveniente grave en los métodos anteriores, o puedes pensar en otras soluciones?
Ampliando la respuesta de Tom Quarendon a esta pregunta , he usado una pequeña variante de la respuesta de Simon Steele:
- Cree un proyecto de prueba (utilizando el marco de prueba que desee, uso CppUnit ).
- En su test_case.cpp,
#include <header/in/source/project.h>
. - En las propiedades del proyecto de prueba:
- En Linker-> General, agregue
$(IntDir)
del proyecto de$(IntDir)
a los Directorios de la Biblioteca Adicional. - En Linker-> Input, agregue los archivos
.obj
a las Dependencias Adicionales.
- En Linker-> General, agregue
- Agregue la dependencia del proyecto de prueba al proyecto de origen en Proyecto-> Dependencias del proyecto.
Una vez más, la única sobrecarga de mantenimiento es la estándar para las pruebas de unidades: para crear la dependencia de las unidades que desea probar.
Intente hacer una definición como la siguiente en algún lugar donde todos los archivos incluirán:
#define EXPORTTESTING __declspec(dllexport)
Y úselo en lugar del dllexport, así:
class EXPORTTESTING Foo
{
...
};
Luego podrá desactivar el indicador para crear una DLL de lanzamiento, pero manténgala activada para una DLL que se pueda probar por unidad.
La solución que utilizo para esto es crear el mismo código no exportado en mi DLL de pruebas también. Esto aumenta el tiempo de construcción y significa agregar todo a ambos proyectos, pero ahorra exportarlo todo o poner las pruebas en el código principal del producto.
Otra posibilidad sería compilar el código no exportado en una biblioteca que sea utilizada tanto por la DLL con exportaciones como por el proyecto de prueba de unidad.
También estaba buscando una solución, tal vez lo siguiente sea más fácil de mantener.
Agregue una nueva configuración de compilación, por ejemplo, "Unit testing Debug" al proyecto DLL y cambie el Tipo de configuración para que sea "Biblioteca estática .lib" ("General" -> "Tipo de configuración").
Luego, simplemente agregue una dependencia de las pruebas de unidad en este proyecto, ahora todo debería estar unido cuando utilice la nueva configuración de compilación "Depuración de prueba de unidad". Si está utilizando compilaciones de lanzamiento para pruebas unitarias, entonces necesita agregar otra configuración con optimizaciones de lanzamiento.
Así que los beneficios de esta solución son:
- bajo costo de mantenimiento
- proyecto DLL / biblioteca estática
- no tiene que enlazar manualmente a archivos .obj
Inconvenientes:
- Los perfiles de configuración adicionales requerirán algunos cambios en su entorno de compilación (CI)
- Mayores tiempos de compilación.
Actualización: En realidad terminamos usando un enfoque diferente.
Agregamos nuevas configuraciones de "Prueba de depuración" / "Versión de prueba" para cada proyecto existente que tenemos.
Para los proyectos .exe / .dll inhabilitamos el main.cpp original de la compilación y lo reemplazamos con el que crea una instancia del marco de prueba (por ejemplo, gtest) y ejecuta todas las pruebas, las pruebas se encuentran en archivos .cpp separados que también se excluyen de compilación en configuraciones regulares (Release / Debug) y habilitada solo en configuraciones de prueba.
Para los proyectos .lib también tenemos nuevas configuraciones de "Prueba de depuración" / "Versión de prueba" y allí convertimos la biblioteca estática en un archivo .exe y proporcionamos main.cpp que crea una instancia del marco de prueba y ejecuta las pruebas y los análisis por sí mismos. Los archivos relacionados con la prueba se excluyen de la compilación en las configuraciones de Liberación / Liberación.