Skip to the content.

Tests Unitaire, support de la Spécification

Où écrire la documentation ?

Philippe Bourgeon (2016)

Le test unitaire est comme le lavage des mains avant une intervention chirurgicale. Cette simple mesure au XIXe siècle a permis des progrès considérables.

Certaines méthodes de programmation des années 90 pronnaient le raffinnement : le développeur écrivaient des tartines de commentaires avant d’écrire le code.

Les tests unitaires sont une bien meilleure solution car les écrits restent (commentaires) et le code s’envole (change). Donc le test est une documentation interactive avec le code : cette documentation est forcée d’évoluer avec le code.

Write tests for people

Gerard Meszaros (CC-BY-3.0-US 2009)

Pour qui écrire les tests ?
Pour ceux qui essayeront de comprendre l’implémentation.

Les tests documentent l’implémentation :
Ils décrivent le fonctionnement du code testé.

Pour chaque cas de test :

Le test unitaire décrit la fonctionnalité testée

Nat Pryce et Steve Freeman à la
conférence XP Day 2006 “Are Your Tests Really Driving Your Development?”, in French:

Le test unitaire doit aller plus loin que la simple vérification de la fonctionalité : le test doit clairement exprimer ce que fait cette fonctionnalité au lecteur.

=> Le test unitaire doit formaliser la spécification.

Le test unitaire n’ayant pas été écrit avec à l’esprit son rôle de specification peut être très confus à comprendre.

Plus il est difficile de comprendre de ce qui est testé, plus il peut être difficile de faire évoluer une base de code.

Le test unitaire est la specification

Great Unit Tests

Should and Must

Coding rules for Unit Test

function names are phrases

Les règles de codage sont différentes pour le code à destination de la prod et pour celui des tests unitaires.

Exercise: Rewrite unit test from scratch

Algorithm from wikipedia:

Provide GUTs using Google Test syntax:

TEST(case_name, test_name)

Comment this result

Improve the following tests:

TEST(is_leap_year, years_not_divisible_by_4_are_not_leap_years)
{
  ASSERT_FALSE( is_leap_year(   7) );
  ASSERT_FALSE( is_leap_year(  17) );
  ASSERT_FALSE( is_leap_year(2002) );
  ASSERT_FALSE( is_leap_year(2003) );
}

TEST(is_leap_year, years_divisible_by_4_but_not_by_100_are_leap_years)
{
  ASSERT_FALSE( is_leap_year(1700) );
  ASSERT_FALSE( is_leap_year(1800) );
  ASSERT_FALSE( is_leap_year(1900) );
  ASSERT_FALSE( is_leap_year(2100) );
}

TEST(is_leap_year, years_divisible_by_100_but_not_by_400_are_not_leap_years)
{
  ASSERT_TRUE(  is_leap_year(1704) );
  ASSERT_TRUE(  is_leap_year(1916) );
  ASSERT_TRUE(  is_leap_year(2012) );
  ASSERT_TRUE(  is_leap_year(2016) );
}

Solution from Kevlin Henney

TEST(A_year_is_not_a_leap_year, if_it_is_not_divisible_by_4)
{
    ASSERT_FALSE(is_leap_year(2015));
}

TEST(A_year_is_a_leap_year, if_it_is_divisible_by_4_but_not_by_100)
{
    ASSERT_TRUE(is_leap_year(2016));
}

TEST(A_year_is_not_a_leap_year, if_it_is_divisible_by_100_but_not_by_400)
{
    ASSERT_FALSE(is_leap_year(1900));
}

TEST(A_year_is_a_leap_year, if_it_is_divisible_by_400)
{
    ASSERT_TRUE(is_leap_year(2000));
}

Real value of tests

Charles Antony Richard Hoare (1996)

The real value of tests is not that they detect bugs in the code, but that they detect inadequacies in the methods, concentration, and skills of those who design and produce the code.