Skip to the content.

Un peu de pratique

Sortez vos claviers   ;-)

Put theory into practice

Une année est bissextile :


Exercice : Coder

Par où commencer ?

Écrire les tests unitaires

Test the function is_leap_year()

Is this test a good idea?

test()
{
  // Test all years until 10'000
  for (int y=1; y<10*1000; ++y)
  {
    bool leap;
    if (y % 4)
      leap = false;
    else
      leap = y % 100 ? true : y % 400;

    // Check if same result
    actual = is_leap_year(y);
    ASSERT_EQUAL(leap, actual);
  }
}

Implement is_leap_year()

bool is_leap_year (int year)
{
  bool leap; // value to return

  if (year % 4) leap = false;
  else leap = year % 100 ? true : year % 400;

  return leap;
}

Just test some cases

test()
{
  ASSERT_FALSE( is_leap_year(   7) );
  ASSERT_FALSE( is_leap_year(  17) );
  ASSERT_FALSE( is_leap_year(2002) );
  ASSERT_FALSE( is_leap_year(2003) );
  ASSERT_FALSE( is_leap_year(1700) );
  ASSERT_FALSE( is_leap_year(1800) );
  ASSERT_FALSE( is_leap_year(1900) );
  ASSERT_FALSE( is_leap_year(2100) );
  ASSERT_TRUE(  is_leap_year(1704) );
  ASSERT_TRUE(  is_leap_year(1916) );
  ASSERT_TRUE(  is_leap_year(2012) );
  ASSERT_TRUE(  is_leap_year(2016) );
}

With comments

test()
{
  // Not Divisible by 4
  ASSERT_FALSE( is_leap_year(   7) );
  ASSERT_FALSE( is_leap_year(  17) );
  ASSERT_FALSE( is_leap_year(2002) );
  ASSERT_FALSE( is_leap_year(2003) );

  // Multiple of 100 except 400
  ASSERT_FALSE( is_leap_year(1700) );
  ASSERT_FALSE( is_leap_year(1800) );
  ASSERT_FALSE( is_leap_year(1900) );
  ASSERT_FALSE( is_leap_year(2100) );

  // Rest
  ASSERT_TRUE(  is_leap_year(1704) );
  ASSERT_TRUE(  is_leap_year(1916) );
  ASSERT_TRUE(  is_leap_year(2012) );
  ASSERT_TRUE(  is_leap_year(2016) );
}

One unit test = One expectation

Roy Osherove (2010)

Unit tests should fail for exactly one reason.
That’s why you should use one assert per unit test.

He has also added (2010)

Test one logical CONCEPT per test.
You can have multiple asserts on the same object.
They will usually be the same concept being tested.

  Unit Test Feature
Bad big_test() -> is_leap_year()
Good test1()
test2()
test3()
-> is_leap_year()

One feature = multiple test cases

Original idea

Unit Tests Code
test1() -> feature1()
test2() -> feature2()
test3() -> feature3()

Idea One unit test = One expectation

Unit Tests Code
test11()
test12()
test13()
test14()
…
-> feature1()
test21()
test22()
test23()
test24()
…
-> feature2()
test31()
test32()
test33()
test34()
…
-> feature3()

Split big test function

test_not_divisible_by_4_is_not_leap()
{
  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_multiple_of_100_except_400_is_not_leap()
{
  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_rest_is_leap()
{
  ASSERT_TRUE(  is_leap_year(1704) );
  ASSERT_TRUE(  is_leap_year(1916) );
  ASSERT_TRUE(  is_leap_year(2012) );
  ASSERT_TRUE(  is_leap_year(2016) );
}