Skip to article frontmatterSkip to article content

TP6 : Tests unitaires

IUT d'Orsay, Université Paris-Saclay

Le but de ce TP est de comprendre les points suivants :

Rappel dépôt GitLab

Exercice 1 : FizzBuzz

  1. Dans TP6/, créez le répertoire fizz-buzz/ avec la structure suivante :
fizz-buzz/
    source/
        fizz-buzz.cpp
        fizz-buzz.h
        main.cpp
        makefile
    tests/
        fizz-buzz-test.cpp
        fizz-buzz-test.h
        main.cpp
        makefile
    makefile
  1. Recopiez le code suivant pour le makefile à la racine de fizz-buzz/.
fizz-buzz/makefile
all: build source

build:
	mkdir -p build/dependencies/ build/objects build/binaries

source:
	make -C source

run:
	make -C source run

test: source
	make -C tests
	make -C tests run

clean:
	rm -rf build

.PHONY: all build source run test clean
  1. Recopiez les codes suivants pour les fichiers de source/.
fizz-buzz.cpp
fizz-buzz.h
main.cpp
makefile
#include "fizz-buzz.h"
#include <string>
#include <stdexcept>

std::string FizzBuzz::fizzBuzz(int number) {
	std::string result = "";
	return result;
}
  1. Recopiez les codes suivants pour les fichiers de tests/.
fizz-buzz-test.cpp
fizz-buzz-test.h
main.cpp
makefile
#include "../source/fizz-buzz.h"
#include "fizz-buzz-test.h"
#include <iostream>
#include <cassert>
#include <stdexcept>

void FizzBuzzTest::runTests() {
    fizzBuzz_NegativeInput_ThrowsInvalidArgument();
	fizzBuzz_ZeroInput_ThrowsInvalidArgument();
    fizzBuzz_OddInputNonDivisibleBy7DoesNotContain2Or7_ReturnsTheSameNumber();
    fizzBuzz_EvenInputNonDivisibleBy7DoesNotContain2Or7_ReturnsFizz();
    fizzBuzz_EvenInputNonDivisibleBy7Contains2ButNot7_ReturnsFizzFizz();
    fizzBuzz_OddInputDivisibleBy7DoesNotContain2Or7_ReturnsBuzz();
    fizzBuzz_OddInputDivisibleBy7Contains7ButNot2_ReturnsBuzzBuzz();
    fizzBuzz_EvenInputDivisibleBy7DoesNotContain2Or7_ReturnsFizzBuzz();
    fizzBuzz_EvenInputNonDivisibleBy7Contains7ButNot2_ReturnsFizzBuzz();
    fizzBuzz_OddInputDivisibleBy7Contains2ButNot7_ReturnsFizzBuzz();
    fizzBuzz_OddInputNonDivisibleBy7Contains2And7_ReturnsFizzBuzz();
    fizzBuzz_OddInputDivisibleBy7Contains2And7_ReturnsFizzBuzzBuzz();
    fizzBuzz_EvenInputNonDivisibleBy7Contains2And7_ReturnsFizzFizzBuzz();
    fizzBuzz_EvenInputDivisibleBy7Contains2ButNot7_ReturnsFizzFizzBuzz();
    fizzBuzz_EvenInputDivisibleBy7Contains7ButNot2_ReturnsFizzBuzzBuzz();
    fizzBuzz_EvenInputDivisibleBy7Contains2And7_ReturnsFizzFizzBuzzBuzz();
    std::cout << "All tests passed\n";
}

void FizzBuzzTest::fizzBuzz_NegativeInput_ThrowsInvalidArgument() {
	try{
		FizzBuzz::fizzBuzz(-728);
		assert(false);
	} catch (const std::invalid_argument& error) {
		std::cout << "fizzBuzz_NegativeInput_ThrowsInvalidArgument passed\n";
	} catch (...){
		assert(false);
	}
}

void FizzBuzzTest::fizzBuzz_ZeroInput_ThrowsInvalidArgument() {
	try{
		FizzBuzz::fizzBuzz(0);
		assert(false);
	} catch (const std::invalid_argument& error) {
		std::cout << "fizzBuzz_ZeroInput_ThrowsInvalidArgument passed\n";
	} catch (...){
		assert(false);
	}
}

void FizzBuzzTest::fizzBuzz_OddInputNonDivisibleBy7DoesNotContain2Or7_ReturnsTheSameNumber() {
    assert(FizzBuzz::fizzBuzz(1) == "1");
	assert(FizzBuzz::fizzBuzz(3) == "3");
	assert(FizzBuzz::fizzBuzz(5) == "5");
	assert(FizzBuzz::fizzBuzz(11) == "11");
	assert(FizzBuzz::fizzBuzz(13) == "13");
	assert(FizzBuzz::fizzBuzz(19) == "19");
	assert(FizzBuzz::fizzBuzz(31) == "31");
	assert(FizzBuzz::fizzBuzz(41) == "41");
	assert(FizzBuzz::fizzBuzz(43) == "43");
	assert(FizzBuzz::fizzBuzz(53) == "53");
	assert(FizzBuzz::fizzBuzz(59) == "59");
    std::cout << "fizzBuzz_OddInputNonDivisibleBy7DoesNotContain2Or7_ReturnsTheSameNumber passed\n";
}

void FizzBuzzTest::fizzBuzz_EvenInputNonDivisibleBy7DoesNotContain2Or7_ReturnsFizz() {
	assert(FizzBuzz::fizzBuzz(4) == "Fizz");
	assert(FizzBuzz::fizzBuzz(6) == "Fizz");
	assert(FizzBuzz::fizzBuzz(8) == "Fizz");
	assert(FizzBuzz::fizzBuzz(10) == "Fizz");
	assert(FizzBuzz::fizzBuzz(16) == "Fizz");
	assert(FizzBuzz::fizzBuzz(18) == "Fizz");
	assert(FizzBuzz::fizzBuzz(40) == "Fizz");
	assert(FizzBuzz::fizzBuzz(44) == "Fizz");
	assert(FizzBuzz::fizzBuzz(46) == "Fizz");
	assert(FizzBuzz::fizzBuzz(48) == "Fizz");
    std::cout << "fizzBuzz_EvenInputNonDivisibleBy7DoesNotContain2Or7_ReturnsFizz passed\n";
}

void FizzBuzzTest::fizzBuzz_EvenInputNonDivisibleBy7Contains2ButNot7_ReturnsFizzFizz() {
	assert(FizzBuzz::fizzBuzz(2) == "FizzFizz");
	assert(FizzBuzz::fizzBuzz(12) == "FizzFizz");
	assert(FizzBuzz::fizzBuzz(20) == "FizzFizz");
	assert(FizzBuzz::fizzBuzz(24) == "FizzFizz");
	assert(FizzBuzz::fizzBuzz(26) == "FizzFizz");
	assert(FizzBuzz::fizzBuzz(32) == "FizzFizz");
	assert(FizzBuzz::fizzBuzz(62) == "FizzFizz");
	assert(FizzBuzz::fizzBuzz(82) == "FizzFizz");	
    std::cout << "fizzBuzz_EvenInputNonDivisibleBy7Contains2ButNot7_ReturnsFizzFizz passed\n";
}

void FizzBuzzTest::fizzBuzz_OddInputDivisibleBy7DoesNotContain2Or7_ReturnsBuzz() {
    assert(FizzBuzz::fizzBuzz(35) == "Buzz");
	assert(FizzBuzz::fizzBuzz(49) == "Buzz");
	assert(FizzBuzz::fizzBuzz(63) == "Buzz");
	assert(FizzBuzz::fizzBuzz(91) == "Buzz");
	assert(FizzBuzz::fizzBuzz(105) == "Buzz");
	assert(FizzBuzz::fizzBuzz(119) == "Buzz");
    std::cout << "fizzBuzz_OddInputDivisibleBy7DoesNotContain2Or7_ReturnsBuzz passed\n";
}

void FizzBuzzTest::fizzBuzz_OddInputDivisibleBy7Contains7ButNot2_ReturnsBuzzBuzz() {
	assert(FizzBuzz::fizzBuzz(7) == "BuzzBuzz");
	assert(FizzBuzz::fizzBuzz(77) == "BuzzBuzz");
	assert(FizzBuzz::fizzBuzz(147) == "BuzzBuzz");
	assert(FizzBuzz::fizzBuzz(175) == "BuzzBuzz");	
    std::cout << "fizzBuzz_OddInputDivisibleBy7Contains7ButNot2_ReturnsBuzzBuzz passed\n";
}

void FizzBuzzTest::fizzBuzz_EvenInputDivisibleBy7DoesNotContain2Or7_ReturnsFizzBuzz() {
	assert(FizzBuzz::fizzBuzz(14) == "FizzBuzz");
	assert(FizzBuzz::fizzBuzz(56) == "FizzBuzz");
	assert(FizzBuzz::fizzBuzz(84) == "FizzBuzz");
	assert(FizzBuzz::fizzBuzz(98) == "FizzBuzz");
	assert(FizzBuzz::fizzBuzz(140) == "FizzBuzz");
	assert(FizzBuzz::fizzBuzz(154) == "FizzBuzz");	
    std::cout << "fizzBuzz_EvenInputDivisibleBy7DoesNotContain2Or7_ReturnsFizzBuzz passed\n";
}

void FizzBuzzTest::fizzBuzz_EvenInputNonDivisibleBy7Contains7ButNot2_ReturnsFizzBuzz() {
	assert(FizzBuzz::fizzBuzz(74) == "FizzBuzz");
	assert(FizzBuzz::fizzBuzz(76) == "FizzBuzz");
	assert(FizzBuzz::fizzBuzz(78) == "FizzBuzz");
	assert(FizzBuzz::fizzBuzz(170) == "FizzBuzz");
	assert(FizzBuzz::fizzBuzz(174) == "FizzBuzz");
	assert(FizzBuzz::fizzBuzz(176) == "FizzBuzz");
    std::cout << "fizzBuzz_EvenInputNonDivisibleBy7Contains7ButNot2_ReturnsFizzBuzz passed\n";
}

void FizzBuzzTest::fizzBuzz_OddInputDivisibleBy7Contains2ButNot7_ReturnsFizzBuzz() {
	assert(FizzBuzz::fizzBuzz(21) == "FizzBuzz");
	assert(FizzBuzz::fizzBuzz(203) == "FizzBuzz");
	assert(FizzBuzz::fizzBuzz(259) == "FizzBuzz");
	assert(FizzBuzz::fizzBuzz(329) == "FizzBuzz");
    std::cout << "fizzBuzz_OddInputDivisibleBy7Contains2ButNot7_ReturnsFizzBuzz passed\n";
}

void FizzBuzzTest::fizzBuzz_OddInputNonDivisibleBy7Contains2And7_ReturnsFizzBuzz() {
    assert(FizzBuzz::fizzBuzz(27) == "FizzBuzz");
	assert(FizzBuzz::fizzBuzz(127) == "FizzBuzz");
	assert(FizzBuzz::fizzBuzz(527) == "FizzBuzz");
	assert(FizzBuzz::fizzBuzz(927) == "FizzBuzz");
    std::cout << "fizzBuzz_OddInputNonDivisibleBy7Contains2And7_ReturnsFizzBuzz passed\n";
}

void FizzBuzzTest::fizzBuzz_OddInputDivisibleBy7Contains2And7_ReturnsFizzBuzzBuzz() {
	assert(FizzBuzz::fizzBuzz(217) == "FizzBuzzBuzz");
	assert(FizzBuzz::fizzBuzz(273) == "FizzBuzzBuzz");
	assert(FizzBuzz::fizzBuzz(427) == "FizzBuzzBuzz");
	assert(FizzBuzz::fizzBuzz(721) == "FizzBuzzBuzz");
    std::cout << "fizzBuzz_OddInputDivisibleBy7Contains2And7_ReturnsFizzBuzzBuzz passed\n";
}

void FizzBuzzTest::fizzBuzz_EvenInputNonDivisibleBy7Contains2And7_ReturnsFizzFizzBuzz() {
	assert(FizzBuzz::fizzBuzz(72) == "FizzFizzBuzz");
	assert(FizzBuzz::fizzBuzz(272) == "FizzFizzBuzz");
	assert(FizzBuzz::fizzBuzz(274) == "FizzFizzBuzz");
	assert(FizzBuzz::fizzBuzz(726) == "FizzFizzBuzz");
	assert(FizzBuzz::fizzBuzz(872) == "FizzFizzBuzz");
    std::cout << "fizzBuzz_EvenInputNonDivisibleBy7Contains2And7_ReturnsFizzFizzBuzz passed\n";
}

void FizzBuzzTest::fizzBuzz_EvenInputDivisibleBy7Contains2ButNot7_ReturnsFizzFizzBuzz() {
	assert(FizzBuzz::fizzBuzz(28) == "FizzFizzBuzz");
	assert(FizzBuzz::fizzBuzz(42)  == "FizzFizzBuzz");
	assert(FizzBuzz::fizzBuzz(112) == "FizzFizzBuzz");
	assert(FizzBuzz::fizzBuzz(126) == "FizzFizzBuzz");
	assert(FizzBuzz::fizzBuzz(182) == "FizzFizzBuzz");
    std::cout << "fizzBuzz_EvenInputDivisibleBy7Contains2ButNot7_ReturnsFizzFizzBuzz passed\n";
}

void FizzBuzzTest::fizzBuzz_EvenInputDivisibleBy7Contains7ButNot2_ReturnsFizzBuzzBuzz() {
    assert(FizzBuzz::fizzBuzz(70) == "FizzBuzzBuzz");
    assert(FizzBuzz::fizzBuzz(378) == "FizzBuzzBuzz");
    assert(FizzBuzz::fizzBuzz(476) == "FizzBuzzBuzz");
    std::cout << "fizzBuzz_EvenInputDivisibleBy7Contains7ButNot2_ReturnsFizzBuzzBuzz passed\n";
}

void FizzBuzzTest::fizzBuzz_EvenInputDivisibleBy7Contains2And7_ReturnsFizzFizzBuzzBuzz() {
    assert(FizzBuzz::fizzBuzz(728) == "FizzFizzBuzzBuzz");
	assert(FizzBuzz::fizzBuzz(2716) == "FizzFizzBuzzBuzz");
    std::cout << "fizzBuzz_EvenInputDivisibleBy7Contains2And7_ReturnsFizzFizzBuzzBuzz passed\n";
}

Dans ce premier exercice, il s’agit d’implémenter la fonction fizzBuzz de la classe FizzBuzz. Les tests sont fournis dans le fichier fizz-buzz-test.cpp.

Les commandes make qui vous sont fournies permettent de compiler le code et de lancer les tests. Quand vous vous placez dans le dossier fizz-buzz/, vous pouvez lancer les commandes suivantes :

  1. Lisez la documentation de la classe FizzBuzz et les tests.

  2. Implémentez fizzBuzz dans fizz-buzz.cpp de sorte que tous les tests passent.

Est-ce que votre code est propre ?

Exercice 2 : Sorting Hat

  1. Dans TP6/, créez le répertoire sorting-hat/.

Voici les codes pour la classe SortingHat et le main.cpp pour tester la classe avec des entrées dans le terminal.

main.cpp
sorting-hat.cpp
sorting-hat.h
#include "sorting-hat.h"
#include <iostream>

int main() {
    int mood;
    std::cout << "Is the sorting fair(0) or playful(1)? ";
    std::cin >> mood;
    SortingHat hat(static_cast<Mood>(mood));

    int student;
    std::cout << "What is the student's best quality: ambitious(0), brave(1), intelligent(2), or loyal(3)? ";
    std::cin >> student;

    std::cout << "The perfect fit for you is (Slytherin:0, Gryffindor:1, Ravenclaw:2, Hufflepuff:3): " << hat.assignHouse(static_cast<Student>(student)) << std::endl;
    return 0;
}

Nous cherchons à simuler le comportement du “Choixpeau magique” (Sorting Hat) du monde de Harry Potter. Hogwarts est l’école des sorciers. Elle est divisée en quatre maisons et le Choixpeau magique est un chapeau qui permet aux sorciers de trouver leur maison. Ce choix est normalement basé sur les quatre qualités principales recherchées chez un sorcier mais le choixpeau est aussi influencé par son humeur.

Le but de l’exercice est d’écrire des tests unitaires pour vérifier le comportement du choixpeau.

  1. Créez et structurez les répertoires et les fichiers de sorting-hat/ de la même manière que vous avez fait pour fizz-buzz/.
  1. Lisez la documentation de la classe SortingHat pour comprendre son fonctionnement.

  2. Écrivez des tests unitaires pour tester les deux méthodes getMood et assignHouse de la classe SortingHat.

  1. Implémentez getMood dans sorting-hat.cpp.

  2. Bonus: Implémentez assignHouse dans sorting-hat.cpp.

Retournez aux objectifs et cochez les points que vous avez maîtrisés. Reprenez les points que vous n’avez pas encore bien compris. Appelez votre encadrant si besoin.