Skip to content

Exercises related to Testing

Write a test program for unique_ptr

Exercice 1

Based on the instructions given in the testing codelab, add a test function to the ptr_test test suite to check that the ownership is passed correctly between two instances of `std::unique_ptr.

Implement the test and verify that it is successful.

Solution

/**
 ** Test that multiple instances of unique pointers correctly manage the
 ** ownership of the the object
*/
ZPP_ZTEST(ptr_test, test_unique_ptr) {
  std::unique_ptr<Test> unique_ptr1(nullptr);

  // Sanity-check value of counter
  zpp_zassert_equal(0, Test::s_instance_count);

  // Create and destroy shared pointer in given scope
  {
    std::unique_ptr<Test> unique_ptr2 = std::make_unique<Test>();
    zpp_zassert_equal(1, Test::s_instance_count);
    // move ownership of unique_ptr2 to unique_ptr1
    // unique_ptr1 = unique_ptr2; is not allowed
    // must use the std::move() semantics
    unique_ptr1 = std::move(unique_ptr2);
    // still one instance only
    zpp_zassert_equal(1, Test::s_instance_count);
    zpp_zassert_equal(Test::kMagicNumber, unique_ptr1->_value);
    // unique_ptr2 does not own ptr any more
    zpp_zassert_equal(nullptr, unique_ptr2.get());
  }

  // unique_ptr1 still owns an instance
  zpp_zassert_equal(1, Test::s_instance_count);

  // release unique_ptr1
  unique_ptr1 = nullptr;

  // unique_ptr instance has been released
  zpp_zassert_equal(0, Test::s_instance_count);
} 

Write a test program for raw pointers

Exercice 2

Based on the instructions given in the testing codelab, add the following test function to the ptr_test test suite. Test that when creating a raw pointer and deallocating it correctly, the destructor is called as expected.

Implement the test and verify that it is successful.

Solution

/**
 * Test that when delete is not called with a raw pointer then a memory leak occurs
*/
ZPP_ZTEST(ptr_test, test_raw_pointers) {
  Test* raw_ptr1(nullptr);

  // Sanity-check value of counter
  zpp_zassert_equal(0, Test::s_instance_count);

  // allocate the raw pointer in a given scope
  {
    // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) -- test of raw pointer usage
    raw_ptr1 = new Test;
    zpp_zassert_equal(1, Test::s_instance_count);
    Test* raw_ptr2 = raw_ptr1;
    // still one instance only
    zpp_zassert_equal(1, Test::s_instance_count);
    zpp_zassert_equal(Test::kMagicNumber, raw_ptr1->_value);
    // cppcheck-suppress knownConditionTrueFalse
    zpp_zassert_true(raw_ptr1 == raw_ptr2);
  }

  // no delete called yet
  zpp_zassert_equal(1, Test::s_instance_count);

  // call delete
  // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) -- test of raw pointer usage
  delete raw_ptr1;
  raw_ptr1 = nullptr;

  // delete was called -> the object must be destroyed
  zpp_zassert_equal(0, Test::s_instance_count);
}