{"id":2652,"date":"2014-12-05T21:39:18","date_gmt":"2014-12-05T21:39:18","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=2652"},"modified":"2014-12-05T21:39:18","modified_gmt":"2014-12-05T21:39:18","slug":"unit-testing-native-c-code-using-visual-studio","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/unit-testing-native-c-code-using-visual-studio\/","title":{"rendered":"Unit testing native C++ code using Visual Studio"},"content":{"rendered":"<p><em>Before I begin with this post, let me state that <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/hh270864.aspx\" title=\"Unit testing native code with Test Explorer\" target=\"_blank\">Unit testing native code with Test Explorer<\/a> explains this topic very well. So why am I writing a post on this? Well I did encounter a couple of issues and felt it worth documenting those along with the &#8220;steps&#8221; I took to when using the Microsoft unit testing solution for C++ in Visual Studio.<\/em><\/p>\n<p>Let&#8217;s jump straight in &#8211; my intention is to create a simple class which has some setter and getter methods (nothing special) and test the implementations, obviously this is just a simple example but it will cover some of the fundamentals (I hope).<\/p>\n<p>Here&#8217;s the steps to get a couple of Visual Studio projects up and running, one being the code we want to test, the second being for the unit tests. <\/p>\n<ul>\n<li>Let&#8217;s start by creating a DLL for our library\/code.<\/li>\n<li>Open Visual Studio and create a New Project<\/li>\n<li>Select Visual C++ Win32 Project and give it a name (mine&#8217;s named MotorController), then press OK<\/li>\n<li>When the Win32 Application Wizard appears, press next then select DLL for Application Type, uncheck Security Development Lifecycle and check Export Symbols. I&#8217;m not going to use MFC or ATL for this so leave them unchecked, then press Finish<\/li>\n<li>Now let&#8217;s create the unit test project<\/li>\n<li>Select Add | New Project from the solution context menu<\/li>\n<li>Select the Visual C++ | Test section and click on Native Unit Test Project<\/li>\n<li>Give the unit test project a name (mine&#8217;s MotorControllerTests), then press OK<\/li>\n<li>Before we can test anything in the MotorController project we need to reference the project<\/li>\n<li>Right mouse click on your unit test project and select Properties<\/li>\n<li>Select Common Properties | Framework and References<\/li>\n<li>Press the Add New Reference button and check the project with code to be tested (i.e. my MotorController project), press OK and OK again on Properties dialog<\/li>\n<\/ul>\n<p>At this point you should have two projects, one for your code and one for your unit tests. Both are DLL&#8217;s and the unit test project includes the code to run the tests via the Test Explorer.<\/p>\n<p>So before we write any code and to ensure all is working, feel free to run the tests&#8230; <\/p>\n<p>Select the menu item &#8211; Test | Run | Run All Tests. If all goes well, within Test Explorer, you&#8217;ll see a single test class named UnitTest1 (unless you renamed this) and a single method TestMethod1 (unless you changed this).<\/p>\n<p>Now let&#8217;s go ahead and write some tests. I&#8217;m going to assume you&#8217;ve used the same names as I have for the objects etc. but feel free to change the code to suit your object names etc.<\/p>\n<ul>\n<li>Rename the TEST_CLASS from UnitTest1 to MotorControllerTest and change the file name of the unit test to match (i.e. MotorControllerTest.cpp)<\/li>\n<li>We&#8217;re going to need access to the header file for the MotorController class so add an include to the MotorControllerTest.cpp file to include the &#8220;MotorController.h&#8221; header, I&#8217;m going to simply use the following for now (i.e. I&#8217;m not going to set up the include folders in VC++)\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n#include &quot;..\/MotorController\/MotorController.h&quot;\r\n<\/pre>\n<\/li>\n<li>We&#8217;re going to implement a couple of simple setter and getter methods to demonstrate the concepts of unit testing with Visual Studio. So to begin with let&#8217;s rename the current TEST_METHOD to getSpeed, then add another TEST_METHOD named getDirection, so your code should like like this\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nTEST_CLASS(MotorControllerTest)\r\n{\r\npublic:\r\n   TEST_METHOD(getSpeed)\r\n   {\r\n   }\r\n\r\n   TEST_METHOD(getDirection)\r\n   {\r\n   }    \r\n};\r\n<\/pre>\n<\/li>\n<li>Now if we run these tests we&#8217;ll see our newly named class and two test methods are green, as we&#8217;ve not implement the code this might be a little off putting so you can always insert the Assert::Fail line into your unit test method until it&#8217;s implemented, for example\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nTEST_METHOD(getSpeed)\r\n{\r\n   Assert::Fail();\r\n}\r\n<\/pre>\n<p>If you now run your tests (assuming you placed the Assert::Fail into your methods) they will both fail, which is as expected until such time as we implement the code to make them pass.\n<\/li>\n<li>To save going through each step in creating the code, I&#8217;ll now supply the unit test code for the final tests\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nTEST_CLASS(MotorControllerTest)\r\n{\r\npublic:\r\n\t\t\r\n   TEST_METHOD(getSpeed)\r\n   {\r\n      CMotorController motor;\r\n      motor.setSpeed(123);\r\n\r\n      Assert::AreEqual(123, motor.getSpeed());\r\n   }\r\n\r\n   TEST_METHOD(getDirection)\r\n   {\r\n      CMotorController motor;\r\n      motor.setDirection(Forward);\r\n\r\n      Assert::AreEqual(Forward, motor.getDirection());\r\n   }    \r\n};\r\n<\/pre>\n<\/li>\n<li>Next let&#8217;s implement some code in the MotorController.h and MotorController.cpp\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n\/\/ MotorController.h\r\n\r\nenum Direction\r\n{\r\n    Forward,\r\n    Reverse\r\n};\r\n\r\n\/\/ This class is exported from the MotorController.dll\r\nclass MOTORCONTROLLER_API CMotorController {\r\nprivate:\r\n    int speed;\r\n    Direction direction;\r\npublic:\r\n\tCMotorController(void);\r\n\r\n    void setSpeed(int speed);\r\n    int getSpeed();\r\n\r\n    void setDirection(Direction direction);\r\n    Direction getDirection();\r\n};\r\n\r\n<\/pre>\n<p>and<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n\/\/ MotorController.cpp\r\n\r\nCMotorController::CMotorController()\r\n{\r\n}\r\n\r\nvoid CMotorController::setSpeed(int speed)\r\n{\r\n    this-&gt;speed = speed;\r\n}\r\n\r\nint CMotorController::getSpeed()\r\n{\r\n    return speed;\r\n}\r\n\r\nvoid CMotorController::setDirection(Direction direction)\r\n{\r\n    this-&gt;direction = direction;\r\n}\r\n\r\nDirection CMotorController::getDirection()\r\n{\r\n    return direction;\r\n}\r\n<\/pre>\n<\/li>\n<li>If you run these tests you&#8217;ll find a compiler error, something along the lines of\n<p><em>Error 1 error C2338: Test writer must define specialization of ToString<const Q&#038; q> for your class class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > __cdecl Microsoft::VisualStudio::CppUnitTestFramework::ToString<enum Direction>(const enum Direction &#038;).\tc:\\program files (x86)\\microsoft visual studio 11.0\\vc\\unittest\\include\\cppunittestassert.h\t66\t1\tMotorControllerTests<br \/>\n<\/em><\/p>\n<p>The problem here is that we&#8217;ve introduced a type which we have no ToString method for within the CppUnitTestAssert.h header, so we need to add one. Simply insert the following code before your TEST_CLASS<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nnamespace Microsoft{ namespace VisualStudio {namespace CppUnitTestFramework \r\n{\r\n    template&lt;&gt; static std::wstring ToString&lt;Direction&gt;(const Direction&amp; direction) \r\n    { \r\n       return direction == Forward ? L&quot;F&quot; : L&quot;R&quot;; \r\n    };\r\n}}}\r\n<\/pre>\n<p>The concatenation of the namespace on a single line is obviously not neccesary, I just copied the way the CppUnitTestAssert.h file had their namespace and also it ensures I can easily show you the main code for this. What does matter though is that we&#8217;ve implemented a new ToString which understands the Direction type\/enum.\n<\/li>\n<li>Finally, run the tests and see what the outcome is &#8211; both tests should pass, feel free to break the getter code to prove the SUT is really being tested<\/li>\n<\/ul>\n<p>That should be enough to get your unit testing in VC++ up and running.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Before I begin with this post, let me state that Unit testing native code with Test Explorer explains this topic very well. So why am I writing a post on this? Well I did encounter a couple of issues and felt it worth documenting those along with the &#8220;steps&#8221; I took to when using the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[4,28],"tags":[],"class_list":["post-2652","post","type-post","status-publish","format-standard","hentry","category-c-programming","category-testing"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/2652","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=2652"}],"version-history":[{"count":14,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/2652\/revisions"}],"predecessor-version":[{"id":2698,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/2652\/revisions\/2698"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=2652"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=2652"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=2652"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}