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.
Related
I have a C++ project in Visual Studio, and have added another project exclusively for testing. Both of these projects are EXEs (console apps). So how do I use the first project inside the second?
Just to clarify, the question here would be somewhat self-evident if the first project was a library that one could simply include in the second project but, being an EXE, this is where the problem lies.
Per your comments, you have a C++ console application (MyApp) for which you have developed some application-specific classes that you want to unit-test with googletest in
Visual Studio. How?
As you say, if you wanted to unit-test a library the way to do it would be
obvious. You would:
1) Create a project to create a unit-testing application (UnitTest).
2) Configure the include-search directories so that the compiler can find the library's headers.
3) Configure the library-search directories so that the linker can find the library itself.
4) Add the library itself to the linker inputs.
5) Make the UnitTest project dependent on the library project, so that building UnitTest ensures MyApp is up-to-date.
6) Code the UnitTest app per googletest docs.
But since the classes you want to unit-test are specific to MyApp, you don't have any
library.
A drill-sergeant answer to that is: You don't have a library containing the classes you want to unit-test? So make one!
That way you use 3 projects:-
MyAppLib, generating library that contains all the functionality you want to unit-test.
MyApp, generating the same executable as at present, but linking MyAppLib
UnitTest, generating an executable that unit-tests MyAppLib, also linking MyAppLib
However if you don't like the drill-sergeant answer you can work around it.
From the usual build-system point of view (the one designed into Visual Studio),
the important output of the MyApp project is the build-target - the .exe.
The .obj files generated are just intermediate by-products. VS offers you no support
for treating these by-products as automatic linker inputs of a dependent project, and if a dependent project was also an .exe of the same sort - as it is your case - then such automatic linkage would be impossible anyhow because the main entry point would be multiply defined.
But from the unit-testing point of view it's the other way round. The .exe is of no interest, whereas (some of) the .obj files wholly or partly contain the implementations of the classes you want to unit test. In the text-book case where class foo is defined in foo.h and implemented in foo.cpp, the object file foo.obj is needed in the linkage of UnitTest.
For simplicity, assume that MyApp employs just one application-specific class foo,
defined in foo.h and implemented in foo.cpp. Then you have two options for building UnitTest.
a) You can add foo.cpp to the source files of UnitTest. Don't copy it of course. Just Add an existing item from the source folder of MyApp. Then you're done, but this
course has the downside that foo.cpp is exposed to untoward editing within
the UnitTest project.
b) You can treat foo.obj just like a static library required for the linkage of UnitTest and follow steps 1) - 6) above. This means in particular at step 3) that the {Debug|Release} build of UnitTest is configured with library-search directories that include \path\to\MyApp\{Debug|Release} (either in relative or absolute form).
In reality, for option b), there's very likely more than one .obj file from MyApp that you will have to link in UnitTest, and quite likely that their number will grow with time. Maintaining the right linkage of UnitTest could become a chore, and you might come to the conclusion that the drill-sergeant was right after all.
Depends. Google Test is (primarily) a Unit Testing framework (oversimplifying, testing classes). You can absolutely use is for other types of tests, but it doesn't have "built in" functionality for other types of testing, you'll have to write it yourself.
If you are trying to system test your executable, than you can run the process. I suggest using Boost.Process if you are using a multi-platform system or already have a boost dependency. Else, look here: launch an exe/process with stdin stdout and stderr?
The "tests" you write will call the executable, and can input stdin or stdout accordingly.
For example:
std::string path_to_exectuable = "thepath";
TEST(FooTester,CheckHelpScriptReturns0)
{
using bp =::boost::process;
std::vector<std::string> args; args.push_back("--help");
bp::context ctx;
ctx.stdout_behavior = bp::capture_stream();
bp::child c = bp::launch(exec, args, ctx);
bp::status s = c.wait();
ASSERT_TRUE(s.exited())<<"process didn't exit!";
ASSERT_EQ(s.exit_status(),0)<<"Help didn't return 0";
}
I was in a similar situation and I set this up in a way that effectively accomplishes the same goal of Mike Kinghan's answer as far as the compiler is concerned, but goes about it a different way from the user's perspective.
What I did was create a custom Configuration that I called "Testing". You create a new configuration by opening the project settings, choosing "Configuration Manager..." and selecting "New..." in the configuration selection box.
When prompted, I chose to copy the settings from the default "Debug" configuration, so that I can use the debugger with my tests just the same as if I was in the "Debug" configuration.
Under the new Testing configuration, I set the options for the compiler and linker to use google test as you normally would.
The important change in the properties is that I define a preprocessor variable which I have called "TESTING".
I rewrote my "main.cpp" to look something like this:
...
// includes
// functions
// whatever
...
#ifdef TESTING
#include <gtest/gtest.h>
#endif
int main(int argc, char **argv) {
#ifdef TESTING
::testing::InitGoogleTest(&argc, argv);
int val = RUN_ALL_TESTS();
getchar(); // not necessary, but keeps the console open
return val;
#endif
// rest of main() as normal...
}
What I'm trying to indicate is that I only changed a few lines right around where main is defined, I don't have to make gross changes spread throughout the file.
Now that this is all set up I simply made a new source folder for my tests, and create ".cpp" files in there. To avoid bloating the normal executable, I wrap these files with a check for the TESTING variable, so I have something like this:
tests/Test.cpp:
#ifdef TESTING
#include <gtest/gtest.h>
#include "my_class_header.h"
TEST(TestMyClass, test_something) {
// perform some test on class
}
#endif
I think these files still get "hit" by the compiler under Debug and Release configurations, so having a ton of these might slow down the build, but the Debug and Release objects wont get bloated with testing code.
The two takeaways are:
Using this method, the testing code is still organized separately from the application code, but it still resides in the same Visual Studio project, which may or may not be beneficial. Personally I like not having to manage/worry about a second project.
Like Mike Kinghan said, managing and linking .obj files yourself can become a chore, but by using this method, the default Visual Studio settings manage this for you.
One downside is that effectively redundant copies of all object files will get created in the "Testing" output directory. With more configuration, surely there must be a way to "share" the Debug object files, but I didn't have a reason to go that far.
This is a very simple method which may be a lot easier than refactoring your application into separate libraries and a main. I don't love using preprocessor wankery, but in this case it's fairly straightforward, not too much code bloat, and accomplishes exactly what it needs to. You could always trigger the tests another way, without using the preprocessor.
If you are not very rigid about having the tests in a different project, you can write the tests in your application project. Then just make the application execute the tests when receiving certain command line arguments, and execute the normal application logic otherwise, i.e.
int main(int argc, char* argv[])
{
if (argc >= 2 && std::string(argv[1]) == "--tests")
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
else
{
// Application logic goes here
}
}
TEST(ExampleTests, TestSQRTCalculation) // assuming all the right headers are included
{
EXPECT_NEAR(2.0, std::sqrt(4.0), 0.000001);
}
This avoids creating an unnecessary library for the sole purpose of testing, although you can still do it if it is correct structure-wise. The downside is that the testing code goes into the executable you are going to release. If you don't want that I guess you need an additional configuration which specifies a pre-processor directive to disable the tests.
Debugging the tests or running them automatically at post build is easy, simply by specifying "--tests" as debug args or at post build command line respectively.
If you want to test a console app you can run a test that opens a console window and run the exe file of the first app.
Then in your googletest catch the standard output from the exe you just ran.
[For more control over the first app you might need to have the first app parse arguments sent to it, e.g. some flags like -x or what ever you need.]
I have prepared a github repo including Visual Studio 2015 solution in parralel of Mike's "drill-sergeant" suggestion. You can use it directly without any additional requirement or dependency.
https://github.com/fuatcoskun/GoogleTestVS2015
I hope it helps...
I have a basic question regarding Googletest in Eclipse.
I am using the test-runner plug in to run the Googletests.
But I need to specify a binary which runs my unit tests (of course that makes sense.)
The problem is that in my project I now have two main functions, one to run the actual program and one
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
to run the google tests.
Each time I want to run one I comment the other out, which of course is stupid.
But what practice do you use to handle this situation?
Googletest C++ is a unit-testing framework. That means it is intended for testing
implementations of C++ APIs. It isn't intended for testing programs.
For practical purposes a C++ API is what you get in a C++ header file. The
implementation of such an an API might be:
Just the header file itself. (The implementation is entirely inline)
The header file plus a single C++ source file
The header file plus a bunch of C++ source files
To generalize, the implementation of a C++ API is a header file plus
0 or more source files.
Say your program my_prog invokes an API that you or your team have developed
for managing gizmos. The implementation is something like:
gizmo.h
[gizmo_0.cpp,...gizmo_N.cpp]
where [...] means optionally ...
Maybe my_prog relies on other APIs for which you or your team are responsible,
but we'll stick with just one. my_prog uses the gizmo API by:-
Using #include "gizmo.h" in some source files.
Compiling the [gizmo_0.cpp,...gizmo_N.cpp] source files, if any.
Linking the [gizmo_0.o,...gizmo_N.o] object files, if any.
(gizmo_0.obj, etc. if you're on Windows)
Testing your implementation of the gizmo API with Googletest is supposed
to confirm that this implementation is correct, independently of my_prog
or any other program that relies on it to manage gizmos. So incorporating
the unit-testing of the implementation in the implementation of my_prog is misguided:-
Maybe your colleague writes another program that also needs to manage gizmos
with this implementation. Maybe you write another one. Is whoever writes this
other program supposed to repeat the process of incorporating gizmo unit-tests
into it - The same ones? Different ones? - and making the program conditionally
compile as either a gizmo test-harness or as whatever it's supposed to be in real life?
And how do you know that the gizmo implementation isn't somehow entangled with
functionality that's unique to my_prog, or with the implementation of some
other API that my_prog uses in the same way - so that when you or somebody
else tries to reuse it in another program, it breaks or behaves wrongly?
No program that relies on this gizmo implementation is the place to put
its unit-testing. Making my_prog conditionally compile different main functions so it can
double as a unit-test harness for your gizmo library is similar to cutting a hole in the
crotch of your jeans for your head to fit through.
The way you're supposed to unit-test the gizmo library is to write a program that is the
test-harness for this library, and nothing else. This program, say gizmo_test, will
use the gizmo API in just the same way as any other program would use it, but
for the sole purpose of testing the gizmo library. All that gizmo_test will do is execute tests
of the gizmo library, by invoking its API.
As a first approximation, the GoogleTest recipe for gizmo_test is:
Write a header file, gizmo_test.h
#include "gizmo.h" in it
#include <gtest/gtest.h> in it
Then write your Googletest test cases in it
Write the following source file gizmo_test.cpp
#include "gizmo_test.h"
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Create a project gizmo_test - in Eclipse or whatever development environment or build system you use -
that builds the gizmo_test executable by:
Compiling the source files gizmo_test.cpp + [gizmo_0.cpp,...gizmo_N.cpp]
Linking the resulting object files gizmo_test.o + [gizmo_0.o,...gizmo_N.o], plus libgtest and any other libraries on which your gizmo library depends
You have two projects. The one that makes my_prog and the one that makes gizmo_test. In your development environment or
build system, make the build of my_prog depend on the build of gizmo_test, so that when you change anything that affects
the gizmo library and rebuild my_prog, gizmo_test gets rebuilt first.
That's a first approximation. Did you notice a while back that I started talking about your gizmo library? That's what
you've got (or should have). In C++ and programming generally, the implementation of an an API is called a library.
And maybe you also noticed some fragility, inconvenience and wastage in the recipe for gizmo_test. You have the same set of gizmo source files
[gizmo_0.cpp,...gizmo_N.cpp] in both projects. So you might edit, compile and link them differently in two projects. And they'll get compiled in both projects, either differently,
which is wrong, or identically, which is pointless.
Of course if this set of source files is empty - the gizmo library is nothing but gizmo.h - there's no such problem. But if it's not empty,
there is.
As you know, in C++ we don't use a library by building its source files in every program that uses it - not unless it's a header-only library.
A library is built by itself into an object library (either static or dynamic), and to use it a program just includes the library's
header file(s) and links the object library.
That's how a program should use your gizmo library too. So to the final approximation:-
Make a project libgizmo that builds a gizmo object library (static or dynamic, as you see fit).
Make a project gizmo_test as above, except that instead of compiling and linking [gizmo_0.cpp,...gizmo_N.cpp], it just links libgizmo, and make this project
depend on the libgizmo project.
Make a project my_prog as you have it now, but instead of compiling and linking [gizmo_0.cpp,...gizmo_N.cpp], just link libgizmo, and make this project
depend on the gizmo_test project.
So you have three projects by the time you build the first program that uses the gizmo library. Each subsequent program that uses the gizmo library needs one
more project, like the my_prog project.
Googletest is designed for testing C++ libraries, and this is how you're supposed to use it.
Now I know nothing about your program or how you are currently deploying Googletest test cases in your project. Maybe there aren't any well-defined API implementations in it
that those test cases are supposed to exercise, that you can factor out into free-standing libraries. Possibly that could be because your program is so very simple that
unit-testing its "components" is non-applicable, and you'd be wiser just to write blackbox tests of the program. More likely it would be because you've so far failed
to design a program architecture that is capable of being unit-tested. If that's what you find, you need to fix it, and then apply Googletest the right way. It will be worth the
effort.
And in case it needs pointed out, unit-tests are not program tests, so as well as unit-testing any libraries your program relies on, if they are your responsibility, you also need blackbox tests of your program.
Indeed a valid question. I believe that Mike Kinghan's detailed response explains how you should use google-test but nothing is set in stone and in the end, you can use google-test in any way you want.
So, since I actually encountered a similar situation, what I did was rather simple.
I modified the production file source code so that the main function will change from this:
void main(void)
to this:
#ifndef TDD_ENABLED // TDD_ENABLED is defined only in the unit test project
void main(void)
#else
void main_app(void)
#endif
this way when you are running unit tests, the original 'main' function is converted to 'main_app' and you avoid conflicts with the 'main' of google test. When you are running the original production code project, the 'main_app' function is named again 'main' as it should. So, technically, from your production code perspective, nothing has changed.
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).
After a day of banging my head against the wall both literally and metaphorically, I plead for help:
I have an unmanaged C++ project, which is compiled as a DLL. Let's call it CPP Project. It currently works in an unmanaged environment. In addition, I have created a WPF project, that shall be called WPF Project. This project is a simple and currently almost empty project. It contains a single window and I want it to use code from Project 1. For that, I have created a CLR C++ project, which shall be called Interop Project and is also compiled as a DLL.
For simplicity I will attach some basic testing code I have boiled down to the basics.
CPP Project has the following two testing files:
tester.h
#pragma once
extern "C" class __declspec(dllexport) NativeTester
{
public:
void NativeTest();
};
tester.cpp
#include "tester.h"
void NativeTester::NativeTest()
{
int i = 0;
}
Interop Project has the following file:
InteropLib.h
#pragma once
#include <tester.h>
using namespace System;
namespace InteropLib {
public ref class InteropProject
{
public:
static void Test()
{
NativeTester nativeTester;
nativeTester.NativeTest();
}
};
}
Lastly, WPF Project has a single window refrencing Interop Project:
MainWindow.xaml.cs
using System;
using System.Windows;
using InteropLib;
namespace AppGUI
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
InteropProject.Test();
}
}
}
And the XAML itself has an empty window (default created).
Once I am trying to run the WPF project, I get the following error:
System.Windows.Markup.XamlParseException: 'The invocation of the constructor on type 'AppGUI.MainWindow' that matches the specified binding constraints threw an exception.' Line number '3' and line position '9'. ---> System.IO.FileNotFoundException: Could not load file or assembly 'InteropLib.dll' or one of its dependencies. The specified module could not be found.
at AppGUI.MainWindow..ctor()
Interestingly enough, if I do not export the class from CPP Project, I do not get this error. Say, if i change tester.h to:
#pragma once
class NativeTester
{
public:
void NativeTest()
{
int i = 0;
}
};
However, in this case I cannot use my more complex classes. If I move my implementation to a cpp file like before, I get unresolved linkage errors due to my not exporting my code. The C++ code I want to actually use is large and has many classes and is object oriented, so I can't just move all my implementation to the h files.
Please help me understand this horrific error I've been trying resolve without success.
Thanks.
This went wrong right from the start, your tester.h file is not correct. The class should only have the __declspec(dllexport) attribute when you are building the tester project. Any other project that uses the DLL must see the class with the __declspec(dllimport) attribute. Start fixing this by using a macro in tester.h:
#undef EXPORTED
#ifdef BUILDING_DLL
# define EXPORTED __declspec(dllexport)
#else
# define EXPORTED __declspec(dllimport)
#endif
class EXPORTED NativeTester {
// etc..
};
And in your tester project, use C/C++, Preprocessor, Preprocessor Definitions and add BUILDING_DLL.
Next thing is to make sure that the DLL is being stored in the right directory. Which is what the exception is complaining about, it can't find the DLL. The build directory for C++ projects is Debug but for WPF projects it is bin\Debug. Fix that by changing the General + Output Directory setting, make it $(SolutionDir)$bin\(ConfigurationName).
Build the C++ project and verify that you can find the DLL back in the Solution's bin\Debug directory. And check that you also have the .lib file, you'll need that when you build the C++/CLI project. As an extra verification step, run Dumpbin.exe /exports foo.dll from the Visual Studio Command Prompt and check that you indeed see the class getting exported.
The C++/CLI project next, you need to change the Output Directory setting the same way. Add the .lib file to the linker's Additional Dependencies properties. You'll get the kind of linker errors you were talking about if you skip that step. Build it and verify that you get the DLL in the correct bin\Debug directory again.
Repeat these changes for the Release configuration.
Set the project dependencies, the WPF project depends on the C++/CLI project. The C++/CLI project depends on the C++ project. This ensures the projects are getting built in the right order.
You should now have a good shot at using these DLLs in your WPF project.
I used to have a static library which was imported by both my main program and my tests. However, I needed global variables inside of my static library to be constructed, and there's no way to force Visual Studio to do that.
What I'd like to do then is to have a project which compiles all the common C++ files, a project which compiles and links the unit tests (with the common C++ files), and a project which links the actual application.
How can I do this in Visual Studio 2010?
EDIT: Because clarification has been asked, here's what I mean:
InterfaceIUse.hpp
#include <memory>
struct IInterface
{
virtual ~IInterface() {}
virtual void SomethingIDependOn() = 0;
};
std::auto_ptr<IInterface> FactoryMethod();
CodeUnderTest.cpp
#include "InterfaceIUse.hpp"
void FunctionUnderTest()
{
//Blah blah blah
}
IExistOnlyInTheMainProgram.cpp
#include "InterfaceIUse.hpp"
std::auto_ptr<IInterface> FactoryMethod()
{
//I return the real implementation of the interface.
}
IExistOnlyInTheTest.cpp
#include "InterfaceIUse.hpp"
std::auto_ptr<IInterface> FactoryMethod()
{
//I return the mock implementation of the interface.
}
The idea is to compile the right .cpp implementation of the given factory, which will allow the dependencies of the code to be tested to be dependency injected.
Doing this kind of link seam is easy with makefiles -- but makefiles are undesirable because I'm forced to manually maintain header dependencies in the makefile.
I have done similar setup in VS2008, which I think still applicable for you in VS2010.
To start, I setup my project hierarchy as Build, ProductionCodeBase and TestCodeBase.
Common interface/headers are extracted into folder accessible by all projects.
Then in my "Build" project, I manually add object file(s) from ProductionCodeBase into "Release" configuration, and object file(s) from TestCodeBase into "Debug" configuration.
Don't forget to set project dependencies so that object file are valid when linking in "Build".
Do note that you can create project that only compile source code into object files without attempt to link them. Just go to "Tool Build Order" for that particular project and disable corresponding linker.