{"id":2315,"date":"2017-03-01T12:07:28","date_gmt":"2017-03-01T20:07:28","guid":{"rendered":"http:\/\/visualgdb.com\/w\/?p=2315"},"modified":"2017-03-01T12:07:28","modified_gmt":"2017-03-01T20:07:28","slug":"developing-unit-tests-for-linux-with-googletest","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/tests\/googletest\/","title":{"rendered":"Developing unit tests for Linux with GoogleTest"},"content":{"rendered":"<p>This tutorial shows how to use the GoogleTest framework to develop unit tests for Linux with VisualGDB. We will create a basic remotely built Linux project and will show how to use different GoogleTest assertion macros to test for various conditions.<\/p>\n<p>Before you begin, install VisualGDB 5.2.<\/p>\n<ol>\n<li>Start Visual Studio and open the VisualGDB Linux Project Wizard:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/01-prjname1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2316\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/01-prjname1.png\" alt=\"01-prjname\" width=\"887\" height=\"544\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/01-prjname1.png 887w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/01-prjname1-300x184.png 300w\" sizes=\"(max-width: 887px) 100vw, 887px\" \/><\/a><\/li>\n<li>Select &#8220;New Project -&gt; Unit test project -&gt; MSBuild&#8221;:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/02-test.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2317\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/02-test.png\" alt=\"02-test\" width=\"822\" height=\"662\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/02-test.png 822w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/02-test-300x242.png 300w\" sizes=\"(max-width: 822px) 100vw, 822px\" \/><\/a><\/li>\n<li>Select the computer that you want to use for building. The steps described here will work for remotely built projects as well as for the projects built with cross-toolchains:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/03-prj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2318\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/03-prj.png\" alt=\"03-prj\" width=\"822\" height=\"662\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/03-prj.png 822w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/03-prj-300x242.png 300w\" sizes=\"(max-width: 822px) 100vw, 822px\" \/><\/a><\/li>\n<li>Proceed with the default settings on the next page:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/04-access.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2319\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/04-access.png\" alt=\"04-access\" width=\"822\" height=\"662\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/04-access.png 822w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/04-access-300x242.png 300w\" sizes=\"(max-width: 822px) 100vw, 822px\" \/><\/a><\/li>\n<li>Press &#8220;Finish&#8221; to generate the project. Build it via Ctrl-Shift-B and ensure that VisualGDB recognizes the sample tests generated by the wizard:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/05-build.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2320\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/05-build.png\" alt=\"05-build\" width=\"977\" height=\"667\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/05-build.png 977w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/05-build-300x205.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/05-build-130x90.png 130w\" sizes=\"(max-width: 977px) 100vw, 977px\" \/><\/a><\/li>\n<li>Select Test-&gt;Run All to automatically launch the tests. Ensure that the FailingTest() reports a failure and the two other tests succeed:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/06-testresults.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2321\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/06-testresults.png\" alt=\"06-testresults\" width=\"977\" height=\"667\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/06-testresults.png 977w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/06-testresults-300x205.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/06-testresults-130x90.png 130w\" sizes=\"(max-width: 977px) 100vw, 977px\" \/><\/a><\/li>\n<li>Now we will show how to use the most common GoogleTest macros to check for common conditions. Remove the auto-generated tests and put the following contents into the &lt;Project Name&gt;Tests.cpp file:\n<pre class=\"\">#include &lt;gtest\/gtest.h&gt;\r\n#include &lt;stdio.h&gt;\r\n\r\nbool IsWordAligned(void *addr)\r\n{\r\n\u00a0\u00a0\u00a0 return (((unsigned long)addr) &amp; 0x3) == 0;\r\n}\r\n\r\nTEST(DemoTests, AllocationTest)\r\n{\r\n\u00a0\u00a0\u00a0 char *p = new char[1024];\r\n\u00a0\u00a0\u00a0 ASSERT_TRUE(p != NULL);\r\n\u00a0\u00a0\u00a0 ASSERT_PRED1(IsWordAligned, p);\r\n\u00a0\u00a0\u00a0 delete[] p;\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 ASSERT_THROW(p = new char[2 * 1024 * 1024 * 1024], std::bad_alloc);\r\n}<\/pre>\n<p>The code above shows 3 different assertion macros:<\/p>\n<ul>\n<li>ASSERT_TRUE() is used to quickly check that a condition is true. Note that ASSERT_NE() will not work with NULL due to limitations of GoogleTest.<\/li>\n<li>ASSERT_PRED1() is used to check the value with a custom check function (a.k.a. predicate)<\/li>\n<li>ASSERT_THROW() is used to verify that the checked expression throws an exception (we check that trying to allocate too many bytes results in a std::bad_alloc)<\/li>\n<\/ul>\n<\/li>\n<li>Build the project and run the test. Ensure that it passes:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/07-throw.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2322\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/07-throw.png\" alt=\"07-throw\" width=\"977\" height=\"667\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/07-throw.png 977w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/07-throw-300x205.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/07-throw-130x90.png 130w\" sizes=\"(max-width: 977px) 100vw, 977px\" \/><\/a><\/li>\n<li>Now we will provide a custom implementation of the new() operator that will simply call malloc() and will see if the our test can catch this:\n<pre class=\"\">void * operator new(size_t size)\r\n{\r\n\u00a0\u00a0\u00a0 return malloc(size);\r\n}<\/pre>\n<\/li>\n<li>Run the test and see how the test report provides a detailed message on what went wrong:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/08-nothrow.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2323\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/08-nothrow.png\" alt=\"08-nothrow\" width=\"977\" height=\"667\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/08-nothrow.png 977w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/08-nothrow-300x205.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/08-nothrow-130x90.png 130w\" sizes=\"(max-width: 977px) 100vw, 977px\" \/><\/a><\/li>\n<li>Now we will cause the IsWordAligned() check to fail by adding 1 to the allocated pointer:\n<pre class=\"\">\u00a0\u00a0\u00a0 ASSERT_PRED1(IsWordAligned, p + 1);<\/pre>\n<p><a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/09-align.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2324\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/09-align.png\" alt=\"09-align\" width=\"977\" height=\"667\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/09-align.png 977w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/09-align-300x205.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/09-align-130x90.png 130w\" sizes=\"(max-width: 977px) 100vw, 977px\" \/><\/a><\/li>\n<li>Note how the test now fails, but the shown message is not very informative. You could improve its readability by changing IsWordAligned() to return <strong>testing::AssertionResult<\/strong> with\u00a0 some additional information instead of just <strong>bool<\/strong>:\n<pre class=\"\">testing::AssertionResult IsWordAligned(void *addr)\r\n{\r\n\u00a0\u00a0\u00a0 if ((((unsigned long)addr) &amp; 0x3) == 0)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return testing::AssertionSuccess();\r\n\u00a0\u00a0\u00a0 else\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 return testing::AssertionFailure() &lt;&lt; addr &lt;&lt; \" is not word-aligned\";\r\n}<\/pre>\n<p>Change the line calling IsWordAligned() as follows:<\/p>\n<pre class=\"\">\u00a0\u00a0\u00a0 ASSERT_TRUE(IsWordAligned(p + 1));<\/pre>\n<\/li>\n<li>The error message will now be more meaningful and will show the mismatched value:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/10-alignmsg.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2325\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/10-alignmsg.png\" alt=\"10-alignmsg\" width=\"977\" height=\"667\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/10-alignmsg.png 977w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/10-alignmsg-300x205.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/10-alignmsg-130x90.png 130w\" sizes=\"(max-width: 977px) 100vw, 977px\" \/><\/a><\/li>\n<li>Now we will show how to use test fixtures to define initialization and cleanup code shared between several tests. Start with defining the following class:\n<pre class=\"\">class RNGTests : public::testing::Test\r\n{\r\nprotected:\r\n\u00a0\u00a0\u00a0 virtual void SetUp() override\r\n\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 srand(123);\r\n\u00a0\u00a0\u00a0 }\r\n};<\/pre>\n<\/li>\n<li>Then define a basic test that will check the first value returned by rand():\n<pre class=\"\">TEST_F(RNGTests, BasicTest)\r\n{\r\n\u00a0\u00a0\u00a0 ASSERT_EQ(rand(), 128959393);\r\n}<\/pre>\n<p>Note that we used TEST_F() instead of just TEST() to declare the test. This will ensure that the RNGTests::SetUp() will be called before the test and RNGTests::TearDown() will be called after the test.<\/li>\n<li>Run the test and ensure it passes:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/11-rng.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2326\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/11-rng.png\" alt=\"11-rng\" width=\"977\" height=\"667\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/11-rng.png 977w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/11-rng-300x205.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/11-rng-130x90.png 130w\" sizes=\"(max-width: 977px) 100vw, 977px\" \/><\/a>The value returned by rand() may not match the one shown here, as different implementations of rand() may work differently. If this happens, edit the test accordingly.<\/li>\n<li>You can use the Debug Tests command to quickly verify that srand() actually gets called:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/13-srand.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2327\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/13-srand.png\" alt=\"13-srand\" width=\"977\" height=\"667\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/13-srand.png 977w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/13-srand-300x205.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/13-srand-130x90.png 130w\" sizes=\"(max-width: 977px) 100vw, 977px\" \/><\/a><\/li>\n<li>To understand how exactly GoogleTest handles the fixtures, you can right-click on the line defining your test and select &#8220;Preprocess Selected Lines&#8221;. VisualGDB will show that defining a test with TEST_F() simply defines a class derived from your fixture class:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/12-expand.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2329\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/12-expand.png\" alt=\"12-expand\" width=\"977\" height=\"667\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/12-expand.png 977w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/12-expand-300x205.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/12-expand-130x90.png 130w\" sizes=\"(max-width: 977px) 100vw, 977px\" \/><\/a><\/li>\n<li>If you are not using C++11 or later, you may encounter strange IntelliSense errors:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/14-sense.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2331\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/14-sense.png\" alt=\"14-sense\" width=\"977\" height=\"667\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/14-sense.png 977w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/14-sense-300x205.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/14-sense-130x90.png 130w\" sizes=\"(max-width: 977px) 100vw, 977px\" \/><\/a><\/li>\n<li>The easiest way to fix those is to switch the language standard to C++11 or later:<a href=\"http:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/15-c-11.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2332\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/15-c-11.png\" alt=\"15-c++11\" width=\"822\" height=\"558\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/15-c-11.png 822w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2016\/11\/15-c-11-300x204.png 300w\" sizes=\"(max-width: 822px) 100vw, 822px\" \/><\/a><\/li>\n<\/ol>\n<p>You can read more about the advanced features of the GoogleTest framework <a href=\"https:\/\/github.com\/google\/googletest\/blob\/master\/googletest\/docs\/AdvancedGuide.md\">here<\/a> or look through <a href=\"http:\/\/visualgdb.com\/tutorials\/tests\/cpputest\/\">this tutorial<\/a> to see how to use VisualGDB with CppUTest.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to use the GoogleTest framework to develop unit tests for Linux with VisualGDB. We will create<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[128],"tags":[137,129],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/2315"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=2315"}],"version-history":[{"count":2,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/2315\/revisions"}],"predecessor-version":[{"id":2333,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/2315\/revisions\/2333"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=2315"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=2315"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=2315"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}