Skip to content

Tests de l'application

Patson edited this page May 16, 2022 · 46 revisions

Stratégie de testing

Méthodologie globale et Technologie:

Test intégration

Le premier type de test mis en place pour notre application est le test d'intégration visant à tester chacune des routes déclencheur de requête de notre application. Pour ce type de test on a utilisé 02 outils :

  • Mocha/Chai qui nous à permet de rédiger directement des tests depuis notre application afin de l'automatiser via l'outil Github Action. Mocha/Chai sont des librairies très célèbre utilisé depuis longtemps pour les tests d'application nodejs leurs performance vient du leur facilité de compréhension et la simplicité dans la rédaction des tests les plus complexe. Une de leur puissance est l'automatisation. Les test rédigés avec ces librairies s'adaptent parfaitement au outil qui permettent d'automatiser le testing d'application.

  • Postman Outil très puissant et efficace qui nous permettait de tester nos différentes routes au cours du developpement de l'application. Les tests sur postman sont facile à mettre en place mais la complexité vient lors de l'automatisation du processus. Il est complexe de relier les tests effectués sur postman au outil d'automatisation en ligne.

Un troisième outil qui a aussi été utilisé est thunder client qui utilise la même stratégie de testing de postman mais reste intégré au logiciel vscode.

Tests end to end

Le second type de test implémenté est le test end to end visant à tester chacun de nos composants côté frontend. La bibliothèque utilisée pour la rédaction de ces tests est [react-testing-library]

Etant donnée que notre frontend est écrit en react, l'outil est directement intégré et nous permet de faire des tests qui ne peuvent pas ce faire manuellement. C'est l'outil le mieux adapté pour tester nos composants réact bien que la rédaction des tests avec celui reste assez complexe car l'application est lié avec la bibliothèque rédux.

Les tests sont effectués directement dans les dossiers où se trouvent nos composants et sont encore en cours de developpement.

Présentation des test

Présentation Test d'intégration

Nombre de test

Nous disposons pour l'instant de 22 tests d'intégration pour les différentes routes en backend : /api/users, /api/orders , /api/cars. Les tests sont répertoriés dans le dossier test qui se trouve dans le dossier backend.

Les tests s'effectue de la façon suivante:

  1. Nous rédigeons tout d'abord les tests a l'aide des modules Mochajs, chai et supertest.

Cette article de Sebastián Pérez Etchandy nous a servi de base pour la mise en place de ceux-ci.

  1. Dans un fichier .yml nous créons un base de données de test à chaque fois que l'on lance la commande npm run test,

Grâce au seeders on insère des données temporaires à l'intérieur de celle-ci. ces données seront utilisés pour effectuer certains tests qui nécessitent des données au préalale.

Choix des valeurs d'input

Comme repris tout en haut la base de données de test est popularisé bien avant le lancement donc:

  1. Nous vérifions les requêtes GET sur base des données que contient déjà la base de données de test mais aussi des données que l'on insère lors des tests

Lien vers le code dest tests en question

  • Exemple : Pour une requête sur la route GET /api/cars

On va s'assurer que notre reponse contient bien l'objet shouldGetCars qui est déjà au préalable dans le db de test

const shouldGetCars = {
	id: 3,
	name: "okooo",
	price: 500,
	brand_id: 2,
	color: "okooo",
	doors: 5,
	boot_size: 140,
	type: "okooo",
	energy: "okooo",
	is_automatic: true,
	air_conditioning: true,
	is_available: true,
	passengers: 5,
	description: "okooo",
	number_plate: null,
	year: null,
	mileage: null,
	cars_brands: { id: 2, brand: "mercedes", model: "1996" },
};

describe("GET /api/cars/images", async () => {
	it("Should return all cars images", async () => {
		const response = await request(server).get(`/api/cars/images`);
		expect(response.status).to.equal(200);
		expect(response.body).to.deep.include(shouldGetCarsImages);
	});
});
  1. pour une requête GET qui nécessite des paramètres on s'assure que les paramètres qu'on passe correspond bien à ce que doit recevoir le controlleur qui effectue la requête dans le code.

Lien vers le code des tests en question

  • Exemple : Un requête de filtre vers la route /api/orders ou la on à choisis des valeurs d'input en fonction de ce que contient déjà la base de données
describe("GET /api/orders", async () => {
       it("Should return orders filter on date", async () => {
		//Try to insert parameters
		const shouldFilterOrders = {
			startDate: "2022-04-30",
			startTime: "12:00",
			endDate: "2022-05-10",
			endTime: "08:00",
		};
		const response = await request(server)
			.get("/api/orders/")
			.query(shouldFilterOrders);
		expect(response.status).to.equal(200);
		expect(response.body.orders).to.deep.include(shouldGetOrders1);
	});
});
  1. Nous vérifions des requêtes POST en envoyant dans le corps de la requête les éléments dont chaque controlleurs à besoin soit pour bien effectué une insertion soit pour retourner une erreur bien précise

Lien vers le code des tests en question

  • Exemple : Une requête pour insérer un administrateur dans la base de données sur la route /api/admins cette route nécessite non seulement la présence d'un admin dans la db de test mais aussi que l'utilisateur en question soit dans la table des utilisateurs
describe("POST /api/admins", async () => {
	it("Should add admin", async () => {
		const response = await request(server)
			.post("/api/admins")
			.send({
				emailAdmin: "test.toto@gmail.com",
				emailUser: "test.titi@gmail.com",
				passwordAdmin: "Toto1234",
			})
			.set(
				"Authorization",
				`Bearer ${jwt.sign(
					{ user: "test.toto@gmail.com" },
					"SHORT_HASH_PHRASE",
					{
						expiresIn: "24h",
					}
				)}`
			);
		expect(response.status).to.equal(200);
		expect(response.body).to.deep.include({
			result: "Le nouvel administrateur à bien été enregistré",
		});
	});
});

les tableaux input/output utilisés pour construire les tests

  1. GET /api/cars
Input data Output status Output data
startDate: "2022-04-30",
startTime: "12:00",
endDate: "2022-05-10",
endTime: "08:00"
200 {
id: 1,
car_id: 1,
user_id: 1,
date_order: "2022-04-30T12:00:00.000Z",
departure_date: "2022-05-05T13:00:00.000Z",
return_date: "2022-05-10T08:00:00.000Z",
total_price: 800
};
startDate: "",
startTime: "12:00",
endDate: "2022-05-10",
endTime: "08:00"
500 { message: "Internal server error", }

Couverture des tests

Le taux de couverture des tests peut être visualisé sur le schema ci dessous:

coverage intégration

On peut apercevoir que la majorité des fonction qui tourne en backend on bien été testé

Présentation Test end to end

Test end to end

Nombre de test

Nous disposons pour l'instant de 4 tests end to end visant à éprouver les différentes parties de l'interface utilisateur. Les tests sont répertoriés dans le même dossier où se trouve dans le composant à tester suivie de .test à la fin exemple.

Pour ce qui est de la technologie on à choisie d'uitliser React testing library car vu qu'on utilise la bibliothèque react comme technologie en frontend, il est le plus adapté pour tester le plus efficacement nos composants réact en fournissant des tests internes pour certaines parties de l'application qui ne peuvent pas être testé manuellement.

Choix des valeur d'input

Pour ce qui est des choix des valeurs en input on essaie de simuler l'envoie de données qu'on reçoit normalement depuis le backend afin de savoir si la construction des composants s'éffectue correctement.

Pour celà on harcode les valeurs nécessaires à la construction des composants dès le départ. Par exemple pour la construction d'un composant voiture on aura besoin des informations d'une voiture précise. En temps normale ces valeurs nous sont fournie par la base de données mais lors de l'éxecution des tests, comme on a pas accès à la db on fournira les informations d'une voiture afin de construire directement le composant

Exemple :

const state = {cars: [
			{
				air_conditioning: true,
				boot_size: 143,
				brand_id: 2,
				cars_brands: { brand: "Audi", id: 2, model: "RS 3" },
				color: "Gris Nardo",
				description: "hello",
				doors: 5,
				energy: "Essence",
				id: 2,
				is_automatic: true,
				is_available: true,
				mileage: null,
				name: "RS3_Gris-Nardo",
				number_plate: null,
				passengers: 5,
				price: 100,
				type: "Sportive",
				year: null,
			},
		],}
const rootReducer = combineReducers({
	carState: carReducer,
	userState: userReducer,
});
const store = configureStore({ reducer: rootReducer, preloadedState }); // Celui qui va fournir les valeurs dont les composants react  ont besoin

Et pour tester le composant voiture, c'est lui qu'on passera en input suivi des valeurs qu'on à harcoder pour vérifier que le composant voiture à bien été construit avec les informations de la voiture passé au préalable.

Tableaux input/oput utilisés pour la construction des tests

Dans ces tests on vérifie bien si la construction d'un composant réact s'est bien effectué en passant un composant en input et en vérifiant si quelques éléments se trouve bien à l'intérieur ce composant.

  1. COMPOSANT cars

Dans ce composant on vérifie juste si les valeurs qui se trouve dans le composant voiture est bel et bien à l'intérieur

Exemple

test("Get Cars", async () => {
    render(
		<Router location={history.location} navigator={history}>
			<Cars />
		</Router>,
		{ carProperty }
	);
    expect(await screen.findByText("Voitures disponibles")).toBeTruthy();
    expect(await screen.findAllByText("Type")).toBeTruthy();
    expect(await screen.findAllByText("Places")).toBeTruthy();
Input data Expected Data Output data
<Cars /> "Voitures disponible", "Voiture disponible"
<Cars /> "/cars" "/cars"
<Cars /> "Type", "Type"
<AddCars /> "Ajouter une voiture" "Ajouter une voiture"
<AddCars /> "Nom" "Nom"

Couverture des tests

Le taux de couverture des tests peut être visualisé via le schema ci dessous:

La majeur partie des fichiers nécessitant des tests ont été correctement testé comme les fichiers cars.js et order.js qui contiennent toute la logique de l'application à l'arrivé de l'utilisateur.

coverage front

Lien vers le code des tests en question

Vous pouvez retrouver les quelques tests end to end en cliquant sur ce lien

Tests unitaires

Nombre de tests

Quelques test unitaires ont bien été implémenté. ces tests visent à assurer le bon fonctionnement de l'application rédux en frontend

Vous pouvez retrouver ces tests via ce lien

Les réducteurs sont ceux là qui vont permettre de gérer les données qu'on recoit depuis le backend en frontend donc il est nécessaire de s'assurer qu'ils fonctionnent correctement afin de ne pas avoir des incohérences dans les données reçues depuis le backend.

Pour le taux de couverture de ces tests vous pouvez vous apercevoir les fichiers carReducer et userReducer qui ont contiennent les fonctions testées

coverage reducer

Bilan général des tests

[Analyse de la qualité de la validation du projet]

Tests individuels

Michaël - US02 Ajouter des voitures

[Bilan personnel de la réalisation des tests de l'US implémentée. ]

Pour l'API et ses routes, nous avons utilisé Postman pour les tester. En testant les différentes routes, j'essaye de couvrir le plus de cas possible. La route http://localhost:3001/api/cars présente un cas plus particulier car il faut aussi vérifier les données quelle renvoie.

[Lien vers le code de test produit par l'étudiant]

Tests effectués

Test de la route POST http://localhost:3001/api/cars:

Lien du test sur Postman

Test de la route POST http://localhost:3001/api/car/1/images:

Lien du test sur Postman

[Tableau de valeurs input/output utilisés pour chaque test]

[Tableau de valeurs input/output utilisés pour chaque test]

Input data Output status Output data
{ "brand": "Renault", "model": "Clio", "year": "2015", "price": "12000", "description": "Coupe", "color": "Blanc", "seats": "5", "doors": "5", "transmission": "Manuelle", "fuel": "Essence", "mileage": "100", "available": "true", "location": "Paris", "images": [ "https://www.renault.fr/medias/sys_master/root/h1b/h1c/h00/1089724681849/renault-clio-2015-blanc-1-1.jpg", "https://www.renault.fr/medias/sys_master/root/h1b/h1c/h00/1089724681849/renault-clio-2015-blanc-1-1.jpg" ] } 201 { "id": 20 }

Rachid US-01 Afficher les voitures

[Bilan personnel de la réalisation des tests de l'US implémentée. ] [Lien vers le code de test produit par l'étudiant]

Tests effectués

Test de la route GET http://localhost:3001/api/cars:

Lien du test sur Postman

[Tableau de valeurs input/output utilisés pour chaque test]

Input data Output status Output data
/ 200 [ { "id": 2, "name": "RS3_Gris-Nardo", "price": 100, "brand_id": 2, "color": "Gris Nardo", "doors": 5, "boot_size": 143, "type": "Sportive", "energy": "Essence", "is_automatic": true, "air_conditioning": true, "is_available": true, "passengers": 5, "description": "hello", "number_plate": null, "year": null, "mileage": null, "cars_brands": { "id": 2, "brand": "Audi", "model": "RS 3" } }, { "id": 1, "name": "test50", "price": 50, "brand_id": 7, "color": "test50", "doors": 5, "boot_size": 50, "type": "test50", "energy": "test50", "is_automatic": true, "air_conditioning": true, "is_available": true, "passengers": 5, "description": "testsss50", "number_plate": null, "year": null, "mileage": null, "cars_brands": { "id": 7, "brand": "test50", "model": "test50" } } ]

Aymar US06 Choisir la marque de la voiture

[Bilan personnel de la réalisation des tests de l'US implémentée. ] [Lien vers le code de test produit par l'étudiant]

Tests effectués

[Tableau de valeurs input/output utilisés pour chaque test]

Patson US05 Choisir la plage horaire de location

[Bilan personnel de la réalisation des tests de l'US implémentée. ] [Lien vers le code de test produit par l'étudiant]

Tests effectués

Test de la route GET http://localhost:3001/api/orders avec des query.

Lien pour les test avec mocha et chai Lien pour les tests postman

Bilan des Tests

Pour ce qui est du bilan, des tests ont tout d'abord été effectué sur postman puis à l'aide de la bibliothèque mocha et chai afin d'automatiser le processus de tests avec l'outil github action. L'ensemble des tests effectués sur la route /api/orders ont été rédigés afin d'éprouver les différents valeurs de retour de cette route. Bien évidemment afin de sécuriser au mieux les requêtes des tests supplémentaires peuvent encore être implémentés:

Les différents cas de figure qui ont été testé sont listé ci-dessous :

  • Cas où le filtre est appliqué correctement: 2 cas de filtre ont été appliqué et tous les deux sont passé.

Exemple :

it("Should return orders filter on date", async () => {
		//Try to insert parameters
		const shouldFilterOrders = {
			startDate: "2022-04-30",
			startTime: "12:00",
			endDate: "2022-05-10",
			endTime: "08:00",
		};
		const response = await request(server)
			.get("/api/orders/")
			.query(shouldFilterOrders);
		expect(response.status).to.equal(200);
		expect(response.body.orders).to.deep.include(shouldGetOrders1);
	});
  • Cas où le filtre est mal appliqué du a un mauvais intervalle : 1 cas de filtre a été appliqué et l'erreur correpondante est retourné. exemple :
it("Should return 404 due to wrong car", async () => {
		const response = await request(server)
			.post("/api/orders")
			.send(shouldNotAddOrders);
		expect(response.status).to.equal(404);
		expect(response.body).to.deep.include({
			message: "Car not found",
		});
	});

En tout on a 3 tests pour la route /api/orders avec des paramètres de filtre et les 3 sont passé correctement avec un taux de couverture sur la route pour cette route de 83%.

Valeur d'input et résultat attendu Afin de vérifier la récupération des voitures sur base de la plage horaire, Les tests pour cette partie de l'application sont divisé en 3 parties :

Les tests destinés à passer : Ceux ci recoivent des valeurs qui sont cohérentes et qui existent dans la base de données et en sortie on doit recevoir non seulement un réponse 200 mais aussi l'ensemble des voitures filtrées sur les valeurs d'input

Input data Output status Output data
startDate: "2022-05-04",
startTime: "12:00",
endDate: "2022-05-15",
endTime: "08:00"
200 {
id: 1,
car_id: 1,
user_id: 1,
date_order: "2022-04-30T12:00:00.000Z"
departure_date: "2022-05-05T13:00:00.000Z",
return_date: "2022-05-10T08:00:00.000Z",
total_price: 800,
};
{
id: 2,
car_id: 2,
user_id: 1,
date_order: "2022-0-31T12:00:00.000Z"
departure_date: "2022-05-04T13:00:00.000Z",
return_date: "2022-05-15T08:00:00.000Z",
total_price: 7600,
};
startDate: "2022-04-30",
startTime: "12:00",
endDate: "2022-05-10",
endTime: "08:00"
200 {
id: 1,
car_id: 1,
user_id: 1,
date_order: "2022-04-30T12:00:00.000Z"
departure_date: "2022-05-05T13:00:00.000Z",
return_date: "2022-05-10T08:00:00.000Z",
total_price: 800,
};
startDate: "",
startTime: "12:00",
endDate: "2022-05-10",
endTime: "08:00"
500 { message: "Internal server error", }

Pour ce qui est des fichiers qui ont été testé on a les fichiers carsSlot.js et car.js coverage cars

on peut bien apercevoir que le taux de couverture pour ces fichiers montre qu'ils ont été correctement testé.

Clone this wiki locally