I have a solution with two projects in it
One of them is a console application, and the other one is a Google Test project
My project has a .h file and a .CPP with a main() in it
My gtest consists of a .CPP file which calls the .h file using #include and a main function to RUN_ALL_TESTS()
I need a main in my project but I also need a main in the gtest project, but having two main() doesn't let me build the gtest successfully
Is there a workaround to this?
Sorry if it's a silly question, I have no clue how to use gtest because various sites keep presenting different ways
First of all you should have a dedicated file main.cpp for your main() function, which contains nothing else.
E.g. your project structure could look like:
project1
file1.h
file1.cpp
main.cpp
I'm not familiar wiht gtest specifically, but usually unit test frameworks have a separate file for the gtest main function, e.g. gtest_main.cpp. Tests are in one or more files like file1test.cpp etc.
So you would compile and link your project1 with file1.h, file1.cpp and main.cpp to get an executable.
For unit tests you would compile and link file1.h, file1.cpp, file1test.cpp and gtest_main.cpp for a unit test executable.
Structure could be like
project1
file1.h
file1.cpp
main.cpp
project1test
file1test.cpp
gtest_main.cpp
EDIT additional infos on linking:
In project1test you would include file1.h with #include "../project1/file1.h".
For correct linking right-click on project1test project
--> Configuration Properties --> Linker --> Input --> Additional Dependencies --> Add "..\project1\Debug\file1.obj"
As #Alan Birtles pointed out it would be even more clearer if you had the following structure:
project1library
file1.h
file1.cpp
project1application
main.cpp
project1test
file1test.cpp
gtest_main.cpp
The you would get a static/dynamic library project1library.lib/.dll, an executable project1application.exe and a unit test executable project1test.exe.
The advantage is that you would just link the library in your unit test project with
--> Configuration Properties --> Linker --> Input --> Additional Dependencies --> Add "..\project1library\Debug\project1library.lib"
If you have more than one file you need from your project, you don't have to add every obj file, but just one lib file.
But making sure that everything was rebuilt correctly on changes can be more difficult and error prone with a lib, an executable and a unit test project.
Standart usage of gtest is for unit testing.
Usually, unit tests don't check main :).
I recommend you to use standart gtest main function (don't define custom main function). it allows you to use command line to filter running tests.
If you don't want to use gtest main, IMHO, you shouldn't include gtest_main library.
I used macros for this problem. I have defined a TESTING macro which evaluates to true when compiling the unit tests and otherwise to false:
#ifndef TESTING
// the source main
int main() {
...
}
#endif // !TESTING
You can also use this later for "test" code in your sources. What I do sometimes (not good design IMO):
class Klass:
#ifdef TESTING
friend class KlassUnitTestClass; // allows access to private members in my google test unit class. Disabled when i build sources
#endif // !TESTING
Related
I am using CMake 3.16.
I add my source files to my target with target_sources(). I would like later in my CMakeLists.txt to remove a source file I previously added with target_sources().
For example:
target_sources(my_target PRIVATE main.c abc.c def.c ghi.c)
# Later...
# Remove def.c from the previously added source files.
Is there a way to do this ideally without setting a custom "sources" variable and removing it from this list with list(REMOVE_ITEM ...)?
EDIT:
The context of this question is unit testing static functions in C.
My program is made of a lot of static functions that I want to unit test. To test them, I decided to include the .c file in the test files instead of the .h.
For example:
abc.c:
#include "abc.h"
// several static functions defined here
abc.h:
// some stuff
test_abc.c:
#include "unity.h" // a unit test framework
#include "abc.c" // notice the .c instead of the .h to be able to test the static functions
// the test functions
By doing this, I need to remove in CMake the xxx.c file if I add the test_xxx.c file because otherwise the content of the xxx.c file will be defined 2 times and the linker will not be happy with it.
You can set the source file property HEADER_FILE_ONLY to ON on the source file in question. See also set_source_files_properties().
Since CMake version 3.18, you can also do this if the source file belongs to a target defined in a different directory:
set_source_files_properties(subdir/source.c TARGET_DIRECTORY target-from-subdir PROPERTIES HEADER_FILE_ONLY ON)
I have two projects. One called projectA and the other called projectA-tests.
The first project is my actual project, and the second project contains GoogleTest unit tests for classes in projectA.
I have coded one very simple unit test so far and everything builds OK. Note that this first simple test depends on a single .h file of projectA that has only a static class method defined in the same .h file (no .cpp file). It's actually a "StringUtils" class with methods like ::startsWith() and so on.
After adding a second test I'm having linking problems. This second test depends con a Class of projectA that is declared in a .h file and defined in a .cpp file. I'm getting an undefined reference regarding this Class, trying to build this second test.
projectA-tests compiler settings are configured to include projectA/src in project -> properties -> C/C++ build -> settings -> C++ compiler -> includes. (I guess this is why the first compiles ok, because it only requires a .h file which is covered by this "includes" setting).
What I don't know is how to configure the C++ linker in projectA-test to include all .o files of projectA in the linkage process.
I'm more experienced in Java, and the equivalent would be simply adding the other project source folder as dependency of the build path. Whay is Eclipse CDT's C++ equivalent?
Thanks!
I have a Visual Studio solution organised like this:
ProjectA // A static library I'm working on
ProjectB // A static library containing UnitTest++ test suites for ProjectA
ProjectC // An executable test runner which links to ProjectA and ProjectB
ProjectB contains two files which look like this:
// RunTests.h
#ifndef RUNTESTS_H
#define RUNTESTS_H
#include "UnitTest++.h"
int runAllTests();
#endif
and this:
// RunTests.cpp
#include "RunTests.h"
int runAllTests()
{
return UnitTest::RunAllTests();
}
As well as several files containing test suites e.g.:
// FooTests.cpp
#include "RunTests.h" //
#include "Foo.h" // From ProjectA
TEST(SomeTest)
{
CHECK(true);
}
ProjectC consists of a single file:
// main.cpp
#include "RunTests.h" // from ProjectB
int main()
{
return runAllTests();
}
The reason I have the tests and the test runner separated, is that I have another project which uses the same tests to analyse code coverage, which I need to keep separate as it is not cross-platform, whereas the test runner is.
The issue is, that when I compile and run ProjectC, no tests are actually run (UnitTest++ runs, but with zero tests). This is because ProjectC does not reference any symbols relating to the tests from ProjectB, so the linker doesn't link the object files from ProjectB.lib.
It is my understanding that if ProjectB was an executable, I would not have this issue (presumably because the linker would link all the object files), as per the documentation:
The general idea is that you keep one Main.cpp file with the
entry-point which calls RunAllTests().
Then you can simply compile and link new .cpp files at will, typically
one per test suite.
Each of the Test*.cpp files will contain one or more TEST macro incantations with the associated
test code. There are no source-level dependencies between Main.cpp and
Test*.cpp, as the TEST macro handles the registration and setup
necessary for RunAllTests() to find all tests compiled into the same
final executable.
How can I resolve this problem without having to declare all the tests in header files that ProjectC can see (which would kill UnitTest++'s ease of use)? One possibility I've noticed in Visual Studio is:
Project Settings > Configuration Properties > Linker > Input > Force Symbol References
However it would be rather tedious to have to add every single symbol, every time I write a new unit test. Is there some way I can force it to include the entire contents of ProjectB.lib? Or perhaps some code-based solution?
EDIT: What I'm looking for is something like this but for Visual Studio.
I was trying to use UnitTest++ the same way you've described and ran into the same problem. I ran across a suggestion in another forum that seems to work for my unittest executable (i.e. ProjectC).
For ProjectC:
Project Settings > Common Properties > (select ProjectB) > Use Library Dependency Inputs: True
This worked for me. I think what this does is effectively link any object files from ProjectB into ProjectC (as opposed to linking the library).
I have a project of 50+ .H/.CPP files/classes. I would like to test every class with its own test case, which will include methods for testing of different aspects of every class. My classes are located in different directories, like this:
/project
/include
/SuperModule
Foo.h
Foo.cpp
..
Alpha.h
Alpha.cpp
..
/test // I assume that my tests shall be here
main.cpp
Makefile
I would like to use boost::test as a unit-testing framework. How should I organize my files, how shall I name them, etc. Some hint or a link or a suggestion will be appreciated. Thanks.
We are using boost::test in a similar layout. Our layout is -
/project
/include
/SuperModule
/Foo
foo.c
foo.h
/foo_unittest
foo_unittest.c // note - no separate header file is required
// for boost::test unit test.exe program.
Basic layout rule is to put the unit test for a class in a sub-directory named "foo_unittest" after the class in the same directory as the source code. The advantage to this naming is
The source code and the directory are stored next to each other. So by simple inspection you can see if you have written the unit test or not.
Also, when you copy the source code,
it is easy to copy the unit test at
the same time.
As our projects are not overly complex (30-50 major classes), this system works for us. If you are running larger projects, I don't think this would be an optimal solution.
Is there any way to easily test C++ classes in java way.
In java you can add static function main and run it directly from IDE
class Foo{
...
public static void main(String args[])
{
System.out.println("Test class foo here");
}
}
is it possible to do it in Visual C++ ?
Of course you can create another project, but it is bad solution(you sould create project, and then add it to solution or run another copy of Visual Studio)
Another way is to modify main() function, or CWinApp::InitInstance() but if you change file
Foo.h, VS will rebuild all files from project, depending on it (we just want to test Foo.h & Foo.cpp)
The best way i founded is to create another project (console), add Foo.h and Foo.cpp to it, add public static function run() to my class Foo and run it from main() function in console project like this
//unitTester.cpp
include "Foo.h"
int main(...){
Foo::run();
return 0;
}
in such way i can test my class Foo separately (without recompiling the big project)
When I feel like writing unit tests, I usually add another project that links in the test code + the classes being tested. The test code I write using the Boost Test Library, which nicely integrates with Visual Studio. I make my actual project dependent on the test project. The test project runs its executable as a post-build step. Therefore, as long as the tests fail, I cannot even build the main project.
The workaround I use is to use a #define to decide what mode the app is in.
I usually have a def.h file, which would have
#define TEST
Then on the main file you write,
#ifdef TEST
// test code
#else
// main code
#endif
This condition check can be done in several places too if for testing you need to change things in several places. If this testing code needs changes in several files also, all you have to do is to include def.h in those source files.
Hope this helps
Use the Boost Test Library. If your application has a GUI, its a littlebit difficult to integrate, but once it works, its quite simple and straightforward to write tests.