TP8 : Passer des tests unitaires
Le but de ce TP est de comprendre les points suivants :
FizzBuzz¶
Créez le répertoire
TP8/avec la structure suivante :
TP8/
├── include/
│ └── fizz-buzz.h
├── source/
│ ├── fizz-buzz.cpp
│ └── main.cpp
├── tests/
│ ├── include/
│ │ └── fizz-buzz-test.h
│ └── source/
│ ├── fizz-buzz-test.cpp
│ └── main.cpp
└── makefileStructure du projet
Ici, il s’agit ici d’un petit exercice, donc la structure du projet peut sembler un peu complexe. L’objectif est de vous montrer une organisation typique de projet plus conséquent et de vous proposer une structure réutilisable pour des projets de plus grande taille.
Recopiez les codes suivants pour les différents fichiers.
EXECUTABLE = fizz-buzz
TEST_EXECUTABLE = fizz-buzz-tests
CXX = g++
CXXFLAGS = -std=c++17 -Iinclude
TEST_CXXFLAGS = -std=c++17 -Iinclude -Itests/include
SOURCES = $(wildcard source/*.cpp)
TEST_SOURCES = $(wildcard tests/source/*.cpp)
OBJECTS = $(patsubst source/%.cpp,build/objects/%.o,$(SOURCES))
TEST_OBJECTS = $(patsubst tests/source/%.cpp,build/tests/objects/%.o,$(TEST_SOURCES))
DEPENDENCIES = $(patsubst source/%.cpp,build/dependencies/%.d,$(SOURCES))
TEST_DEPENDENCIES = $(patsubst tests/source/%.cpp,build/tests/dependencies/%.d,$(TEST_SOURCES))
SRC_OBJECTS_NO_MAIN = $(filter-out build/objects/main.o,$(OBJECTS))
all: build/binaries/$(EXECUTABLE)
build:
mkdir -p build/objects build/dependencies build/binaries build/tests/objects build/tests/dependencies build/tests/binaries
build/binaries/$(EXECUTABLE): $(OBJECTS) | build
$(CXX) $(OBJECTS) -o build/binaries/$(EXECUTABLE)
build/tests/binaries/$(TEST_EXECUTABLE): $(SRC_OBJECTS_NO_MAIN) $(TEST_OBJECTS) | build
$(CXX) $(SRC_OBJECTS_NO_MAIN) $(TEST_OBJECTS) -o build/tests/binaries/$(TEST_EXECUTABLE)
build/objects/%.o: source/%.cpp | build
$(CXX) $(CXXFLAGS) -MMD -MF build/dependencies/$*.d -c $< -o $@
build/tests/objects/%.o: tests/source/%.cpp | build
$(CXX) $(TEST_CXXFLAGS) -MMD -MF build/tests/dependencies/$*.d -c $< -o $@
clean:
rm -rf build
run:
./build/binaries/$(EXECUTABLE)
tests: build/tests/binaries/$(TEST_EXECUTABLE)
./build/tests/binaries/$(TEST_EXECUTABLE)
.PHONY: all build clean run tests
-include $(DEPENDENCIES)
-include $(TEST_DEPENDENCIES)#include "fizz-buzz.h"
#include <string>
std::string FizzBuzz::fizzBuzz(int number) {
std::string result = "";
return result;
}#ifndef FIZZ_BUZZ_H
#define FIZZ_BUZZ_H
#include <string>
/**
* Contains only the fizzBuzz method.
*
* fizzBuzz is a method that takes a positive integer as input
* and outputs a string according to the some rules related to
* the divisibility by 2 or 7, and the presence of the digits 2 or 7.
*/
class FizzBuzz {
public:
/**
* Returns a string depending on the number.
*
* fizzBuzz returns the string according to the following rules:
* 1. if number is even, then the string contains a "Fizz";
* 2. if number is divisible by 7, then the string contains a "Buzz";
* 3. if number contains 2, then the string contains a "Fizz";
* 4. if number contains 7, then the string contains a "Buzz";
* 5. every "Fizz" must come before every "Buzz";
* 6. each "Fizz" or "Buzz" correspond to exactly one rule from 1. to 4.;
* 7. if none of 1. to 4. is true, then the string is the number itself;
* 8. the string must not contain more characters than necessary.
*
* @param number A positive integer.
* @return The string according to the rules above.
* @throw std::invalid_argument when number is not positive.
*/
static std::string fizzBuzz(int number);
};
/**
* @example
* \code{.cpp}
* std::cout << FizzBuzz::fizzBuzz(1); \\ Output: "1"
* std::cout << FizzBuzz::fizzBuzz(2); \\ Output: "FizzFizz"
* std::cout << FizzBuzz::fizzBuzz(7); \\ Output: "BuzzBuzz"
* std::cout << FizzBuzz::fizzBuzz(728); \\ Output: "FizzFizzBuzzBuzz"
* \endcode
*/
#endif#include "fizz-buzz.h"
#include <iostream>
int main() {
int number;
std::cout << "Enter a number: ";
std::cin >> number;
std::cout << FizzBuzz::fizzBuzz(number) << std::endl;
return 0;
}#include "fizz-buzz.h"
#include "fizz-buzz-test.h"
#include <iostream>
#include <cassert>
void FizzBuzzTest::runTests() {
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_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";
}#ifndef FIZZ_BUZZ_TEST_H
#define FIZZ_BUZZ_TEST_H
class FizzBuzzTest {
public:
static void runTests();
private:
static void fizzBuzz_OddInputNonDivisibleBy7DoesNotContain2Or7_ReturnsTheSameNumber();
static void fizzBuzz_EvenInputNonDivisibleBy7DoesNotContain2Or7_ReturnsFizz();
static void fizzBuzz_EvenInputNonDivisibleBy7Contains2ButNot7_ReturnsFizzFizz();
static void fizzBuzz_OddInputDivisibleBy7DoesNotContain2Or7_ReturnsBuzz();
static void fizzBuzz_OddInputDivisibleBy7Contains7ButNot2_ReturnsBuzzBuzz();
static void fizzBuzz_EvenInputDivisibleBy7DoesNotContain2Or7_ReturnsFizzBuzz();
static void fizzBuzz_EvenInputNonDivisibleBy7Contains7ButNot2_ReturnsFizzBuzz();
static void fizzBuzz_OddInputDivisibleBy7Contains2ButNot7_ReturnsFizzBuzz();
static void fizzBuzz_OddInputNonDivisibleBy7Contains2And7_ReturnsFizzBuzz();
static void fizzBuzz_OddInputDivisibleBy7Contains2And7_ReturnsFizzBuzzBuzz();
static void fizzBuzz_EvenInputNonDivisibleBy7Contains2And7_ReturnsFizzFizzBuzz();
static void fizzBuzz_EvenInputDivisibleBy7Contains2ButNot7_ReturnsFizzFizzBuzz();
static void fizzBuzz_EvenInputDivisibleBy7Contains7ButNot2_ReturnsFizzBuzzBuzz();
static void fizzBuzz_EvenInputDivisibleBy7Contains2And7_ReturnsFizzFizzBuzzBuzz();
};
#endif#include "fizz-buzz-test.h"
int main() {
FizzBuzzTest::runTests();
return 0;
}Lisez la documentation de la classe
FizzBuzzainsi que les tests.Implémentez la fonction
fizzBuzzdansfizz-buzz.cppde sorte que tous les tests passent.
Indices
std::to_string(number)retourne la chaîne de caractères représentantnumber(par exemple,std::to_string(3)retourne"3").a % bretourne le reste de la division deaparb(par exemple,3 % 2retourne1).bigString.find(smallString) != std::string::nposretourne vrai sibigStringcontientsmallString, faux sinon."3" + "3"retourne"33".
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 nécessaire.