How to test an EXE with Google Test?

c++, googletest

Solution

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.

Problem

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.

Original source

Related problems