Skip to content

Latest commit

 

History

History
 
 

04-practice

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

Un peu de pratique

Sortez vos claviers   ;-)

Put theory into practice

Une année est bissextile :

  • si l'année est divisible par 4
    et non divisible par 100

  • ou si l'année est divisible par 400

      bool is_leap_year(int year);
    

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;
}
  • The feature uses the same implementation as the test!
  • Finally, what is the added value of the test?

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) );
}
  • Is this a good way of testing?
  • What can be improved?

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