Skip to article frontmatterSkip to article content

PS6 : Unit tests

IUT d'Orsay, Université Paris-Saclay

The objectives of this session is to understand the following points:

GitLab Repository Reminder

Exercise 1: FizzBuzz

  1. In PS6/, create the directory fizz-buzz/ with the following structure:
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. Copy the following code into the makefile at the root of 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. Copy the following code into the files in 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";
}

In this first exercise, the task is to implement the fizzBuzz function of the FizzBuzz class. The tests are provided in the fizz-buzz-test.cpp file.

The make commands provided allow you to compile the code and run the tests. When you are in the fizz-buzz/ folder, you can run the following commands:

  1. Read the documentation of the FizzBuzz class and the tests.

  2. Implement fizzBuzz in fizz-buzz.cpp so that all tests pass.

Is your code clean?

Exercise 2: Sorting Hat

  1. In PS6/, create the sorting-hat/ directory.

Here are the codes for the SortingHat class and the main.cpp to test the class with terminal inputs.

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;
}

We are trying to simulate the behavior of the “Sorting Hat” from the Harry Potter world. Hogwarts is a school for wizards. It is divided into four houses and the Sorting Hat is a hat that allows wizards to find their house. This choice is normally based on the four main qualities sought in a wizard, but the Sorting Hat is also influenced by its mood.

The goal of the exercise is to write unit tests to verify the behavior of the Sorting Hat.

  1. Create and structure the directories and files of sorting-hat/ in the same way as you did for fizz-buzz/.
  1. Read the documentation of the SortingHat class to understand how it works.

  2. Write unit tests to test the two methods getMood and assignHouse of the SortingHat class.

  1. Implement getMood in sorting-hat.cpp.

  2. Bonus: Implement assignHouse in sorting-hat.cpp.

Return to the objectives and check off the points you have mastered. Review the points you don’t yet understand. Call your instructor if needed.