I have a small test project with the following layout:
testmain.cc
Foo\
|--FooClass1_test.cc
|--FooClass2_test.cc
Bar\
|--BarClass1_test.cc
|--BarClass2_test.cc
In the *_test files I have defined tests along the lines of
TEST(Foo, foo_func1_works)
{
EXPECT_EQ(42, the_answer);
}
And testmain.cc contains only:
#include <gtest/gtest.h>
int main(int argc, char* argv[])
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
I can see that the TEST macros generate self-registering classes which RUN_ALL_TESTS will know about, but how is this code linked? Nothing references the tests defined in the .cc files, no includes etc. Why does the linker not throw this code away? I am compiling the project with MSVC 2010.
Related
I'm just learning c++. I have a main.cpp unit which has a lot of stuff in it already, and I just want to build a quick little testMain.cpp unit that will test a couple of things.
Basically I want to trick the compiler (xCode) into ignoring the real main function for a minute. I could
Rename the main() function inside main.cpp to mmain() temporarily.
Remove the reference to main.cpp in my project temporarily.
Comment out the main() method in main.cpp temporarily.
All these seem pretty clunky. There has to be an easier way. I suspect this is a common thing people do. How do you do it?
Another solution would be to separate the code into multiple files, have most of the logic in one file, have the real main in another and the test main in a third, you compile and link either the first and second or first and third files but never all three together.
Your option 2 is the most common strategie, and from my understanding also the cleanest.
After all, your test application will most likely not share the same command line interface, and that is usually about the only thing which should (of at all) be located in the main function or file.
If your main.cpp contains significantly more than just the entry point, you should immediately start thinking about how to distribute that logic into the modules you already have.
Use a macro.
Option 1: Use a macro to include/exclude entire files:
main.cpp:
#ifdef USE_REAL_MAIN
int main(int argc, char* argv[]) {
...
}
#endif
testMain.cpp
#ifdef USE_TEST_MAIN
int main(int argc, char* argv[]) {
...
}
#ENDIF
build file:
gcc -DUSE_REAL_MAIN
gcc -DUSE_TEST_MAIN
Option 2: Use a command-line macro to rename main:
main.cpp:
int realMain(int argc, char* argv[]) {
...
}
testMain.cpp
int testMain(int argc, char* argv[]) {
...
}
build file:
gcc -DrealMain=main
gcc -DtestMain=main
Note this is probably the least attractive option because it breaks the convention of macros having UPPER_CASE names and means the real entrypoint of your program is non-obvious to someone who hasn't seen the build script. It also means the program simply won't compile (as there's no main function) without your custom build script either.
Option 3: Have a new common main with the #ifdef directives instead:
main.cpp
#include "realMain.h"
#include "testMain.h"
int main(int argc, char* argv[]) {
#ifdef USE_TEST_MAIN
return testMain( argc, argv );
#else
return realMain( argc, argv );
#endif
}
build file:
gcc -DUSE_REAL_MAIN
gcc -DUSE_TEST_MAIN
I think this is my preferred option because it's almost self-documenting and makes it clear to another programmer how to get it to work without needing your custom build script.
I have a foo library in c++, and I am using gtest as testing framework.
I want to create testFoo executable which calls runTests which is defined in statically linked testFoo library which contains all tests for statically linked foo library.
I have created all that I am written, but google test shows me "Empty test suite."
testFooLib.h
int runTests(int argc, char* argv[]);
testFooLib.cpp
int runTests(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
If I put
TEST(Testing, someTest){
EXPECT_EQ(true, true);
}
in testFooLib.cpp, this test is found, but if I put it in some other cpp it will not be found.
testFooExecutable.h
#include "testFooLib.h"
int main(int argc, char** argv) {
return runTests(argc, argv);
}
I have some tests in project, I don't want to pollute my post with it...
update, I have put tests in code.
I have same problem as here important-note-for-visual-c-users.
Note: I have tried with clang, gcc and msvc and result is always the same.
Seems that by design GTest picks up only TEST() cases defined in the .exe project. Those from static library are ignored.
Check this configuration:
Build gtest lib as a static library.
Put tests in .cpp (TEST() macro, ...) into the project which creates the executable.
GTest initialization should be called from main in .exe project:
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
I am using Google test framework for C++. Each file includes a config.hpp which defined a global configuration variable. I would like to define my config in a variable, not a compile-time const or constexpr. How can I define the dependencies to have the same variable in different files that are linked together? Do I have to use a singleton? Can I avoid that? Is there a better recommended way to use multiple test files xUnit style?
My config file: config.hpp:
#pragma once
struct {
const float tolerance = 0.001;
// ...
} CONFIG_VAR;
Each test *.cpp source file is like:
#include "gtest/gtest.h"
#include "core/config.hpp"
TEST(a, b) { ... }
My main file:
#include "gtest/gtest.h"
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
I compile and link using:
em++ -I $GTEST_ROOT/googletest/include main_all_tests.cpp test_*.cpp
PS. My problem is multiple definition of the variable CONFIG_VAR.
My solution is based on a related question.
Everything you need is right here at the Google Test's official repository on GitHub.
Anyway, to sharing something in the same file test you do it like that:
class YourTestCase : public ::testing::Test
{
protected:
virtual void SetUp()
{
globalObject = new YourObject();
}
virtual void TearDown() {
delete globalObject;
globalObject = nullptr;
}
Object * globalObject = nullptr;
};
so, in your test cases:
TEST_F(YourTestCase, TestOne) {
ASSERT_EQ("your value here", globalObject->getValue());
}
TEST_F(YourTestCase, TestTwo) {
ASSERT_EQ("your value here", globalObject->getValue());
}
TEST_F(YourTestCase, TestThree) {
ASSERT_EQ("your value here", globalObject->getValue());
}
Note.: Pay attention to the function's name. It is TEST_F not TEST.
On the other hand, if what you want to do it is at the test program level ― sharing something among files, you will need to set up an environment object. Something like this:
Environment * AddGlobalTestEnvironment(Environment * env);
I have never worked with that before, so I can not tell you so much about it, but there is more information at that link I shared above. Usually, global variables make the code harder to read and may cause problems. You'd be better off avoiding them.
I want to learn using google test framework with everyday projects, so I looked up a few tutorials, but I have no idea how to get started.
I'm using Qtcreator in Ubuntu 14.04, I downloaded gtest.zip from the google site and unzipped it, but here is where it all stoped.
This is the code i want to "gtest":
//main.cpp
#include <iostream>
#include <cstdlib>
#include "fib.h"
using namespace std;
int main(int argc, char *argv[])
{
int n = atof(argv[1]);
fib fibnumber;
cout << "\nDesired number is: " << fibnumber.fibRec(n) << endl;
}
//fib.h
#ifndef FIB_H
#define FIB_H
class fib
{
public:
int fibRec(int n);
};
#endif // FIB_H
//fib.cpp
#include "fib.h"
int fib::fibRec(int n)
{
if(n <= 0) return 0;
if(n == 1) return 1;
else return(fibRec(n-1)+fibRec(n-2));
}
So where do i even begin, I want to make unit test and compile it without any plugins, but i don't know how to make use of the file I unzipped and then use it to write a unit test.
The google Testing framework works by building it as part of your source code. That means there is no library that you have to link to, instead you build the library when you compile your code (there is a good reason for this).
Have a look at the official documentation:
https://github.com/google/googletest/blob/master/googletest/docs/primer.md
Steps
Try to build a test testcase for your program. I can't tell you how to do it with Qtcreator but that should be easy enough to find. Create a test that will definitely fail, like the one below.
TEST(MyFirstTest, ThisTestShallFail) {
EXPECT_EQ(1, 2);
}
Run this very simple test to check that it fails. If you want, change it to make it pass.
Start creating your unit tests. Check for a few easy number. Check boundary conditions etc.
In addition to #Unapiedra's suggestions, I would suggest to write a separate test file and a separate source/implementation file to test the code with google test framework and link the project using a build system or better a build generator system.
My example below demonstrates this using a cmake build generator. (My assumption here is that the user is familiar with cmake)
Note: although in practice it is recommended to write code incrementally using the Test Driven Development philosophy, I don't do it since the purpose here is to show how a simple unit test can be written and compiled using google test framework.
charOperations.hpp
#ifndef CHAR_OPERATIONS_H
#define CHAR_OPERATIONS_H
#incude <string>
class CharOperations{
private :
// ...
public:
//converts lower case characters to upper case
// and returns a std::string object from this
std::string convertToUpper(const char letter){
char upCase = std::toupper(static_cast<unsigned char>(letter));
return std::string(1, upCase);
}
//converts upper case characters to lower case
// and returns a std::string object from this
std::string convertToLower(const char letter){
char loCase = std::tolower(static_cast<unsigned char>(letter));
return std::string(1, loCase);
}
// more functions ...
};
#endif //class definition ends
test_example.cpp
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "CharOperations.hpp"
//declare a test fixture so that the object
// CharOperation need not be declared in each test
//Each test fixture has to be publicly derived from
// testing::Test
class CharOperationsTest : public testing::Test{
//class object public so that it is accessible
//within the tests that are written
public:
CharOperations charOps;
};
// now write the tests using macro TEST_F
// which is used for testing with test fixtures
//1st parameter to TEST_F is the name of the fixture
//second parameter to TEST_F is the name of the test
//each test has to have a unique name.
//test #1
TEST_F(CharOperationsTest, ConvertsCharToUpperCaseString){
ASSERT_THAT(charOps.convertToUpper('a') testing::Eq("A");
}
//test #2
TEST_F(CharOperationsTest, ConvertsCharToLowerCaseString){
ASSERT_THAT(charOps.convertToLower('A') testing::Eq("a");
}
//more tests ...
//run all tests
int main(int argc, char **argv){
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.2.3)
project(TDD CXX)
enable_testing()
set(CMAKE_CXX_STANDARD 11)
find_package(PkgConfig REQUIRED)
pkg_check_modules(gtest REQUIRED gtest>=1.8.1)
pkg_check_modules(gmock REQUIRED gmock>=1.8.1)
include_directories(${gtest_INCLUDE_DIRS})
include_directories(${gmock_INCLUDE_DIRS})
add_executable(test.out ##target executable name
test_example.cpp
)
target_link_libraries(test.out ${gtest_LIBRARIES})
A general suggestion for writing tests: It can be observed in the file test_example.cpp, the Macros/Functions Test. Eq and InitGoogleTests reside under the namespace testing. Hence it might be prudent to declare a using namespace testing declaration at the beginning of the file after all #includes. Lastly needles to say to compile in a separate build directory
when using the Google Test Framework I can have the following code compile, despite there being barewords undefined symbols passed as arguments to TEST.
#include <gtest/gtest.h>
TEST(faketestfixture,faketestname){
ASSERT_EQ(1,1);
}
int main(int argc, char** argv){
testing::InitGoogleTest(&argc,argv);
return RUN_ALL_TESTS();
}
Why/how does this compile? What magic are they using?
I began to peek around the source, but quickly realized I was out of my depth and don't even know where to start.
TEST is a preprocessor macro, and its areguments are not identifiers, the TEST macro just uses them as building blocks to generate code. In this case it generates the class called faketestfixture_faketestname_Test with the method called TestBody. The actual body of that method is what you supply in curly brackets after the TEST macro invocation. So the generated code looks approximately this way:
class faketestfixture_faketestname_Test : public testing::Test {
public:
void TestBody();
// ... more stuff ...
}
void faketestfixture_faketestname_Test::TestBody() {
// This is the test body you supplied.
ASSERT_EQ(1,1);
}
So that's relatively simple. The real magic is in how it all is hooked together and invoked. :-)