前言:上一篇谷歌的测试的框架,大致介绍了测试的框架的基本情况。这一节,讲述如何构建一个真正的自动化测试项目:

注意,文章最后一部分有一个视频,这个视频是一步一步构建谷歌测试案例,值得仔细研究。

Unit Testing C++ with Google Test

Unit testing C++ applications is not exactly easy. Without any embeddable metadata, the actual process of running a unit test has to be defined explicitly in code. Luckily, frameworks such asGoogle Test provide comprehensive support for this. Let’s take a look.

Download and Build

Google Test is not header-only: there are libraries to build. So, as a Visual Studio user, you have essentially two options.

Option 1 (probably the easiest): Just install Google Test from Nuget:

This sets everything up, but your mileage may vary: the package comes with pre-build binaries that may not target the compiler and bitness you want. So the other option is…

Option 2 (more effort required): Download and build Google Test in some local directory (e.g.,c:\gtest). Now, lucky for us, Google Test comes with a set of Visual Studio projects/solutions ready for building the binaries. You’ll find those in \msvc. Now is a chance for you to open up the solution (e.g., gtest.sln), configure things how you want, then build it and copy the library files and EXEs to some convenient location (e.g., \gtest\lib).

The icing on the cake is you can now open up the %LOCALAPPDATA%\Microsoft\MSBuild\v4.0folder and edit the .user.props files to always include the Google Test paths. Or use Visual Studio’s own Property Manager. This way you’ll always have the directories available, though the library to link against depends on whether you’re building a Debug or Release version.

How It Works

Let’s state the obvious first: Google Test requires you to build an executable. It’s a command-line app, and when you run it, it runs your tests. Even makes them nice and colorful:

So, it is entirely possible to keep rebuilding and running the EXEs, visually inspect the results and fix when necessary. Of course, this works when you have a few tests: if you have hundreds, well… this is where you need tool support.

At any rate, the first thing you need to do is

  • Add the include header

  • Reference the appropriate libraries. If you are using the NuGet package, you don’t have to do this, but otherwise you need to reference gtest.lib for the Release build and gtestd.libfor Debug.

So, in order to run the tests, Google Test needs you to implement the main entrypoint with code similar to:

The call to InitGoogleTest() parses command-line arguments: you can specify your own arguments. To find out which arguments Google Test supports, just run your EXE with the --help flag.

What is a Test?

In its simplest form, a test is just a chunk of code that checks if some condition holds. If it holds, the test passes; if it doesn’t, the test fails.

There are many ways to test conditions. The simplest varieties are EXPECT_TRUE() andEXPECT_FALSE, which can be used as follows:

You’ll notice that the above expectation is wrapped in a TEST() macro. This macro is necessary to tell Google Test that you are, in fact, writing a test. A single test can contain more than once statement, of course.

A slightly more useful variety is EXPECT_EQ(), which tests that the second argument is the same as the first, for example

So the above states that 4 should be the result of adding 2 and 2. I also use the << operator to give a human-readable message to whoever is running the test in case it fails.

Now, EXPECT_EQ does not stop execution. If you have several EXPECT_EQ calls in one test, they will all run. If you want the first test comparison to stop execution if it fails, use ASSERT_EQinstead.

Some refinements of EXPECT_EQ (and ASSERT_, by analogy) include comparisons (e.g.,EXPECT_LT is a less-than check), comparisons of floating-point numbers (EXPECT_FLOAT_EQ and similar), and many more.

At any rate, your TEST() is now runnable. Its location isn’t important so long as it ends up being part of the build. If you want to figure out what tests you’ve got written, just use R++’s Unit Test Explorer, which will locate and list all the unit tests in the project.

Test Fixtures

Whenever you’re testing stuff, you are probably testing a class or set of classes. Setting up and destroying them on every test might be painful and this is what test fixtures are for.

A test fixture is a class that inherits from ::testing::Test and whose internal state is accessible to tests that use it. This is a critical distinction that might be a bit difficult to understand for users of frameworks in other languages. Essentially, instead of being part of the test fixture class, the tests related to a fixture are external. Yeah, it’s weird but that’s what we have.

A test fixture can define set-up and tear-down actions in either SetUp()/TearDown() or in the constructor and destructor. For example, if I want to test a BankAccount, my test fixture might appear as:

But the test fixture is not an actual test: it’s just rules for setting up and destroying objects that you need for testing. (Of course, we could have used a unique_ptr but I wanted to show a destructor, so there.) Anyways, the actual test now uses a TEST_F instead of the usual TEST, and its first argument is the fixture:

With ReSharper C++, you can run this test by pressing Alt+Enter and choosing Run:

Choosing this option causes the program to be compiled and the test executed. You can get a visual read-out on the state of your tests in the Unit Test Sessions window:

How Do I Test Lots of Data?

Data-driven tests? I’m glad you asked, because Google Test has something calledparameterized tests. Essentially, you can just set up a set of values and feed them all consecutively into a test. First of all, set up your structure for running the test:

The above is a statement of before-and-after states for a bank account. We are testing the process of withdrawing money. Oh, notice how I used R++ to generate the operator<< pretty-print: this is necessary because Google Test has no idea how to print account_state objects to the console… and we kind of need this for good-looking tests.

Now comes the tricky part: we want to reuse our previous BankAccountTest fixture but, at the same time we want to use account_state instances to initialize the balance. Here’s how it’s done:

The magic sauce here is in the WithParamInterface<> class as well as the GetParam() function, which yields the parameter being used in the current test case. Finally, we can write the test itself…

Notice the use of TEST_P here. The rest is pretty much the same: we get the test values withGetParam(), extract what we need, perform the test and check not one but two values. So finally, the icing on the cake is in us defining the test cases for this test. Using the magic of uniform initialization we can write it as follows:

When working with parameterized tests, you run them just as you would run a single test or a test based on a test fixture. The difference is in the output: each case takes up a separate line in the tree of test cases:

There’s More!

Google Test is a really big and comprehensive framework. Together with its sister, Google Mock, they provide ample possibilities for unit testing. Check out the advanced guide to find out more about sophisticated Google Test practices.

And here’s a video illustrating the story described above.

【本段视频非常有研究价值,即使对C++的构建英文名词来说也是不可多得的例子】

width="560" height="315" src="https://www.youtube.com/embed/16FI1-d2P4E" allowfullscreen="" frameborder="0" style="background: transparent; border-width: 0px; border-style: initial; margin: 0px; padding: 0px; vertical-align: baseline;">

Hey, did I mention that ReSharper C++ supports Google Test? Well, it does. So check it out if you haven’t already. ■

This entry was posted in ReSharper C++ Tips & Tricks and tagged google test, ReSharper C++, unit testing. Bookmark thepermalink.

16 Responses to Unit Testing C++ with Google Test

  1. Victor says:

    Another (easier) option to set up Google Test is to use the fused version which only requires adding one file, gtest-all.cc, to the build. Also you don’t have to implement main yourself, as gtest_main.cc already provides the implementation.

    Reply

    • Dmitri Nesteruk says:

      Thanks for the pointer!

      Reply

  2. Harry says:

    This seem to fail with visual studio 2015. It seem that nuget is doing something wrong.

    Reply

    • Harry says:

      I got it working by make a few compiler changes

      Reply

      • Ammar says:

        Can you please explain what changes are required and how, for visual studio 2015?

        Reply

      • Kel says:

        What changes did you make?

        Reply

      • Kaustubh says:

        Can you elaborate how you got it to work?

        Reply

        • Igor Akhmetov says:

          The easiest way is to make a fused version of Google test using the fuse_gtest_files.py script from Google test distrib, and to include the resulting source files into your project.

          Reply

  3. ddb says:

    gtest prints some important information to the console for failing cases e.g.:
    ASSERT_EQ(expected, value) << "this line will be printed to console, it includes some important info";

    1. gtest will print the expected value and the value that did not match
    2. gtest will print the text, after ASSERT macro that suppose to explain even better the failing case.

    My question is, where can I find the gtest console output, when using Resharper C++ unittest environment?
    thank you.

    Reply

    • Igor Akhmetov says:

      All test output is saved and should be accessible in the output pane of the “Unit Tests Sessions” window – just make sure that the pane is visible (there’s the “Show Output” toolbar button that controls visibility of the pane).

      There are a couple of known issues:
      1) Output of 64-bit executables is not logged while they are debugged.
      2) Output pane sometimes does not get properly updated between the runs (https://youtrack.jetbrains.com/issue/RSRP-447841) – we hope to fix this in ReSharper 10.

      If you still can’t see the output and the issue is not covered by one of the former cases, we’d love to know how to reproduce it – please create an issue on our tracker (https://youtrack.jetbrains.com/issues?q=%23RSCPP) with the required steps.

      Reply

  4. Guglielmo says:

    It seems that x64 is not supported, is it?

    Reply

    • Igor Akhmetov says:

      x64 binaries are supported with one caveat – after you debug some unit tests, their test status will be inconclusive as ReSharper C++ is not able to intercept the output of a x64 binary under debugger.

      Reply

  5. hung tran says:

    hi,
    I am trying to setup and do one simple unit test using GoogleTest but always struggling in Visual Studio.
    Do you have any reference to the fused version as far as setting it up .
    thank you

    Reply

    • Igor Akhmetov says:

      Hung, you have to run the googletest/scripts/fuse_gtest_files.py script from the Google test distribution to obtain the fused sources – then just add them to your solution.

      Reply

  6. Phil Miller says:

    Do you have plans to extend these capabilities to the Boost.Test framework or will this remain a google-test only capability?

    Reply

    • Igor Akhmetov says:

      Phil, ReSharper C++ 2016.1 added support for running tests written using the Boost.Test framework.

      Reply

[gtest][002] A quick start to build the Google C++ Testing project相关推荐

  1. [gtest][001] A quick introduction to the Google C++ Testing Framework

    前言:这是一篇非常好的介绍谷歌测试框架基本知识的文章.我们知道谷歌在提供开源的模块的时候,往往都附带提供了相应的测试案例.例如浏览器的移植工作,理解这些测试案例,比如unit test案例是很重要的事 ...

  2. the resource is not on the build path of a java project

    从svn里导出一个项目到本地eclipse里,但在代码中点击F3跳转时报错"The resource is not on the build path of a Java project&q ...

  3. the resource is not on the build path of a java project错误

    在eclipse中,使用mavenimport了一个工程,但是在对某一个类进行F3/F4/ctrl+alt+H操作的时候报错:"the resource is not on the buil ...

  4. 解决the resource is not on the build path of a java project

    场景 普通的Java project 转maven 项目后,导入类提示:the resource is not on the build path of a java project 解决方法 将检查 ...

  5. ecilpse导入项目后报错:Open the Java build path property page of project ‘chapter09‘

    ecilpse导入项目后报错:Open the Java build path property page of project 'chapter09' 这是因为要导入的项目的jdk 的版本跟你本地使 ...

  6. 启动项目报:Cannot determine build data storage root for project

    idea启动springboot项目报:Cannot determine build data storage root for project 翻译:无法确定项目的生成数据存储根 其实就是 你对这个 ...

  7. Errors occurred during the build. Errors running builder ‘Maven Project Builder‘ on project

    Errors occurred during the build. Errors running builder 'Maven Project Builder' 博客分类: 异常 前几天项目还好好的, ...

  8. (转) Quick Guide to Build a Recommendation Engine in Python

    本文转自:http://www.analyticsvidhya.com/blog/2016/06/quick-guide-build-recommendation-engine-python/ Int ...

  9. create your own github repository and build link to your local project

    1. create a repository in you github. i.e. repository name: spring5_exercise 2. initial git profile ...

最新文章

  1. Linux 用echo输出带特效的字体
  2. golang count 单字符 字符串 统计函数
  3. python 语言教程(3)数据类型
  4. HDU-不容易系列之(3)—— LELE的RPG难题
  5. POJ1390 Blocks——动态规划——pku1390
  6. 终端到服务器丢包,服务器丢包 ping的时候产生丢包的解决方法
  7. Spark出租车数据实验实用说明书
  8. 没有提取码 php云盘文件,最新百度网盘分享文件链接无需提取码的方法
  9. 图片自适应页面大小的简单HTML代码
  10. iframe标签用法详解
  11. 服务器2003ftp站点向导,Windows 2003 ftp 配置
  12. [网络工程师]-路由配置-OSPF配置
  13. 2021!四川省科学技术厅开展瞪羚企业申报条件材料
  14. 第2次作业:软件案例分析
  15. python密码游戏
  16. HDU 5148 Cities
  17. c语言窗口插件,C语言插件开发形式
  18. C语言创建函数案例:求长方体体积
  19. 科技前沿(1)-石墨烯 在中国、美国、英国、欧盟、韩国、日本的发展情况
  20. 基于Matlab的脑功能网络工具箱 BCT FCLab

热门文章

  1. 部署flas到服务器:No module named flask
  2. 【记录】Docker安装后出现 Cannot connect to the Docker daemon
  3. [Liunx]Linux安装screenfetch
  4. 【C语言】写一个函数,并调用该函数求两个整数的最大公约数和最小公倍数
  5. 【C语言】将两个字符串连接起来
  6. Oracle expdp impdp导出导入命令及数据库备份
  7. ddos常见攻击报文
  8. mac docker 共享_如何在Docker for Mac中加快共享文件访问
  9. snapchat_机器中的幽灵:Snapchat不是移动优先的-完全是另一回事
  10. 大数据自学——Spark