Skip to content

Commit 7a87933

Browse files
Test: Amélioration de la couverture des tests unitaires (#28)
- Ajout de tests unitaires afin d'augmenter la couverture des tests unitaires sur le code - Amélioration de la docstring des fonctions de test unitaire - Ajout de la nouvelle dépendance 'pytest-mock' qui est nécessaire pour les tests unitaires du module main.py - Ajout d'une fonction main dans main.py pour faciliter les tests unitaires - Suppression d'une vérification de type dans parseur_log_apache.py qui ne pouvait jamais être atteinte grâce au regex
1 parent 9973aa1 commit 7a87933

9 files changed

Lines changed: 421 additions & 79 deletions

.github/workflows/tests.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ jobs:
3333
python -m pip install --upgrade pip
3434
pip install pytest
3535
pip install pytest-cov
36+
pip install pytest-mock
3637
3738
# Étape 4 : Lancer les tests unitaires
3839
- name: Lancer les tests unitaires

app/main.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
from analyse.analyseur_log_apache import AnalyseurLogApache
99

1010

11-
if __name__ == "__main__":
11+
def main():
12+
"""
13+
Point d'entrée de l'application.
14+
"""
1215
colorama.init()
1316
print(colorama.Style.DIM + r"""
1417
.-. .-') .-') .-') _ ('-. _ .-') ,---.
@@ -41,3 +44,7 @@
4144
print(f"Erreur dans l'analyse du log Apache !\n{ex}")
4245
except Exception as ex:
4346
print(f"Erreur interne !\n{ex}")
47+
48+
49+
if __name__ == "__main__":
50+
main()

app/parse/parseur_log_apache.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,7 @@ def parse_entree(self, entree):
114114

115115
# Récupération des informations liées à la réponse
116116
code_statut = self.get_information_entree(resultat_analyse, "code_status")
117-
if code_statut:
118-
code_statut = int(code_statut)
119-
120-
if code_statut is None:
121-
raise FormatLogApacheInvalideException("Le code de statut HTTP est obligatoire.")
117+
code_statut = int(code_statut)
122118

123119
taille_octets = self.get_information_entree(resultat_analyse, "taille_octets")
124120
if taille_octets:

tests/conftest.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@
3636

3737
'::1 - - [05/Mar/2025:16:59:43] "DELETE / HTTP/2.1" 200 20',
3838

39-
'192.168.1.1 - [12/Jan/2025:10:15:32 +0000] "GET /index.html HTTP/1.1" test 532'
39+
'- - - [12/Jan/2025:10:15:32 +0000] "GET /index.html HTTP/1.1" 500 532',
40+
41+
'::1 - - - "GET /index.html HTTP/1.1" 500 532',
42+
43+
'::1 - - [12/Jan/2025:10:15:32 +0000] "GET /index.html HTTP/1.1" - 120'
4044
]
4145

4246
# ------------------
@@ -47,6 +51,7 @@
4751
def parseur_arguments_cli():
4852
"""
4953
Fixture pour initialiser le parseur d'arguments CLI.
54+
5055
Returns:
5156
ParseurArgumentsCLI: Une instance de la classe :class:`ParseurArgumentsCLI`.
5257
"""
@@ -58,18 +63,22 @@ def log_apache(tmp_path):
5863
Fixture pour créer et récupérer un fichier de log Apache temporaire.
5964
Elle permet de générer un fichier de log Apache temporaire contenant
6065
soit des lignes valides, soit des lignes invalides selon le paramètre fourni.
66+
6167
Args:
6268
tmp_path (Path): Chemin temporaire fourni par pytest.
69+
6370
Returns:
6471
Callable[[bool], Path]: Une fonction qui crée et retourne le chemin
6572
du fichier de log temporaire.
6673
"""
6774
def _creer_log(valide):
6875
"""
6976
Crée un fichier de log Apache temporaire.
77+
7078
Args:
7179
valide (bool): Si ``True``, le fichier contient des lignes de log valides.
7280
Sinon, il contient des lignes invalides.
81+
7382
Returns:
7483
Path: Le chemin du fichier de log temporaire créé.
7584
"""
@@ -87,12 +96,14 @@ def _creer_log(valide):
8796
def parseur_log_apache(log_apache, request):
8897
"""
8998
Fixture pour initialiser un parseur de fichier de log Apache.
99+
90100
Args:
91101
log_apache: La fixture pour initialiser un fichier temporaire.
92102
request: Paramètre de la fonction. Si il est égale à ``False``, cette fixture
93103
retourne un parseur de log Apache qui analyse un fichier avec un format
94104
invalide. Sinon, retourne un parseur de log Apache qui analyse un fichier
95105
avec un format valide.
106+
96107
Returns:
97108
ParseurLogApache: Une instance de la classe :class:`ParseurLogApache`.
98109
"""
@@ -106,17 +117,43 @@ def fichier_log_apache(parseur_log_apache):
106117
Fixture pour initialiser une représentation d'un fichier de log Apache.
107118
Cette représentation comprend par défaut les entrées parsées de la liste
108119
``lignes_valides``.
120+
121+
Args:
122+
parseur_arguments_cli (ParseurArgumentsCLI): Fixture pour l'instance
123+
de la classe :class:`ParseurLogApache`.
124+
109125
Returns:
110126
FichierLogApache: Une instance de la classe :class:`FichierLogApache`.
111127
"""
112128
return parseur_log_apache.parse_fichier()
113129

130+
@pytest.fixture()
131+
def entree_log_apache(fichier_log_apache):
132+
"""
133+
Fixture pour initialiser une représentation d'une entrée d'un fichier de log Apache.
134+
Cette représentation comprend par défaut les informations de la première ligne de
135+
``lignes_valides``.
136+
137+
Args:
138+
fichier_log_apache (FichierLogApache): Fixture pour l'instance
139+
de la classe :class:`FichierLogApache`.
140+
141+
Returns:
142+
EntreeLogApache: Une instance de la classe :class:`EntreeLogApache`.
143+
"""
144+
return fichier_log_apache.entrees[0]
145+
114146
@pytest.fixture()
115147
def analyseur_log_apache(fichier_log_apache):
116148
"""
117149
Fixture pour initialiser un analyseur statistique de fichier de log Apache.
118150
Le fichier qu'analyse cet analyseur comprend par défaut les entrées parsées de la liste
119151
``lignes_valides``.
152+
153+
Args:
154+
fichier_log_apache (FichierLogApache): Fixture pour l'instance
155+
de la classe :class:`FichierLogApache`.
156+
120157
Returns:
121158
AnalyseurLogApache: Une instance de la classe :class:`AnalyseurLogApache`.
122159
"""

tests/test_analyseur_log_apache.py

Lines changed: 76 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66
from parse.fichier_log_apache import FichierLogApache
77
from analyse.analyseur_log_apache import AnalyseurLogApache
88

9+
910
# Tests unitaires
1011

1112
@pytest.mark.parametrize("fichier, nombre_par_top", [
1213
(False, 3),
1314
(FichierLogApache("test.log"), False)
1415
])
15-
def test_analyseur_exception_type_invalide(fichier, nombre_par_top):
16+
def test_analyseur_log_exception_type_invalide(fichier, nombre_par_top):
1617
"""
1718
Vérifie que la classe AnalyseurLogApache lève une :class:`TypeError` si les types des
1819
paramètres du constructeur sont invalides.
@@ -21,20 +22,26 @@ def test_analyseur_exception_type_invalide(fichier, nombre_par_top):
2122
- Type incorrect pour le paramètre ``fichier``.
2223
- Type incorrect pour le paramètre ``nombre_par_top``.
2324
25+
Asserts:
26+
- Une exception :class:`TypeError` est levée.
27+
2428
Args:
2529
fichier (any): Représentation du fichier log.
2630
nombre_par_top (any): Nombre maximum d'éléments dans le top classement.
2731
"""
2832
with pytest.raises(TypeError):
2933
analyseur = AnalyseurLogApache(fichier, nombre_par_top)
3034

31-
def test_analyseur_exception_valeur_nombre_par_top_invalide():
35+
def test_analyseur_log_exception_valeur_nombre_par_top_invalide():
3236
"""
33-
Vérifie que la classe AnalyseurLogApache lève une :class:`ValueError` si le
37+
Vérifie que la classe AnalyseurLogApache lève une exception si le
3438
paramètre ``nombre_par_top`` du constructeur est un entier négatif.
3539
3640
Scénarios testés:
3741
- Nombre négatif pour ``nombre_par_top``.
42+
43+
Asserts:
44+
- Une exception :class:`ValueError` est levée.
3845
"""
3946
with pytest.raises(ValueError):
4047
analyseur = AnalyseurLogApache(FichierLogApache("test.log"), -4)
@@ -49,12 +56,15 @@ def test_analyseur_exception_repartition_elements_type_invalide(analyseur_log_ap
4956
nom_element,
5057
mode_top_classement):
5158
"""
52-
Vérifie que _get_repartition_elements lève une :class:`TypeError` si les types sont invalides.
59+
Vérifie que _get_repartition_elements lève une exception si les types sont invalides.
5360
5461
Scénarios testés:
55-
- ``liste_elements`` n'est pas une ``list``.
56-
- ``nom_element`` n'est pas un ``str``.
57-
- ``mode_top_classement`` n'est pas un ``bool``.
62+
- Type incorrect pour le paramètre ``liste_elements``.
63+
- Type incorrect pour le paramètre ``nom_element``.
64+
- Type incorrect pour le paramètre ``mode_top_classement``.
65+
66+
Asserts:
67+
- Une exception :class:`TypeError` est levée.
5868
5969
Args:
6070
analyseur_log_apache (AnalyseurLogApache): Fixture pour l'instance
@@ -201,4 +211,62 @@ def test_analyseur_repartition_code_statut_htpp_valide(analyseur_log_apache):
201211
assert repartition[0]["taux"] == 80.0
202212
assert repartition[1]["code"] == 200
203213
assert repartition[1]["total"] == 1
204-
assert repartition[1]["taux"] == 20.0
214+
assert repartition[1]["taux"] == 20.0
215+
216+
@pytest.mark.parametrize("nombre_entrees", [
217+
(0), (3), (100)
218+
])
219+
def test_analyseur_get_total_entrees_valide(analyseur_log_apache,
220+
fichier_log_apache,
221+
entree_log_apache,
222+
nombre_entrees):
223+
"""
224+
Vérifie que ``get_total_entrees`` retourne le nombre correcte d'entrées dans le fichier.
225+
226+
Scénarios testés:
227+
- Vérification avec des fichiers avec des nombre d'entrées différents.
228+
229+
Asserts:
230+
- La méthode renvoie le nombre d'éléments dans la liste.
231+
232+
Args:
233+
analyseur_log_apache (AnalyseurLogApache): Fixture pour l'instance
234+
de la classe :class:`AnalyseurLogApache`.
235+
fichier_log_apache (FichierLogApache): Fixture pour l'instance
236+
de la classe :class:`FichierLogApache`.
237+
entree_log_apache (EntreeLogApache): Fixture pour l'instance
238+
de la classe :class:`EntreeLogApache`.
239+
nombre_entrees (int): Le nombre total d'entrées dans le fichier.
240+
"""
241+
fichier_log_apache.entrees = [entree_log_apache] * nombre_entrees
242+
assert analyseur_log_apache.get_total_entrees() == nombre_entrees
243+
244+
def test_analyseur_get_analyse_complete_valide(analyseur_log_apache):
245+
"""
246+
Vérifie que ``get_analyse_complete`` retourne un rapport de l'analyse correct
247+
qui se base sur le retour des autres méthodes.
248+
249+
Scénarios testés:
250+
- Vérification du rapport de l'analyse.
251+
252+
Asserts:
253+
- Les éléments du rapport se basent sur les mêmes valeurs que les autres méthodes.
254+
255+
Args:
256+
analyseur_log_apache (AnalyseurLogApache): Fixture pour l'instance
257+
de la classe :class:`AnalyseurLogApache`.
258+
fichier_log_apache (FichierLogApache): Fixture pour l'instance
259+
de la classe :class:`FichierLogApache`.
260+
entree_log_apache (EntreeLogApache): Fixture pour l'instance
261+
de la classe :class:`EntreeLogApache`.
262+
nombre_entrees (int): Le nombre total d'entrées dans le fichier.
263+
"""
264+
analyse = analyseur_log_apache.get_analyse_complete()
265+
assert analyse["chemin"] == analyseur_log_apache.fichier.chemin
266+
statistiques = analyse["statistiques"]
267+
assert statistiques["total_entrees"] == analyseur_log_apache.get_total_entrees()
268+
statistiques_requetes = statistiques["requetes"]
269+
assert statistiques_requetes["top_urls"] == analyseur_log_apache.get_top_urls()
270+
assert (statistiques_requetes["repartition_code_statut_http"]
271+
== analyseur_log_apache.get_total_par_code_statut_http())
272+

0 commit comments

Comments
 (0)