Unit Testing in C++

Started by
19 comments, last by Washu 12 years, 2 months ago
Umm... Am I wrong in thinking that unit testing, in it's simplest, doesn't require a huge unit testing software suite to generate and run the tests for you? I know that kind of software would be necessary in production of a large system with many parts utilizing many languages, but if you're only using C++ on a small project, whats wrong with writing your own test functions and running tests in the same process before executing your actual program?
Advertisement

Umm... Am I wrong in thinking that unit testing, in it's simplest, doesn't require a huge unit testing software suite to generate and run the tests for you? I know that kind of software would be necessary in production of a large system with many parts utilizing many languages, but if you're only using C++ on a small project, whats wrong with writing your own test functions and running tests in the same process before executing your actual program?


That is correct, and it is how the current xUnit libraries evolved.

People who had done it frequently just consolidated much of the reusable bits into a library, and also created fancy test runners that let you pick and choose subsets of the test, prettify the results, and make it easier to interpret.


Even with those libraries you are writing your own test functions, outputting events for success or failure (along with the reason for the failure), and then running the tests. Some tools can help automate the creation of function prototypes, but don't know how you intended to use the code. Using either route, using a library of tools or doing it yourself, the work of writing the tests remains, and it is significant.
So far we have established that the functionality exists in a convoluted form and there is no rapid implementation available, there is perhaps no benefit from implementing boost tests in order to check values are equal. I might aswell completely write out my own function for each method which just runs every function and identifies the outputs validity completely from scratch. In fact that is exactly what I will have to do. I was only reiterating exactly what MSDN had told me in relation to the lack of plausibility for unit testing unmanaged code, I even had a reference pointing to something which implictly stated that unmanaged code and unit tests were not going to fly.

To clarify I do not want someone to do anything in my project for me, I find that particularly insulting I am (well was/am) concerned/insulted by the poor quality of support for what should be a normal functionality in any language when reflecting on the ease of functionality provided for basically all other languages in all APIs. I never used the terminology "doomed" although I am in a squeeze and while I am aware that unit testing is usually something you would perform as you develop it would easily over double the development time for this project because as my understanding of the components I am modifying has evolved so has the architecture I have used in an Agile fashion.

It is inefficient to start with debugging when your doing something that is going to evolve and go through essentially paradigm shifts. A prime example is learning that direct x resources are exclusive to their creating threads and that the direct x device must be initialised from the same thread as the thread which created the windows window it renders in. I had to alter the entire operation of multiple threaded classes to change the engine and make that work, It would have been a waste of maybe a hundred hours development if I had unit tested those unworkable classes. In a scenario where I started the project with the knowledge I have now and everything was less volatile I would certainly start with unit testing as I now have the prinicple understanding as to how to use the components I am using. It remains a fact that I am better off unit testing now as its good practice to have unit tests in place when you are confident the fundamental architecture for a project is sound. The unit tests are actually part of my own requirements for my project submitted in my last interim report I have done unit testing in other simpler projects/languages but in this case I had to prototype and the prototype evolved into something stable and worth unit testing.

Unit testing is not pixie dust neither is having the capacity to run unit tests which show failed or succeeded, how hard would it have been to have used the functionality that generates a class diagram to generate a class full of stubs for unit testing based on the classes I have in use autonamously, probably about as hard as it is to generate stub c# unit test cases as it already does. It is something I do expect as a standard for any language and while the capacity does exist to integrate unit testing through seperate third parties or reptitive "manual" labour my opinion of Visual Studio has been greatly smacked by this time delay.

I have decided unit testing becomes a lot less valuable when it consumes time and you already have error handling code to flag anomalies that are not obvious from the visual/audio/physics behaviour. With the time cost added from the lack of stub generation and the need to produce an entirely new project unit testing right now seems a massively cost inefficient additional burden. From my understanding now I have to produce a new project dependent on my engines project and produce a set of unit test sets that are just as likely to fail silently as the actual project when being run. Perhaps I will use the std string library to state no tests failed... what if I generate an error in the thing that registers the error handling is working properly? I guess that is why the third party libraries exist. Still seems like laziness on VS part wasting developers time. I do have to argue it might be faster to test my own tester than attempt to process the huge scope of components involved in the unit tester boost provides, as a library it is of collossul proportions.

That (last paragraph mainly) is my argument with this forum and why I have been angry I have not misunderstood unit testing as a magical concept, everyone has stigmatised my perception of unit tests and failed to acknowledge how many man hours VS have wasted by causing all these deviations of libraries that perform unit testing to manifest. Not to mention all the additional time everyone else has to spend learning how to use them, its unfathomably massive. You cannot argue with that its pretty solid logic :P

Anyway we are done now thank you for routing me to the behemoth unit testing libraries I will now have to make a selection from in order to proceed. I hope you have come to gain some insight in that I am not whining for the sake of pixie dust in unit testing but for the sake of fundamental practices existing on an API commercially worth roughly a grand. I will not look for a new API when I am done getting myself out of the mess I have been dropped in by this unfortunate lack of foresight on both my side and my API's side because no other API comes close. If you know an API that provides this base functionality off the bat for C++ I might transfer in order to perform unit tests and I would love to hear about it, if not we are done here and you can wish me luck or debate the validity of my argument on unit testing an evolving prototype before its stable :)

"Using either route, using a library of tools or doing it yourself, the work of writing the tests remains, and it is significant." I cannot argue with that which is why I will only unit test some of the core components such as the engine class (not all of its sub threaded classes) before my next deadline so as to cover the bases.
You went wrong when you decided to use MS Visual Studio. You should use emacs. Emacs has a plugn to write unit tests for you.

Stephen M. Webb
Professional Free Software Developer


Still seems like laziness on VS part wasting developers time.

I'm left wondering after reading your posts what it is exactly you expect Visual Studio to do for you. Setting up a new project should take you a couple of minutes and many lightweight frameworks require very little boilerplate per test. For example, the testing library I use means my tests look like this:


TEST("The discombobulator assembles the widgets")
{
discombobulator d;
CHECK(d.assemble_widgets() == true);
}


I guess Visual C++ could in theory generate the 5 or 6 characters that aren't boilerplate, but I really can't see a lot to complain about, on balance.


That (last paragraph mainly) is my argument with this forum and why I have been angry I have not misunderstood unit testing as a magical concept, everyone has stigmatised my perception of unit tests and failed to acknowledge how many man hours VS have wasted by causing all these deviations of libraries that perform unit testing to manifest. Not to mention all the additional time everyone else has to spend learning how to use them, its unfathomably massive.
[/quote]
Pick one. Read the manual. You'll be writing tests within no time. FWIW, I rolled my own. The introductory page on the wiki will have you up and running in 5 minutes flat should you choose it. The same is true of many other libraries.


If you know an API that provides this base functionality off the bat for C++ I might transfer in order to perform unit tests and I would love to hear about it
[/quote]
What is this "base functionality" you desire? In your first post, you say you'd like the IDE to generate "an empty method for every function WITH ACCESS TO THE CLASSES USED IN MY PROJECT". This isn't necessarily a good approach to writing unit tests because having one test per method will often mean:



  1. All the behaviours for a method are crammed in to one big test. This granularity makes it hard to narrow-down failing code.
  2. Interaction between methods on an object aren't tested. As a contrived example, std::vector<>::push_back() should change the size() of the associated vector.


Writing good tests, or even half-way-sane tests requires some thought.

I'm left wondering after reading your posts what it is exactly you expect Visual Studio to do for you. Setting up a new project should take you a couple of minutes and many lightweight frameworks require very little boilerplate per test. For example, the testing library I use means my tests look like this:


TEST("The discombobulator assembles the widgets")
{
discombobulator d;
CHECK(d.assemble_widgets() == true);
}



This example shows the two most important things that a unit testing library can do for you:
  • help you make assertions (here the CHECK macro) and report their results nicely as test failures
  • collect tests to be run (here the TEST macro), which is really the only use of reflection in JUnit (looking for patterns in function names) and can be perfectly replaced by other appropriate mechanisms in other languages (like macros here)
These features, together with other framework-style support for writing tests (mainly factoring out text fixtures and enforcing a regular structure) are what makes an unit test library better than writing everything on your own.

The best an IDE can do is running your tests and reporting the results; integration can be very nice and convenient, like Eclipse with JUnit, but a stack trace is a stack trace even if you get it in a command prompt or an ad-hoc test runner after compiling your test suite as a regular program: don't waste time on researching low-value tools, and specifically don't reject unit test libraries because an IDE is only integrated with something else.

Nothing meaningful that can be generated automatically. Python or Java tools can inspect code to create piles of empty tests for each class or method for you, which are not only misleading and useless without you actually testing something, but often mismatched to the structures of tests you actually need. Just copy and paste empty or existing tests instead, without creating graveyards of dead code.

Omae Wa Mou Shindeiru

You can use /clr compiler switch to fix these errors.That force the compiler to generate mixed assemblies contain both managed and native parts, allow you to apply .net features  in unmanaged code. turn off /clr:safe switch by going to project->properties->Configuration Properties->General, in configuration page look for &amp;quot;Common Language Runtime Support&amp;quot;, select /clr option.
A common way test your code(native code) in managed C++ is to use P/Invoke.
but if ur project is not integrated with TFS, U should choice better test suite to accomplish ur work.
hope this info can help u.
Is this about IDE? The visual studio?

The fact it does not have File->New Unit Test? Which in Eclipse would generate a test stub?
This topic is nearly a year old. The OP is probably not still around.

This topic is closed to new replies.

Advertisement