Print this Page

Introduction to asserts and expects

Basic checks

In test we should be able to check if code is doing the right thing. To do that Google Test give us tools for having some checks which may end up with success, nonfatal failure, or fatal failure. In next sections you will learn how to write different type of checks for your test.

Notice

Examples below assume that you have installed:

  • gcc compiler
  • google test library

Asserts

Google Test gives us tools for checking constraints. Usually one of the ASSERT_* command will be used to check if your code is working correctly.

#include 

TEST(Example001, how_to_do_asserts)
{
  ASSERT_TRUE(!false); // !false == true
  ASSERT_FALSE(!true); // !true == false

  ASSERT_EQ(2, 1 + 1); // 2 == 1 + 1
  ASSERT_NE(3, 1 + 1); // 1 != 1 + 1
  ASSERT_LT(1, 3); // 1 < 3
  ASSERT_LE(2, 5); // 2 <= 1
  ASSERT_GE(5, 2); // 5 >= 2

  // the two C strings have the same content
  ASSERT_STREQ("abc", "a" "b" "c");

  // the two C strings have different content
  ASSERT_STRNE("abc", "aBc");

  // the two C strings have the same content, ignoring case
  ASSERT_STRCASEEQ("abc", "aBc");

  // the two C strings have different content, ignoring case
  ASSERT_STRCASENE("abc", "a");
}

Every ASSERT_ command treats first argument as expected value and second as actual value – it is very important in case of failure message.

After we compile it:

$ g++ test.cpp -lgtest -lgtest_main -lpthread
$

We could run our test calling ./a.out

$ ./a.out
Running main() from gtest_main.cc
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from Example001
[ RUN      ] Example001.how_to_do_asserts
[       OK ] Example001.how_to_do_asserts (0 ms)
[----------] 1 test from Example001 (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[  PASSED  ] 1 test.
$

It is rather clear what is going on. If any ASSERT_* fail it will look like this:

$ ./a.out
Running main() from gtest_main.cc
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from Example001
[ RUN      ] Example001.how_to_do_asserts
test.cpp:10: Failure
Expected: (5) >= (22), actual: 5 vs 22
[  FAILED  ] Example001.how_to_do_asserts (0 ms)
[----------] 1 test from Example001 (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (1 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] Example001.how_to_do_asserts

 1 FAILED TEST
$

It should be easy for you to find out what I have changed to make my test failed. Lets check what will happened when we brake all our asserts! I changed my test.cpp to:

#include 

TEST(Example001, how_to_do_asserts)
{
  ASSERT_EQ(22, 1 + 1); // 22 == 1 + 1
  ASSERT_NE(2, 1 + 1); // 2 != 1 + 1
  ASSERT_LT(12, 3);     // 12 < 3
  ASSERT_LE(22, 5);     // 22 <= 5
  ASSERT_GE(5, 22);     // 5 >= 22

  // the two C strings have the same content
  ASSERT_STREQ("aabc", "a" "b" "c");

  // the two C strings have different content
  ASSERT_STRNE("abc", "abc");

  // the two C strings have the same content, ignoring case
  ASSERT_STRCASEEQ("aabc", "aBc");

  // the two C strings have different content, ignoring case
  ASSERT_STRCASENE("abc", "abC");
}

which should end up with all asserts failed! Lets try it!

$ g++ test.cpp -lgtest -lgtest_main -lpthread
$ ./a.out
Running main() from gtest_main.cc
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from Example001
[ RUN      ] Example001.how_to_do_asserts
test.cpp:5: Failure
Value of: 1 + 1
  Actual: 2
Expected: 22
[  FAILED  ] Example001.how_to_do_asserts (0 ms)
[----------] 1 test from Example001 (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] Example001.how_to_do_asserts

 1 FAILED TEST
$

Hmm… it end up with only one failure! It seems that test stops on first failed assert – and this is how asserts work! Asserts should be used when there is no point in running rest of test (when some check failed) i.e. when you are checking if some method return pointer to some object there is no point in checking state of this object when method return null pointer.

Object* object = o.createDefault();

ASSERT_NE(0, object);
ASSERT_EQ(12, object->a);

If you want to continue test after some check failed you should use EXPECT_* instead of ASSERT_*

Expects

Lets rewrite all ASSERT_ commands to EXPECT_ from previous test in which all check should failed

#include 

TEST(Example001, how_to_do_asserts)
{
  EXPECT_EQ(22, 1 + 1); // 22 == 1 + 1
  EXPECT_NE(2, 1 + 1); // 2 != 1 + 1
  EXPECT_LT(12, 3);     // 12 < 3
  EXPECT_LE(22, 5);     // 22 <= 1
  EXPECT_GE(5, 22);     // 5 >= 22

  // the two C strings have the same content
  EXPECT_STREQ("aabc", "a" "b" "c");

  // the two C strings have different content
  EXPECT_STRNE("abc", "abc");

  // the two C strings have the same content, ignoring case
  EXPECT_STRCASEEQ("aabc", "aBc");

  // the two C strings have different content, ignoring case
  EXPECT_STRCASENE("abc", "abC");
}

Recompile and rerun our test.

$ g++ test.cpp -lgtest -lgtest_main -lpthread
$ ./a.out
Running main() from gtest_main.cc
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from Example001
[ RUN      ] Example001.how_to_do_asserts
test.cpp:5: Failure
Value of: 1 + 1
  Actual: 2
Expected: 22
test.cpp:6: Failure
Expected: (2) != (1 + 1), actual: 2 vs 2
test.cpp:7: Failure
Expected: (12) < (3), actual: 12 vs 3
test.cpp:8: Failure
Expected: (22) <= (11), actual: 22 vs 11
test.cpp:10: Failure
Expected: (5) >= (22), actual: 5 vs 22
test.cpp:13: Failure
Value of: "a" "b" "c"
  Actual: "abc"
Expected: "aabc"
test.cpp:16: Failure
Expected: ("abc") != ("abc"), actual: "abc" vs "abc"
test.cpp:19: Failure
Value of: "aBc"
Expected: "aabc" (ignoring case)
test.cpp:22: Failure
Expected: ("abc") != ("abC") (ignoring case), actual: "abc" vs "abC"
[  FAILED  ] Example001.how_to_do_asserts (1 ms)
[----------] 1 test from Example001 (1 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (1 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] Example001.how_to_do_asserts

 1 FAILED TEST
$

As you can see all failed checks display some nice failure message with some descriptive explanations why it failed. In line which starts with “Expected:” first thing in after “Expected:” is what is written into code i.e. when I have check or assert which looks like:

EXPECT_NE(0, myValue);

you will get message

Expected: (0) != (myValue), actual: 0 vs 0

and things after “actual:” describes actual values which where computed before check was made.

Important!

Hint!

Try to use descriptive variable names instead of hard coded values – if you use good variable name your potential failure message will tell you lot.

Permanent link to this article: http://sajdak.eu/trainings/agile-cpp-developer/google-test/introduction-to-asserts-and-expects/

2 comments

  1. streser

    Hint: Use some tools to colour your code and to make your consol oitput more readable.

    1. Filip Sajdak

      Well, I am using javascript library to do that. On mobile it take some time (after content is loaded) to color the code.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>