Using .dlls in my projects - c++

Hello,
Specs: VS 2010 C++ professional edition.
I have a project with some statistical functions that I want to test.
So I wrote a simple test console application which I added to the solution of the project with functions that I want to test.
Here is the detailed layout of my project:
Project BASE, contains classes with functions that are used in my statistical application called ROC. And then there is roc_test, simple console application that I want to use for testing of some functions in ROC application. Now, ROC is linked to BASE and roc_test has ROC as referenced project. My problem is that when I try to compile my test project roc_test, the compiler throws an error saying that my roc_test project is missing a .dll file that belongs to project BASE. roc_test however, is not directly linked to BASE. I don't understand why it throws such a message and how I can fix it. For the sake of clarity let me try to show the relationship in a different way.
roc_test function calls rocfit(..) function, which is part of ROC.h. ROC.h using functions that are written in DoubleMatrix.h, which is part of a BASE project.
I hope I am being clear.
P.S. There is no point in showing the code as the problem is not in the code but in the linker settings.
Thanks for any help.
EDIT: My question is how do i get rid of the error? Do I also need to link my test project to the BASE? It's just doesn't make sense that I have to do it. It should be enough to link it to ROC. Am I right?

If it's not included in the same directory as the console app (or in the path), then you'll need to include BASE as the runtime can't resolve the dependancy on BASE by ROC.
Edit: Simply referencing ROC isn't enough; although there may be some build option that builds ROC and BASE and then links them into a single DLL; that could be worth investigating.
Also, instead of using a Console application, you might find it better in the long run at using unit tests.
This msdn article explains how to use vs2010 test projects with C++:
http://msdn.microsoft.com/en-us/library/ms243171.aspx

Related

Visual Studio test project not finding main project

I created an empty C++ project in Visual Studio and added some code. Then following Microsoft's instructions I created a new Google Test project, selected "Add to solution" with my first project, and then in the next screen I selected the first project as the project under test.
I can get the main project to run, and I can get a test to run if it doesn't use my code. But I can't use my code in the tests.
Here is the current code that's trying to make its way to the test. You can also see in the explorer that the main project is indeed referenced in the test project.
But that is basically all I've done. I haven't played with any other settings anywhere at all. So don't assume I did something, or know something. Pretty n00by in these situations.
Thanks.
The error:
With regards to this being marked as a duplicate: while the question you've linked to does appear to make it clear that I have some sort of linker problem, there is so much information there -- over a dozen common causes -- that it doesn't actually help me answer my question, or at least not much more than telling me to, say, "read these 10 chapters of this C++ textbook". I would appreciate a response that points as close to "exactly" what I'm doing wrong as reasonably possible.

test a C++ dll function

I am trying to test a dll that was created in C++, specifically to test certain functions. A few search results gave the solution as testing in visual studio by creating a simple unit test and referencing the dll as a project. But the solution is not very clear to me and there is no way to add the dll to the unit test project, as the only options are projects, solution, shared projects. I don't even see the browse button.
Does anyone have a solution or could you explain this solution provided here? I just want to be able to call the dll function, from a C++ class or project to test the input & output.
test dll
It is pretty straight forward actually.
In the DLL project you can create a native Unit test project and write test methods.
Here is the link to clear steps with screenshots - https://learn.microsoft.com/en-us/visualstudio/test/writing-unit-tests-for-c-cpp.
Edit: I am assuming you have access to DLL code.

c++ testing herimitic library

I decided to add tests for my library.
The problem is that most (all?) of the test frameworks are using the same approach: build an executable file which contains code to be tested, tests and framework.
But what if I have a library which is heavy (a lot of code inside) but has only a few public functions / classes? In such situation I cannot test it well until:
I export all symbols from library
I build executable file with all library sources included
Ad. 1: it's not nice
Ad. 2: when I work with visual studio it would require me to synchronize library project with 'test' executrable project (adding/removing files etc). So it also doesn't look nice for me.
Are there any other approaches?
If you can do 2) so you should be able to reorganize your file/folder/project like;
1) a static library project containing all the internal function and object
2) a test project using any framework (there is a lot of framework with pro&con for each, my advice if you are beginner select the integrated solution or a simple framework). that test project must DEPEND (add dependcy in solution explorer menu) of the static lib. So you can add test on your internal implemtation
now the external api.
3) your old DLL project keep only the public API definition and implementation. And DEPEND of the static lib.
4) add a test project for your public api
No need to synchronize project and compile code twice, and with effort you could test more than just the external api without any internal code change.
Generally, test-driven programming works well with many and small "units". Having a few and bloated "units" makes the testing phase untolerable!
The only viable solution I see is to isolate specific parts of the code and then step into them with the debugger. Having many private functions usually leads to the aforementioned issue and since you can't access them directly during unit tests, you should really consider using the debugger for the non-obvious.

Is it possible to perform unit testing on dll's methods without an executable during build process?

I have 63 DLL's with various C++ methods in each. I want to validate the output of some of the methods with fixed input values. I'm wondering if it is possible to do unit testing in the DLL itself during compilation build process.
So, the compilation build of DLL gives the results of the Unit Testing in the Output window of Visual Studio.
I know that I can validate this scenario by creating executable file and calling the methods. But, is it possible without executable file?
As others have said - testing "during compilation" does not make sense, so I'm assuming you mean testing during the build process, which is different and of course possible using post build steps etc.
You don't specify which version of Visual Studio you use, but if you have VS2012, there is an MSDN article that describes exactly how to do what you describe. See the link for the full instructions, I've attached a partial screenshot below
Taking your question verbatim, the answer is "no", because you can't test a DLL when you haven't even finished compiling it. Also, you need some kind of executable to load that DLL, so either you load it with a scripting language (Python with ctypes comes to mind) or you create an executable.
Calling that from a post-compile step in Visual Studio, as suggested by shivakumar is probably the only way to get the results into the output window. I personally prefer running this from an external build script, but I'm also cross-compiling a lot and I can't run things from a post-compile step there. This also makes it easier to debug the unit tests when something fails.
You have to wait compilation to complete so that there are no compilation error in the code.
In the post-build event you can add batch files which will run your unit test modules and validate the binaries generated after compilation.
You are asking for a thing that does not make sense. When you say "compiling" that means a very specific thing: invoking the compiler, before invoking the linker. But C++ code (and C++ unit tests) do not work like that. The compiler must finish compiling both your production code and your tests, and the object files must then be linked into libraries, executables, or both. A test framework must then execute the test code which calls your production code in order to get results. None of these steps are optional in C++.
Instead, you probably intended to ask if you could run the unit tests as part of the build (not compile). And the answer to that is an emphatic "yes!"
I'm guessing that your solution is likely structured into 63 or more individual DLL projects. For each production DLL you are going to test, such as Foo.DLL, I recommend you add a new FooTest project, with the unit test code added to the FooTest project. In FooTest, create a project dependency upon the Foo project, which will force FooTest to build after building Foo. In the FooTest project you would have two kinds of code modules: classes containing your unit tests, and a FooTest.cpp that would house the main() entrypoint of the FooTest.EXE program, invoking the testing framework, and outputting the results to the console.
Create your FooTest.cpp so that it's a console program. If you format your test executable's output so that it matches the output of the Visual Studio compiler, as in "filename.cpp(lineNo) : error: description of failure", Visual Studio will automatically navigate to the file and line if you click on it. Unit test frameworks such as CppUnit may already have a "CompilerOutputter" class that will properly format the output to match your compiler's errors.
In your FooTest project, you also need to set the input to the FooTest linker so that it can link in the production code you are trying to test. In the properties of the FooTest project, go to the Linker/Input tab and add the path to your Foo project's OBJ files to the Additional Dependencies. The line I use looks like this: $(SolutionDir)Foo\Debug\obj*.obj
In the Build Events properties of the FooTest project, invoke your new FooTest.EXE as a post-build step. Then, every time you click build, your code will be built and your unit tests will be executed. The project dependency will ensure that if you change your Foo code, you will compile, link, and execute the FooTest tests. And the console output ensures that your test results will appear as clickable output in your IDE.
You could create 63 separate unit test executables, or you could create one all-encompassing unit test executable. That's entirely your choice. If you are looking to make the builds and links happen quicker, you will probably want to have the separate executables; even though it's a bit more individual configuration work, you do it only once, and after that you retain the benefits of quick builds for small changes.
Now you're ready to do some serious coding.

Unit Testing legacy C++ Code with CPPUnit

I am tasked with managing a large code base written in vc++ 6.0, I need to start building unit test for portions of the code. I have set up CPPUnit and it works with my projects DLL's the problem I am facing is as follows. The legacy application is made up of 10 static libraries and one huge executable MFC application that contains 99% of the code. My unit test framework is running in another project within the same workspace and will test the 10 libraries no problem all include and references are ok, when I try to do the same for the large MFC application I get a linker error as I do not have a dll for the application. Is there any way to unit test the application without putting the test code directly inside the application.
You should carry on as you are:
You have one test application that references libraries.
You have one main application that also references those libraries.
Either move code from the main application into the existing libraries, or, preferably, move code into new libraries. Then your test application can access more code without ever referring to the application.
You know when you are done when the source for the application consists of one module which defines main() and everything else in in libraries which are tested by the test application.
My experience with unit testing is usually the opposite. Create a project for your test then import code from your other projects.
You can't link to the MFC application probably because your functions aren't exported. They exist, but have no mean to communicate with other applications unlike DLLs.
I know of no way to link against an executable file. Refactoring the code by moving the business logic to a DLL and leaving the application as a "Front-end" would be the most obvious solution. However, since it is legacy code it is likely more appropriate to simply duplicate the code for purposes of unit testing. This is not ideal, and since it is an MFC applicaiton may not be trivially easy.
To test your main application you can set up a test project which includes the source files you want to test - not sure how easy it is to achieve with VC6, do not have it at hand, but in VS2005 and later this is quite straightforward.
So in your solution you end up with a structure like this:
MyLegacySystem.sln
MyApplication.proj
Main.cpp
BusinessRules.cpp
MyApplicationUnitTests.proj
UnitTestsMain.cpp
BusinessRules.cpp
BusinessRulesTests.cpp
If for whatever reason you cannot include your source files in 2 projects, you can pull the sources into your test project by invoking the preprocessor magic:
BusinessRulesStub.cpp:
#include "..\src\BusinessRules.cpp"
However, this is essentially a temporary fix. As already suggested, in the end most of the code should be extracted into separate libraries.
If you can't refactor your project to move the business logic into a new static library, try linking your test project against your project's intermediate object files, which you can probably find in BigProject\debug or BigProject\debug\obj . You can't link to the .EXE as you've discovered.
This achieves the same results as the copy process that Chad suggested while avoiding the actual duplication of source code, which would be a really bad thing.