GoogleTest run_all_tests not finding test fixtures - c++

I have a C++ project that is going to be made up of only google tests. This project references another project (the project it is testing). I have a include and source folder for the header and implementation files. I am creating google test fixtures classes and split the header and implementation into the include and source folders. I have a main.cpp that contains the following code:
//main.cpp
#include "../inc/zeroEstimatorTest.h"
#include "gtest/gtest.h"
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
The problem I am having is that the RUN_ALL_TESTS() call is not calling my google test fixture. The test fixture is located in the implementation of the test class. It looks like this:
//zeroEstimatorTest.cpp
class zeroEstimatorTest : public ::testing:Test
{
...
};
TEST_F(zeroEstimatorTest, zeroTest)
{
...
}
The project builds and runs but the output is the following:
[0;32m[==========] [mRunning 0 tests from 0 test cases.
[0;32m[==========] [m0 tests from 0 test cases ran. (0 ms total)
[0;32m[ PASSED ] [m0 tests.
I am currently using Eclipse (for the first time) and I am on a Linux 64 machine.
Things I have done:
The zeroEstimatorTest class includes the "zeroEstimatorTest.h" at the top.
The #include "gtest/gtest.h" is at the top of all three files (main.cpp, zeroEstimatorTest.h, and zeroEstimatorTest.cpp)
Can anyone help?
Thank you very much!

The problem is that you're not setting the tests filter name try initializing google test with --gtest_filter= it can be done using the main function parameters . 

Related

C++Builder11: How to unit test with googletest?

Until recently I've used C++Builder 10.2 for a project, and I had begun to use DUnitX to add some unit tests for the project.
Now I have upgraded to C++Builder 11.2, and found that DunitX is no longer supported for C++Builder when using this version. Instead, Embarcadero recommends to use DUnit or Googletest.
On further research, it seems that Googletest cannot be used with the classic compiler (but I'm not actually interested in using the pre-C++11 classic compiler), but also that DUnit cannot be used when targeting the Firemonkey framework, and that DUnit (1) is unmaintained and (2) does not work well with the Clang-based compiler.
I'm interested in using googletest because I have already used both, googletest and googlemock, on less niche platforms than C++Builder such as Linux/GCC, Apple/Clang and Windows/MinGW-w64. I am aware that the googletest project itself refuses to accept build files or patches for C++Builder because they do not want to spend effort to support niche compilers (see e.g. here, here, and here).
I'm happy to learn that some patched version of googletest is currently available for C++Builder through the GetIt package manager, even though it is not clear who has actually made that patch, and although I realize that Embarcadero may remove googletest from the GetIt package manager an any moment.
I've found two blog posts explaining how to install googletest in C++Builder and how to use it, however, I cannot successfully follow the second blog post when it comes to point 6, which reads
In your project group create a new windows64 bit VCL console application. Set this to use the debug settings (this allows you to debug code that doesn’t pass a unit test).As well as the files you want to test and the files containing the testing code you need to add to the project the library file …GT2021.09\cbuilder\lib\Win64\Debug\gtest.a.
I'm not sure how I am supposed to "add to the project the library file". I've tried to
copy the gtest.a and gmock.a files into the project directory and then
right-click on the project name in the "Projects" view of the IDE and select "Add...", then change file type to "static libraries", then select gtest.a and repeat with gmock.a.
Here I've gone ahead and have already added gmock.a because I have experience with googlemock and envision that its additional matchers and mock class generators will help me writing tests.
When I compile a simple test project that does not actually perform any tests, everything compiles and links fine, but when I execute the resulting command line program, then it fails with exit code (errorlevel) -1073741819 and produces no output. This does not happen if I comment all usages of googletest out.
The simple test project which fails during execution consists only of
#include <gtest/gtest.h>
#include <vcl.h>
#include <tchar.h>
int _tmain(int argc, _TCHAR* argv[])
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
which should cause googletest to print that 0 tests were executed, but instead it crashes as described. When replacing the two lines in main with a simple printf, which does not use googletest, but leaving all includes unaltered and without altering the project with regard to libraries, it works fine (the new printf prints something) but of course cannot perform any tests.
How to fix this?
One more observation: When adding the static libraries to the project as described above, I get a notification message box from the IDE, saying "One or multiple lines were too long and have been truncated". I have no idea how this message could make sense with regard to adding a static library to the project. It seems however, that this is not an error, and the linker actually uses the static libraries when linking.
The main problem here was the inclusion of the gmock.a library as it was compiled by the GetIt googletest package. This gmock project and basically all other gmock projects in the GetIt package are broken and need to be repaired before using them. I may post more details about this in a future topic. The gmock.cbproj project as distributed by GetIt, e.g., includes the unrelated source file googletest\samples\sample8_unittest.cc, among other errors.
A simple method to use googletest with C++Builder 11.2, which is based on the blog posts by Cigol, but which does not require to copy include files and library files:
When installing googletest with the getit package manager, the IDE automatically opens a group project Googletest.groupproj and compiles two of the contained projects (gtest and gtest_main) for the Windows 64 bit platform in "Release" mode. Furthermore, all other project files in the Googletest project group are modified probably because they have been updated from an earlier C++Builder version and want to be saved when closing the IDE.
There is no need to compile googletest in "Debug" mode, one would need that only for debugging the unit testing framework itself.
Next, create a new VCL Windows 64 bit console application to start using googletest:
File -> New -> "Console Application - C++Builder"
Source Type: C++, Target Framework: Visual Component Library, [OK]
Add Target Platform Windows 64-Bit in the "Projects" view (right-click on Target Platforms).
Delete Target Platform Windows 32-Bit.
Save all in a dedicated directory:
File -> Save All
Create a new folder, e.g. MyUnitTests.
Place project file as e.g. MyUnitTests.cbproj into that folder.
Rename File1.cpp to MyTestsMain.cpp and store in that folder
This creates a C++ source file MyTestsMain.cpp with some includes and an empty main function:
#include <vcl.h>
#include <tchar.h>
int _tmain(int argc, _TCHAR* argv[])
{
}
For convenience, googletest provides a library gtest_main.a which only contains a main function that one can use to execute all unit tests compiled into an executable. By linking against the gtest_main.a library, users can avoid writing their own main function and concentrate on only writing test code. But since the C++Builder wizard has already created a main function, one can as well fill the generated main function with the necessary boilerplate code (only two lines are required, compare against the googletest main function in C:\Users\yourLogin\Documents\Embarcadero\Studio\22.0\CatalogRepository\GoogleTest-2021.09\googletest\src\gtest_main.cc) and add the gtest.h include directive:
#include <gtest/gtest.h>
#include <vcl.h>
#include <tchar.h>
int _tmain(int argc, _TCHAR* argv[])
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Trying to build this project fails because the gtest/gtest.h include file is not found. This can be fixed in Project -> "Options..." -> Building -> C++ Shared Options -> "Include path": After selecting "All configurations - All platforms" in the drop-down list "Target", add the following entry to "Include path":
$(BDSCatalogRepository)\GoogleTest-2021.09\googletest\include
Using the variable $(BDSCatalogRepository) avoids machine- and developer-specific absolute PATHs. Save the changed project settings with File -> "Save all". Trying again to build this project now fails because of different errors, which is progress! The errors now are "Unresolved external"s, which means we have to tell the project to link against gtest.a and where to find it. Linking against gtest.a can be done by adding a pragma to the top of the file containing the main function:
#pragma comment(lib,"gtest")
#include <gtest/gtest.h>
#include <vcl.h>
#include <tchar.h>
int _tmain(int argc, _TCHAR* argv[])
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Where to find the library can be configured in Project -> "Options..." -> Building -> C++ Shared Options -> "Library path": Again first select "All configurations - All Platforms", then add the following entry to "Library path":
$(BDSCatalogRepository)\GoogleTest-2021.09\cbuilder\lib\$(Platform)\Release
After File -> "Save All", a new, clean build generates different "Unresolved external"s, progress! This time, symbols from the standard C++ library are missing, which can be fixed via Project -> "Options..." -> Building -> C++ Linker, again for Target "All configurations - All platforms", check the checkbox "Link with Dynamic RTL, Windows...". After another File -> "Save All", a clean build succeeds and executing the generated Win64\Debug\MyUnitTests.exe generates this output:
[==========] Running 0 tests from 0 test suites.
[==========] 0 tests from 0 test suites ran. (0 ms total)
[ PASSED ] 0 tests.
One can now add tests to the test project. Tests can be added to the source file which contains the main function or to different, topic-specific source files. I'll add two tests in new files for demonstration:
In the "Projects" view, right click on the current project, which is confusingly named "MyUnitTest.exe" in the project view with an ".exe" extension instead of a project file extension, then select "Add new..." -> Unit in the popup menu. "Unit" here is C++Builder's language for a pair of one source and one header file, and is not necessarily related to unit testing.
The new files are initially named "Unit1.cpp" and "Unit1.h" but can be renamed when doing File -> "Save All". I name this first test file to "SelfContainedTest.cpp" because its test will be self-contained. Add the following code to the .cpp file after the IDE-Generated boilerplate:
#include <gtest/gtest.h>
TEST(SelfContained, Addition) {
EXPECT_EQ(3, 1+2);
EXPECT_GT(3, 2+2);
}
Rebuilding succeeds, execution reveals that the second EXPECT fails as it should, the number 3 is in fact not greater than the sum 2+2. Fix if you like.
In a second test, I want to test non-GUI methods of an existing VCL form. In a real-world scenario, the GUI project and my test project would be part of the same project group and live in the same directory or below the same parent directory, and I would add the VCL form's .cpp file also to the test project with (Project View) -> right click -> "Add..." -> C++Builder unit (*.cpp). My form TAdderForm that I'm using here is a simple form with two VCL TEdit fields for entering numbers and a VCL TLabel to display the sum of the two numbers. The sum is computed in a method
int TAdderForm::add(int num1, int num2)
{
return num1 + num2;
}
which I want to test here. To write the test, I add a new "Unit" to the test project as before, naming the source file "VCLTest.cpp" this time. After the IDE-generated boilerplate, I add this code to the .cpp file:
#include "adderFormx.h"
#include <gtest/gtest.h>
TEST(VCL, Addition) {
// Have to instantiate VCL form before calling its method.
Application->CreateForm(__classid(TAdderForm), &AdderForm);
EXPECT_EQ(3, AdderForm->add(1,2));
EXPECT_GT(3, AdderForm->add(2,2));
delete AdderForm; // Delete no longer used form.
AdderForm = nullptr; // clear pointer, another test may allocate new instance
}
This is basically the same test as before. The second expectation will fail again and needs to be fixed because 3>4 is a wrong expectation. The test uses the global instance pointer "AdderForm" from the form's source file for simplicity, this can be modified if required. If multiple tests want to instantiate the same form, a fixture should be used and the setup and teardown done here inside the test should be moved to the fixture's respective methods, but this is no longer C++Builder specific.
Note that Application->Run() is never called, and no GUI elements actually appear on the screen when executing the tests. I'm restricting tests to non-GUI methods of the GUI classes.

How can I make catch2 run tests that reside in a static library?

My usual workflow with catch2 is to have a single console application that contains all the test cases and the tests 'runner'.
For example:
file1.cpp, file2.cpp contains tests:
#include <catch2/catch.hpp>
TEST_CASE("test", "[test]")
{
CHECK(true);
}
A single file main.cpp would contain the runner code:
#define CATCH_CONFIG_RUNNER
#include <catch2/catch.hpp>
int main(int argc, char* argv[])
{
return Catch::Session().run(argc, argv); // run tests
}
In order to reduce compilation time, I tried to move all files containing the tests (file1, file2 etc) to a separate static library project (Visual Studio).
But after doing this, catch fails to find any test cases:
catch main started..
Filters: [test]
===============================================================================
No tests ran
I tried putting the runner code inside a function that resides inside the static library, but that didn't help.
Questions:
How exactly does catch finds its test cases?
Why is this failing?
How can I fix it?

Where to put implementation when using Doctest alongside code

I'm using doctest for the tests in my C++ project.
I would like to put the test code alongside my implementations, as the library says is possible, but I can't seem to figure out what to do with the doctest implementation code.
I have a doctest.cpp file that looks like this:
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest.h"
A main.cpp that looks like this:
#include "thing.h"
int main(int argc, const char *argv[]) {
do_thing();
}
thing.h is self-explanatory, but thing.cpp looks like this:
do_thing() {}
TEST_CASE("Test thing") {
CHECK(1 == 1);
}
CMake is used to create two executables, a Tests executable and a Main executable.
If I don't include doctest.cpp in my project sources for Main, I get undefined reference errors because it can't find a definition for all the testing stuff in doctest.
However, if I do include it I get errors because there are multiple main() functions in one target.
I can't find any info on this in the doctest documentation.
How are you meant to get around this?
The author of the library gave a good response in this issue:
DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN implements the test runner and also defines a main() function.
DOCTEST_CONFIG_IMPLEMENT implements ONLY the test runner.
If you define your own main() then you should use DOCTEST_CONFIG_IMPLEMENT - have a look at the relevant docs.
You will need the test runner implemented in your main executable (that means doctest.cpp) since you are writing your tests alongside your production code.
You can also define DOCTEST_CONFIG_DISABLE when building the main executable so tests are written in the production code but aren't compiled (you will still need doctest.cpp so it all links). This way you won't need to #ifdef the tests.
You could also entirely remove the test executable and use the main executable for running the tests - docs.
I went with the first option of writing my own main() function.
I encountered the same problem and one workaround is to add -DDOCTEST_CONFIG_DISABLE to the compiler flags when you compile Main.

GoogleTest: main() in different lib -> test cases not found

I have various executable projects in my VS solution that contain various GoogleTest cases. I tried to reduce the code by having a separate .lib project that contains nothing more than the main() function and GoogleTest's initialization code. I could then link this into all the exe projects that contain the actual tests:
So:
---main.cpp in static lib project TESTMAIN---
#include <gtest/gtest.h>
int main(int argc, char* argv[])
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
And
---accounttest.cpp in exe project TESTACCOUNT
#include <gtest/gtest.h>
struct BankAccount
{
int m_iBalance;
BankAccount(){}
};
TEST(AccountTests, BankAccountStartsEmpty)
{
BankAccount account;
EXPECT_EQ(0, account.m_iBalance);
}
However, when running TESTACCOUNT.exe, the unit tests are not picked up:
Running main() from gmock_main.cc
[==========] Running 0 tests from 0 test cases.
[==========] 0 tests from 0 test cases ran. (0 ms total)
[ PASSED ] 0 tests.
When explicitly adding a main() (with gtest init code) to my exe project, it does work. My hunch is that it has to do with the linker, but I am not exactly sure why this isn't working. I still would like to avoid adding a main+init to all my test projects..
Any suggestions on good ways to doing this would be really appreciated.
Ben
As #David and #Michal Walenciak noted, it worked by linking to gtest_main. In the end, I think I didn't need to link to a static lib, but to a DLL.

Linking google test to your main project

I am new to the gtest. I have followed a tutorial how to set it up in the VS 2105.
But all that I could find talked about how to build and link gtest.
I am passed that level. The code below runs and passes the first dummy test.
#include "gtest/gtest.h"
TEST(VI, simple) {
EXPECT_EQ(false, false);
}
int main(int argc, char* argv[]) {
testing::InitGoogleTest(&argc, argv);
RUN_ALL_TESTS();
std::cin.get();
return 0;
}
My question:
How do I exactly hook it up to my project that I want to test?
Both gtest project and my "code" project are in the same solution.
As far as I understood from reading numerous tutorials, I need 2 things:
1) to include my .h of the class I am about to test (easy and done)
2) To compile my "code" project into a static lib and then hook up
the lib to gtest project so I can create and test objects from the
"code" project.
I am struggling with the point 2. How exactly do I go about it?
Thank you for help in advance.
Add a new empty Win32 project to your solution, in its properties select Project Type "static library (.lib)"
Move all your sources except the main() function to that project
Add a reference to the .lib project to both your main application project and the google test project