J'ai une collection de tests unitaires Boost que je veux exécuter en tant qu'application console.
Lorsque je travaille sur le projet et que j'exécute les tests, j'aimerais pouvoir déboguer les tests et je voudrais que la console reste ouverte après l'exécution des tests.
Je vois que si je lance en mode release, la fenêtre de la console reste ouverte après la fin du programme, mais en mode debug ce n'est pas le cas.
Je ne veux pas ajouter 'system ("pause");' ou tout autre piratage comme lire un personnage dans mon programme. Je veux juste faire une pause dans Visual Studio après avoir exécuté les tests avec le débogage comme si je fonctionnais en mode de publication. J'aimerais également que la sortie des tests soit capturée dans l'une des fenêtres de sortie de Visual Studio, mais cela semble également être plus difficile qu'il ne devrait l'être.
Comment puis-je faire ceci?
Boost test offre ce qui suit recommandations d'utilisation pour Visual Studio qui vous permettrait d'exécuter automatiquement les tests unitaires à la fin de la compilation et de capturer la sortie dans la fenêtre de génération.
L'effet secondaire de Nice de cette astuce est qu'il vous permet de traiter les échecs de test comme des erreurs de compilation. "... vous pouvez sauter ces erreurs en utilisant les raccourcis clavier/clics de souris habituels que vous utilisez pour l'analyse des erreurs de compilation ..."
Essayez d'exécuter l'application avec le Ctrl + F5 combinaison.
Dans les anciennes versions, il s'agissait par défaut du sous-système de console même si vous avez sélectionné "projet vide", mais pas en 2010, vous devez donc le définir manuellement. Pour ce faire, sélectionnez le projet dans l'explorateur de solutions à droite ou à gauche (probablement déjà sélectionné, vous n'avez donc pas à vous en soucier). Sélectionnez ensuite "projet" dans les menus déroulants de la barre de menu, puis sélectionnez " propriétés du nom du projet "> "propriétés de configuration"> "éditeur de liens"> "système" et définissez la première propriété, la liste déroulante "sous-système" sur "console (/ SUBSYSTEM: CONSOLE)". La fenêtre de la console doit maintenant rester ouverte après l'exécution, comme d'habitude.
Définissez un point d'arrêt sur la dernière ligne de code.
Je viens de copier à partir de http://social.msdn.Microsoft.com/forums/en-US/Vsexpressvc/thread/1555ce45-8313-4669-a31e-b95b5d28c787/?prof=required :
Ce qui suit fonctionne pour moi :-)
//////////////////////////////////////////////////// ////////////////////////////////////
Voici une autre raison pour laquelle la console peut disparaître. Et la solution:
Avec le nouveau Visual Studio 2010, vous pouvez voir ce comportement même lorsque vous utilisez Ctrl + F5 aka "commencer sans débogage". Cela est probablement dû au fait que vous avez créé un "projet vide" au lieu d'une "application console Win32". Si vous créez le projet en tant qu '"application console Win32", vous pouvez ignorer cela car il ne s'applique pas.
Dans les anciennes versions, il s'agissait par défaut du sous-système de console même si vous avez sélectionné "projet vide", mais pas dans Visual Studio 2010, vous devez donc le définir manuellement. Pour ce faire, sélectionnez le projet dans l'explorateur de solutions à droite ou à gauche (probablement déjà sélectionné, vous n'avez donc pas à vous en soucier).
Sélectionnez ensuite "projet" dans les menus déroulants de la barre de menus, puis sélectionnez " propriétés nom_projet " "" propriétés de configuration "→" éditeur de liens "→" système " et définissez la première propriété, la liste déroulante "sous-système" sur "console (/ SUBSYSTEM: CONSOLE)". La fenêtre de la console doit maintenant rester ouverte après l'exécution, comme d'habitude.
//////////////////////////////////////////////////// ////////////////////////////////////
S'il s'agit d'une application console, utilisez Ctrl + F5.
Dans Boost.Test, il y a le --auto_start_dbg
paramètre pour pénétrer dans le débogueur en cas d'échec d'un test (sur une exception ou sur un échec d'assertion). Pour une raison quelconque, cela ne fonctionne pas pour moi.
Pour cette raison, j'ai créé mon test_observer personnalisé qui entrera dans le débogueur en cas d'échec d'une assertion ou d'une exception. Ceci est activé sur les versions de débogage lorsque nous fonctionnons sous un débogueur.
Dans l'un des fichiers source de mon fichier EXE de test unitaire, j'ai ajouté ce code:
#ifdef _DEBUG
#include <boost/test/framework.hpp>
#include <boost/test/test_observer.hpp>
struct BoostUnitTestCrtBreakpointInDebug: boost::unit_test::test_observer
{
BoostUnitTestCrtBreakpointInDebug()
{
boost::unit_test::framework::register_observer(*this);
}
virtual ~BoostUnitTestCrtBreakpointInDebug()
{
boost::unit_test::framework::deregister_observer(*this);
}
virtual void assertion_result( bool passed /* passed */ )
{
if (!passed)
BreakIfInDebugger();
}
virtual void exception_caught( boost::execution_exception const& )
{
BreakIfInDebugger();
}
void BreakIfInDebugger()
{
if (IsDebuggerPresent())
{
/**
* Hello, I know you are here staring at the debugger :)
*
* If you got here then there is an exception in your unit
* test code. Walk the call stack to find the actual cause.
*/
_CrtDbgBreak();
}
}
};
BOOST_GLOBAL_FIXTURE(BoostUnitTestCrtBreakpointInDebug);
#endif
Vous dites que vous ne voulez pas utiliser le hack system("pause")
. Pourquoi pas?
Si c'est parce que vous ne voulez pas que le programme vous invite quand il est pas en cours de débogage, il existe un moyen de contourner cela. Cela fonctionne pour moi:
void pause () {
system ("pause");
}
int main (int argc, char ** argv) {
// If "launched", then don't let the console close at the end until
// the user has seen the report.
// (See the MSDN ConGUI sample code)
//
do {
HANDLE hConsoleOutput = ::GetStdHandle (STD_OUTPUT_HANDLE);
if (INVALID_HANDLE_VALUE == hConsoleOutput)
break;
CONSOLE_SCREEN_BUFFER_INFO csbi;
if (0 == ::GetConsoleScreenBufferInfo (hConsoleOutput, &csbi))
break;
if (0 != csbi.dwCursorPosition.X)
break;
if (0 != csbi.dwCursorPosition.Y)
break;
if (csbi.dwSize.X <= 0)
break;
if (csbi.dwSize.Y <= 0)
break;
atexit (pause);
} while (0);
Je viens de coller ce code dans chaque nouvelle application console que j'écris. Si le programme est exécuté à partir d'une fenêtre de commande, la position du curseur ne sera pas <0,0> et il n'appellera pas atexit()
. S'il a été lancé depuis votre débogueur (n'importe quel débogueur), la position du curseur de la console sera <0,0> et l'appel atexit()
sera exécuté.
J'ai eu l'idée d'un exemple de programme qui se trouvait dans la bibliothèque MSDN, mais je pense qu'il a été supprimé.
REMARQUE: l'implémentation Microsoft Visual Studio de la routine system () nécessite la variable d'environnement COMSPEC pour identifier l'interpréteur de ligne de commande. Si cette variable d'environnement est gâchée - par exemple, si vous avez un problème dans les propriétés de débogage du projet Visual Studio afin que les variables d'environnement ne soient pas correctement transmises au lancement du programme - alors il échouera silencieusement .
Ou vous pouvez utiliser boost_test "Test Log Output".
http://www.boost.org/doc/libs/1_47_0/libs/test/doc/html/utf/user-guide/test-output/test-log.html
Ensuite, peu importe si la fenêtre de la console s'affiche du tout ET votre journalisation de génération peut conserver la sortie de test unitaire comme un artefact pour l'examen des générations ayant échoué ...
J'utiliserais une commande "wait" pendant une durée spécifique (millisecondes) de votre choix. L'application s'exécute jusqu'à la ligne que vous souhaitez inspecter, puis continue après l'expiration du délai.
Inclure le <time.h>
entête:
clock_t wait;
wait = clock();
while (clock() <= (wait + 5000)) // Wait for 5 seconds and then continue
;
wait = 0;
Cela demanderait en fait plus d'efforts, mais vous pourriez simplement créer dans VS.Net, l'exécuter à partir de la ligne de commande standard (cmd.exe), puis vous attacher au processus après son démarrage. Cependant, ce n'est probablement pas la solution que vous recherchez.
Utilisez simplement une bibliothèque de journalisation, comme log4net, et demandez-lui de vous connecter à un appender de fichier.
Je démarre l'application avec F11 et j'obtiens un point d'arrêt quelque part dans unit_test_main.ipp (peut être le code d'assemblage). J'utilise shift-f11 (Step out) pour exécuter le test unitaire et obtenir la prochaine instruction d'assemblage dans le CRT (normalement dans mainCRTStartup ()). J'utilise F9 pour définir un point d'arrêt à cette instruction.
Lors de la prochaine invocation, je peux démarrer l'application avec F5 et l'application se cassera après l'exécution des tests, me donnant ainsi une chance de jeter un œil à la fenêtre de la console
Vous pouvez également configurer votre exécutable en tant qu'outil externe et marquer l'outil pour tiliser la fenêtre de sortie. De cette façon, la sortie de l'outil sera visible dans Visual Studio lui-même, pas dans une fenêtre distincte.
L'ajout de la ligne suivante fera un simple MS-DOS pause
n'affichant aucun message.
system("pause >nul | set /p \"=\"");
Et il n'est pas nécessaire de Ctrl+F5 (ce qui fera fonctionner votre application en mode Release)