- Présentation de GoogleTest
GoogleTest (souvent abrégé gtest) est un framework de tests unitaires C++ open source et multiplateforme (Linux, macOS, Windows, Cygwin, Windows CE, Symbian) développé par Google. Il permet d'écrire des tests en C++ sur différentes plateformes en fournissant des assertions variées : vérifications fatales ou non, tests paramétrés, tests de mortalité, etc.
- Préparation
Ce guide suppose un environnement Windows 10 avec Visual Studio 2015. La première étape consiste à télécharger et compiler GoogleTest pour obtenir les bibliothèques nécessaires.
2.1 Téléchargement des sources
Téléchargez le code source depuis le dépôt officiel : https://github.com/google/googletest. Vous obtenez une archive ZIP.
2.2 Compilation de GoogleTest
Décompressez l'archive dans un répertoire approprié. Ouvrez le fichier msvc/2010/gtest.sln avec Visual Studio 2015 ; acceptez la mise à jour des outils VC++.
Dans les propriétés du projet gtest (clic droit sur le projet), modifiez les paramètres selon la méthode au choix (les deux fonctionnent). Assurez-vous de compiler à la fois en configuration Debug et Release.
Lors de la compilation, un message "Impossible de lancer le programme" peut apparaître – c'est normal, car seules les bibliothèques statiques sont générées.
Après compilation, les fichiers gtestd.lib (Debug) et gtest.lib (Release) se trouvent respectivement dans msvc/2010/gtest/Win32-Debug et msvc/2010/gtest/Win32-Release.
2.3 Notions essentielles sur les assertions
GoogleTest utilise des macros pour réaliser des assertions. Il en existe deux familles principales :
- ASSERT_* : en cas d'échec, la fonction courante est interrompue (mais pas le test).
- EXPECT_* : en cas d'échec, l'exécution continue.
Voici les catégories les plus courantes :
| Comparaison booléenne | Macro | Condition |
|---|---|---|
| Vrai | ASSERT_TRUE(condition) EXPECT_TRUE(condition) | condition == true |
| Faux | ASSERT_FALSE(condition) EXPECT_FALSE(condition) | condition == false |
| Comparaison numérique | Macro | Condition |
| Égalité | ASSERT_EQ(expected, actual) EXPECT_EQ(expected, actual) | expected == actual |
| Inégalité | ASSERT_NE(val1, val2) EXPECT_NE(val1, val2) | val1 != val2 |
| Infériorité | ASSERT_LT(val1, val2) EXPECT_LT(val1, val2) | val1 < val2 |
| Infériorité ou égalité | ASSERT_LE(val1, val2) EXPECT_LE(val1, val2) | val1 <= val2 |
| Supériorité | ASSERT_GT(val1, val2) EXPECT_GT(val1, val2) | val1 > val2 |
| Supériorité ou égalité | ASSERT_GE(val1, val2) EXPECT_GE(val1, val2) | val1 >= val2 |
| Comparaison de chaînes C | Macro | Condition |
| Égalité (char* / wchar_t*) | ASSERT_STREQ(str1, str2) EXPECT_STREQ(str1, str2) | contenu identique |
| Inégalité | ASSERT_STRNE(str1, str2) EXPECT_STRNE(str1, str2) | contenu différent |
| Égalité sans casse (char* seulement) | ASSERT_STRCASEEQ(str1, str2) EXPECT_STRCASEEQ(str1, str2) | identique, ignorer la casse |
| Inégalité sans casse | ASSERT_STRCASENE(str1, str2) EXPECT_STRCASENE(str1, str2) | différent, ignorer la casse |
| Comparaison flottante | Macro | Condition |
| float | ASSERT_FLOAT_EQ(val1, val2) EXPECT_FLOAT_EQ(val1, val2) | presque égaux |
| double | ASSERT_DOUBLE_EQ(val1, val2) EXPECT_DOUBLE_EQ(val1, val2) | presque égaux |
| Comparaison approchée | Macro | Condition |
| Écart absolu | ASSERT_NEAR(val1, val2, abs_error) EXPECT_NEAR(val1, val2, abs_error) | |val1 - val2| <= abs_error |
| Test d'exception | Macro | Comportement |
| Exception spécifique | ASSERT_THROW(statement, exception_type) EXPECT_THROW(statement, exception_type) | l'instruction lève une exception du type donné |
| Exception quelconque | ASSERT_ANY_THROW(statement) EXPECT_ANY_THROW(statement) | l'instruction lève une exception |
| Pas d'exception | ASSERT_NO_THROW(statement) EXPECT_NO_THROW(statement) | aucune exception |
| Prédicats (jusqu'à 5 arguments) | Macro | |
| Prédicat unaire | ASSERT_PRED1(pred, val1) EXPECT_PRED1(pred, val1) | |
| Prédicat binaire | ASSERT_PRED2(pred, val1, val2) EXPECT_PRED2(pred, val1, val2) | |
| HRESULT Windows | Macro | |
| Succès | ASSERT_HRESULT_SUCCEEDED(expression) EXPECT_HRESULT_SUCCEEDED(expression) | |
| Échec | ASSERT_HRESULT_FAILED(expression) EXPECT_HRESULT_FAILED(expression) | |
| Prédicats formatés (jusqu'à 5 arguments) | Macro | |
| Format unaire | ASSERT_PRED_FORMAT1(pred, val1) EXPECT_PRED_FORMAT1(pred, val1) | |
| Format binaire | ASSERT_PRED_FORMAT2(pred, val1, val2) EXPECT_PRED_FORMAT2(pred, val1, val2) |
2.4 Création du projet de test
Dans Visual Studio 2015, créez un projet Application console Win32 nommé MyTest. Ouvrez les propriétés du projet :
- Propriétés de configuration → C/C++ → Général : dans Répertoires Include supplémentaires, ajoutez
.\include(chemin relatif vers le dossier include de GoogleTest). - Propriétés de configurasion → C/C++ → Génération de code : modifiez Bibliothèque runtime en Multithread Debug DLL (/MDd) pour Debug, et /MD pour Release.
- Propriétés de configuration → Éditeur de liens → Entrée : dans Dépenadnces supplémentaires, ajoutez le chemin complet vers
gtestd.lib(Debug) ougtest.lib(Release).
2.5 Écriture des tests
Nous créons trois fichiers : TestPrincipal.cpp, MonBoite.h et MonBoite.cpp. Voici une version remaniée du code :
// MonBoite.h
#pragma once
class MonBoite {
public:
MonBoite(double longueur, double largeur, double hauteur);
MonBoite(); // constructeur par défaut
double CalculerVolume() const;
private:
double m_longueur;
double m_largeur;
double m_hauteur;
};
// MonBoite.cpp
#include "pch.h"
#include "MonBoite.h"
#include <iostream>
MonBoite::MonBoite(double longueur, double largeur, double hauteur)
: m_longueur(longueur), m_largeur(largeur), m_hauteur(hauteur) {
std::cout << "Constructeur paramétré appelé.\n";
}
MonBoite::MonBoite()
: m_longueur(0), m_largeur(0), m_hauteur(0) {
std::cout << "Constructeur par défaut appelé.\n";
}
double MonBoite::CalculerVolume() const {
return m_longueur * m_largeur * m_hauteur;
}
// TestPrincipal.cpp
#include "pch.h"
#include "gtest/gtest.h"
#include "MonBoite.h"
// Fixture pour tester MonBoite
class MonBoiteTestFixture : public ::testing::Test {
protected:
MonBoite* boite;
void SetUp() override {
boite = new MonBoite(2.0, 3.0, 4.0);
}
void TearDown() override {
delete boite;
}
};
TEST(MonBoiteTest, VolumeCalcul) {
MonBoite b1(78.0, 24.0, 18.0);
MonBoite b2;
EXPECT_LT(23.0, b1.CalculerVolume());
}
TEST_F(MonBoiteTestFixture, VolumeAvecFixture) {
EXPECT_EQ(24.0, boite->CalculerVolume()); // 2*3*4 = 24
}
int main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
3. Problèmes rencontrés et solutions
- Erreur "application Win32 non valide" lors de la compilation de gtest : c'est normal, seules des bibliothèques statiques sont produites, pas d'exécutable.
- Bibliothèque runtime incohérente : assurez-vous que le paramètre Bibliothèque runtime du projet de test correspond à celui utilisé lors de la compilation de GoogleTest (ex. /MDd en Debug).
- Fichier .lib manquant dans les dépendances supplémentaires : indiquez le chemin complet incluant le nom du fichier (gtestd.lib ou gtest.lib).