Getting started learning how to use GTest in Visual Studio 2022

Pages: 12
Hi all,

I'm starting to learn how to use Google Test (GTest) on my VS 2022 IDE for a simple project called test with this code:

1
2
3
4
5
6
7
int main()
{
    int number;
    std::cin >> number;
    std::cout << number * 2 << '\n';
    return 0;
}


My first question is that, do I necessarily need to create a header, and a .cpp file for the project to be able to use it for GTest, please?
Last edited on
No, you don't have to.

But it is generally a good idea to keep the unit tests separate from the production code. So, usually, you will write the test code in a separate source code file. This separate source code file then, of course, needs to #include the header file(s) where the functions and/or classes to be tested are declared.

Think of a structure like:
1
2
3
src/MyClass.h           <-- class to be tested is declared here
src/MyClass.cpp         <-- the actual implementation of the class is here
test/MyClassTests.cpp   <-- your unit tests for that class go here
Last edited on
From a meta-search "visual studio google test tutorial":
https://duckduckgo.com/?q=visual+studio+google+test+tutorial&t=ffsb&ia=web

How to use Google Test for C++ - Visual Studio (Windows)
https://docs.microsoft.com/en-us/visualstudio/test/how-to-use-google-test-for-cpp

Get started with unit testing - Visual Studio (Windows)
https://docs.microsoft.com/en-us/visualstudio/test/getting-started-with-unit-testing

(There are other links that could be helpful.)
Thank you both @kigar64551 and George P. Let's get started with the second link above.
But before that, please note that I already have a console application (https://docs.microsoft.com/en-us/cpp/build/vscpp-step-1-create?view=msvc-170) named MathFib.cpp with this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <vector>

int Fibonacci(int n)  // Returns the factorial of n
{
    std::vector<int> fibVec{ 0,1 };
    while (n-- > 2)
        fibVec.push_back(fibVec[fibVec.size() - 2] + fibVec[fibVec.size() - 1]);

    return fibVec[fibVec.size() - 1];
}

int main()
{
    std::cout << Fibonacci(8) << '\n';

    system("pause");
    return 0;
}


for which I'm going to create a Google Test project named MathTest using @George's second link. In the Test Project Configuration dialog, I chose MathFib as the project I want to test. In the test.cpp (the .cpp file of the MathTest directory/project) there're a few lines of code written by default.
This is the view of my projects up to this point: https://imgur.com/a/p5rH5gu

1) Have I gone through the process correctly up to now?
2) Is it time to add a header file (or project) to the Solution Explorer?
Last edited on
Again, this is not a must, just a good practice:

Create a source file "fibonacci.cpp" and put your Fibonacci implementation there:
1
2
3
4
5
6
7
8
9
10
11
#include "fibonacci.h"
#include <vector>

int Fibonacci(int n)  // Returns the factorial of n
{
    std::vector<int> fibVec{ 0,1 };
    while (n-- > 2)
        fibVec.push_back(fibVec[fibVec.size() - 2] + fibVec[fibVec.size() - 1]);

    return fibVec[fibVec.size() - 1];
}

Also create a corresponding header file "fibonacci.h" with the proper declaration:
(I also recommend adding proper "include guards")
1
2
3
4
5
6
#ifndef _INC_FIBONACCI_H
#define _INC_FIBONACCI_H

int Fibonacci(int n);

#endif //_INC_FIBONACCI_H 


Wherever in your project you need to call the Fibonacci function, you can now simply do this:
1
2
3
4
5
6
7
8
#include "fibonacci.h"

int main()
{
    std::cout << Fibonacci(8) << '\n';
    system("pause");
    return 0;
}


Unit tests written with GTest (e.g."fibonacci_tests.cpp") would then look something like this:
1
2
3
4
5
6
7
#include "gtest/gtest.h"
#include "fibonacci.h"

TEST(myTest, myFibonacciTest)
{
    EXPECT_EQ(/*expected result here*/, Fibonacci(8));	
}
Last edited on
Thank you so much for your description. Only an issue remains!
So we should have four files, not three! I mean:
One header file, e.g., fibonacci.h, which contains the declaration of the function for test.
One .cpp file, e.g., fibonacci.cpp, which contains the definition of the function for test.
One .cpp file, e.g., main.cpp, which contains the code to run the project and call the function.
One .cpp file, e.g., fibonacci_tests.cpp which contains the tests for the function.
Right?

Can't we combine the second file with the third one (the first code with the third one in your post above)?

You can do whatever you deem feasible for your project :-)

But, in general, I would recommend to keep a re-usable code unit, like your Fibonacci function, separate from the main() function. Also, generally, we expect that foo.cpp contains the implementation of the functions or classes that are declared in foo.h. It would seem a bit odd to find unrelated code, such as a main() function in foo.cpp. So, using a separate main.cpp for your main() function is much more common...

Then again, you can have everything in just a single "program.cpp" file. Probably not a good idea, with respect to readability and maintainability, though. Especially when your project will grow...
Last edited on
Got it, thank you.One last question.
Should we create a separate project for each of the four files: fibonacci.h, fibonacci.cpp, main.cpp and fibonacci_tests.cpp?
As you know each project contains some folders in Solution Explorer, say, Header Files, Resource Files and etc. Can I create only two projects: one for the program and another for testing it?
This way the first project contains main.cpp, fibonacci.h and fibonacci.cpp and then the new project fibonacci_tests.cpp in a separate project includes the header. If it's possible this way the projects will be very nice and the whole pack look coherent I guess.
You do not need to create separate projects. But it is possible. And sometimes makes sense.

For example, you could create a project "core library" as a static library or DLL, which contains just the re-usable code, such as your Fibonacci function. Then you can make a separate "front-end" project, as an EXE file, which contains the main() function and calls functions from your "core library" project.

Your GTest unit tests could be yet another separate project.

But, be aware that, in such a setup, you have to correctly configure the dependencies between your projects! In the above example, the "front-end" and "GTest" projects depend on the "core library" project.

Note: Refactoring "shared" (re-usable) code into a separate project (static library or DLL) mostly makes sense, if you actually intend to use that code in more than just one project!
Last edited on
For this simple situation, you could probably get away with 2 projects.

1. The "real" program containing the fibonacci files as well as main.cpp.
2. The GTest program, containing links to the fibonacci files. (I don't generally do this, but I'm pretty sure it can be done.)


In the industry, however, we generally put related code into libraries. Each library would be its own project. For this more industrial solution, you would have 3 projects.

1. The foo library (for fibonacci.h and fibonacci.c)
2. The "main" project for you main.cpp, which links in the fibonacci library
3. Your GT test code, which also links in the fibonacci library

I would encourage you to use the 3-project approach to get used to the idea of creating and using libraries, because that will help you down the road.
Thank you. OK, I will go for the 3-project approach. But just a simple question. What do you mean by linking in this sense, please?
2. The "main" project for you main.cpp, which links in the fibonacci library. 3. Your GT test code, which also links in the fibonacci library
I guess you mean to include the header file in both the main and GTest projects. Right?
Last edited on
Suppose you have a "core library" project containing the Fibonacci function that is built as a shared library (.lib) file. And you have a "front-end" (main) project that is built as an EXE file and that wants to call the Fibonacci function from the "core library". You will have to link the "core library" into the "front-end" executable!

That is something different from #include'ing the header file: The header file just provides the declarations to the C/C++ compiler, but you have to link the actual implementation too!

...otherwise you are going to see linker errors, complaining about unresolved external symbols ;-)
Last edited on
Here is a full example:
https://www.mediafire.com/file/71hrb1vbavp0619/sample-project.zip/file

Be aware of the project dependencies, which cause Visual Studio the link the library into the main project:
https://i.imgur.com/FEE7zGX.png
Last edited on
When I thought I was done with the process, "linking" turned up at the final posts to mess the whole thing up and I don't know what to do now!
If the 3-project approach is commoner and popular:
1. The foo library (for fibonacci.h and fibonacci.c)
2. The "main" project for you main.cpp, which links in the fibonacci library
3. Your GT test code, which also links in the fibonacci library
how to do linking, please?
how to do linking, please?

Did you look at the example I posted above? And the screenshot ???

(If you set up the dependencies between your projects correctly, then Visual Studio will take care of the linking automatically; in addition to that, you can also configure which libraries to link explicitly)

See also:
https://i.imgur.com/RK81yu1.png
Last edited on
In VS, make sure that fibonacci is being built as a library.
In the "main" program, add fibonacci in the "References" portion of you project. Then recompile that project and see if you get the final program.
Do the same with the GT project.

frek wrote:
What do you mean by linking in this sense, please?


Linking is just a normal step in the creation of an executable. First, the compiler compiles your source code files into object files - usually, named something like *.o or *.obj. Then, the linker links the object files, and any library files, into an executable.

Usually, this is all done automatically by whatever you're using to compile, e.g. Visual Studio.

Surely this isn't the first time in over 3 years of C++ coding that you've encountered the concept of linking?
Created a project called Fibonacci with 3 files: a header,
1
2
#pragma once
int Fibonacci(int n);


a source file,
1
2
3
4
5
6
7
8
9
10
11
#include "fibonacci.h"
#include <vector>

int Fibonacci(int n)  // Returns the factorial of n
{
    std::vector<int> fibVec{ 0,1 };
    while (n-- > 2)
        fibVec.push_back(fibVec[fibVec.size() - 2] + fibVec[fibVec.size() - 1]);

    return fibVec[fibVec.size() - 1];
}


and a main.cpp to call the function.

1
2
3
4
5
6
7
8
9
#include "fibonacci.h"
#include <iostream>

int main()
{
    std::cout << Fibonacci(8) << '\n';
    system("pause");
    return 0;
}


It works.
Then created a Google Test project (selected the first project as the one for testing):
https://imgur.com/GK4xUTb

After these ran "All Tests" and seemingly successful.
https://imgur.com/V7EqOcY

Right up to this point?
Pages: 12