Unit testing non-exported classes in a DLL

心已入冬 提交于 2020-06-24 02:59:07

问题


We develop a C++ application using Visual Studio 2008 and unit test using Boost.Test. At the moment, we have a separate solution which contains our unit tests.

Many of our projects in the core solution produce DLL's. We're limited in test coverage because we cannot test non-exported classes.

I have two ideas on how these could be tested:

  1. Export everything
  2. Put the tests inside the DLL (same project and solution) and use Boost.Test's external runner

I'm not entirely sure what the drawbacks would be. Number 1 above breaks module level encapsulation, and number 2 could result in a much larger DLL, unless it's possible to only include the test code in certain configurations.

So, are there any severe drawbacks to the above methods, or can you think of other solutions?


回答1:


Expanding on Tom Quarendon's answer to this question, I have used a slight variant of Simon Steele's response:

  • Create a test project (using whatever test framework you like, I use CppUnit).
  • In your test_case.cpp, #include <header/in/source/project.h>.
  • In the test project properties:
    • In Linker->General, add the source project's $(IntDir) to the Additional Library Directories.
    • In Linker->Input, add the .obj files to the Additional Dependencies.
  • Add the dependency from the test project to the source project in Project->Project Dependencies.

Again, the only maintenance overhead is the standard one for unit tests - to create the dependency on the unit(s) you want to test.




回答2:


The solution I use for this is to build the same non-exported code into my tests DLL as well. This does increase build time and means adding everything to both projects, but saves exporting everything or putting the tests in the main product code.

Another posibility would be to compile the non-exported code into a lib which is used by both the DLL with exports, and the unit test project.




回答3:


Was searching a solution as well, maybe the following will be easier to maintain.

Add a new build configuration e.g. "Unit testing Debug" to the DLL project and change the Configuration Type to be "Static Library .lib" ("General"->"Configuration Type").

Then just add a dependency of your unit tests on this project, now everything should link together when you use new build configuration "Unit testing Debug". If you are using release builds for unit tests then you need to add another configuration with release optimizations.

So the benefits of this solution are:

  • low maintanability cost
  • single DLL/Static library project
  • don't have to manually link to .obj files

Drawbacks:

  • Extra configuration profile(s) will require some changes in your build environment (CI)
  • Greater compilation times

Update: We actually ended up using a different approach.

We added new "Test debug"/"Test release' configurations for every existing project that we have.

For .exe/.dll projects we disable the original main.cpp from compiling and replaced it with the one that instantiates the test framework (e.g. gtest) and runs all the tests, the tests are in separate .cpp files which are also excluded from compilation in regular configurations (Release/Debug) and enabled only in Test configurations.

For .lib projects we also have new "Test debug"/"Test release" configurations and there we convert the static library to be an .exe file and provide a main.cpp which instantiates the testing framework and runs the tests and tests themselves. Test related files are excluded from compilation on Release/Debug configurations.




回答4:


Try making a define such as the following somewhere all files will include:

#define EXPORTTESTING __declspec(dllexport)

And use it in place of the dllexport, like this:

class EXPORTTESTING Foo 
{
 ...
};

Then you will be able to turn off the flag for building a release DLL, but keep it on for a unit-testable DLL.



来源:https://stackoverflow.com/questions/5496912/unit-testing-non-exported-classes-in-a-dll

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!