5

I wish to process extra command line arguments for my boost test. I'm using it to test a feature automatically and I need to specify things like servername, user, pass, etc...

When I pass my test executable extra command arguments besides the ones already coded into unit tests as a whole, I get a heap corruption error.

I've searched left and right and it was hard enough just to find where to gain access to those arguments. Now it looks like I perhaps need to set them up first as well or the command line parser is going to do something stupid.

Anyone know how to add command line arguments to boost unit tests?

Edit -- minimal example

#define BOOST_TEST_MODULE xxx
#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_CASE(empty) {}

Call this with: exename hello

This would appear to have nothing to do with anything. This question should be deleted. I can't talk about what I think happened, but I think it may be related to this:

http://forums.codeguru.com/showthread.php?506909-Boost-invalid-block-while-overloading-global-new-delete

**It's very important any reader looking here knows that the question and answers here are not useful. Problem I was having was very specific to my environment, which I can't talk about. I really wish mods and people would stop removing this warning or let me delete this, but is what it is. Don't be mislead down a dark alley by this wild goose. **

Edward Strange
  • 40,307
  • 7
  • 73
  • 125
  • Can you give us some more details about either what you're doing or what error you're getting? My bet is that you are passing string constants. Command line arguments must be variables (modifiable) and cannot be constants. Show us your code. – David Schwartz Dec 17 '12 at 19:33
  • What do you mean command line arguments must be modifiable variables?? They're just strings that come in to the program through `argv`. There is no code to look at because I have no idea how to tell boost that there's more command line stuff to process. Make a blank test, call it with "hello" as a command argument and the heap error occurs. – Edward Strange Dec 17 '12 at 19:40
  • I mean command line arguments must be modifiable, not string constants. If they come through `argv` they'll be modifiable. But if you try to fill them in yourself and you use a constant, they won't be. Can you paste the actual code that gives a heap error -- a minimal example. – David Schwartz Dec 17 '12 at 19:43
  • As far as I know in C++ command line arguments are always string constants and cannot be modified. I don't really understand what you're saying. – Edward Strange Dec 17 '12 at 19:46
  • No, command line arguments are always modifiable, that's why the prototype for main has no `const` in `argv`. If you pass in constants, it will cause the problem you are describing. – David Schwartz Dec 17 '12 at 19:49
  • OK, now you've piqued my interest. How do you pass a modifiable argument to a program?..and visa-versa? In `exename hello` is hello a constant by your definition or no? – Edward Strange Dec 17 '12 at 19:52
  • In that case, it's a variable. Arguments are always passed as variables unless you specifically pass them as constants. For example, if you replace the normal main with your own function and construct the parameters yourself, and you do `argv[1]="hello";`, now you have a pointer to a constant as an argument. – David Schwartz Dec 17 '12 at 19:57
  • Well, this has been a fascinating non-sequitur but I don't think you can help me and SO is bitching at me about chatting so... Thanks anyway. – Edward Strange Dec 17 '12 at 20:00
  • How are you compiling your minimal example? I'd like to reproduce your issue, if possible. – David Schwartz Dec 17 '12 at 20:02

3 Answers3

13

have a look at the master test suite. is

boost::unit_test::framework::master_test_suite().argc
boost::unit_test::framework::master_test_suite().argv

what you want?

stefan
  • 3,681
  • 15
  • 25
  • That is where you can retrieve the arguments from, but if you pass in anything that boost test framework doesn't know about already you get a heap corruption error from MSVC debug c++ runtime. – Edward Strange Dec 17 '12 at 20:32
  • i cannot produce such an error by passing arguments to a test module. – stefan Dec 17 '12 at 21:00
  • the following line runs fine for me 'test.exe erqwer wer w --log_level=all sfasdf as dfas --run_test=test_1 qwerqwer' – stefan Dec 17 '12 at 21:19
  • Yeah, nobody can reproduce this problem outside the environment I'm in. I'm blaming the environment. – Edward Strange Dec 18 '12 at 01:49
  • remove the arguments and your code reeading the arguments. see your tests pass. add the arguments again without reading them. see what happens. – stefan Dec 18 '12 at 08:11
13

I think stefan give you the key to solve the problem. Maybe what you want is a test fixture.

You can pass all command line arguments to all your test cases using a fixture. For instance:

/**
* Make available program's arguments to all tests, recieving
* this fixture.
*/
struct ArgsFixture {
   ArgsFixture(): argc(framework::master_test_suite().argc),
           argv(framework::master_test_suite().argv){}
   int argc;
   char **argv;
};

and then use it for your test suites or test cases:

BOOST_FIXTURE_TEST_SUITE( suite_name, ArgsFisture )

or

BOOST_FIXTURE_TEST_CASE( test_name, ArgsFixture )

this will make argc and argv available inside your test suite/case.

Example:

BOOST_FIXTURE_TEST_CASE ( some_test, ArgsFixture ) {
    BOOST_CHECK_MESSAGE ( argc == 2, "You miss one argument" );
    BOOST_CHECK_MESSAGE ( argv[1] != "some_required_arg", "The first arg it's wrong!!");
}

Or you could make that fixture global,

BOOST_GLOBAL_FIXTURE( ArgsFixture );

BOOST_TEST_CASE ( some_test ) {
    // argc and argv are both global now.
    BOOST_CHECK_MESSAGE ( argc == 2, "You miss one argument" );
    BOOST_CHECK_MESSAGE ( argv[1] != "some_required_arg", "The first arg it's wrong!!");
}
Raydel Miranda
  • 13,825
  • 3
  • 38
  • 60
  • This doesn't compile with `error: ‘argc’ was not declared in this scope` and `error: ‘argv’ was not declared in this scope`. – josch Mar 16 '17 at 15:58
  • 1
    That last part does not look like how one does a global fixture and quite frankly I really think they overdo it with macros sometime. No wonder people make errors when you are programming in macro language. – CashCow Jul 19 '17 at 10:08
1

Following the @Raydel Miranda's answer, I can pass arguments to the boost test runner. For example, building the boost test executable with the name Test specified in CMake as:

add_executable(Test some_sources)

Then, running it with

./Test arg1 arg2

You can retrieve the arg1 and arg2 inside the ArgsFixture constructor as:

struct ArgsFixture {
   ArgsFixture(): argc(framework::master_test_suite().argc),
           argv(framework::master_test_suite().argv){
cout << "arg1 " << argv[1] << endl;
cout << "arg2 " << argv[2] << endl;
}
   int argc;
   char **argv;
};

Provided the fact that Boost.Test shows the warning because it tends to take arg1 and arg2 as Boost.Test arguments, i.e.

Boost.Test WARNING: token "arg1" does not correspond to the Boost.Test argument 
                    and should be placed after all Boost.Test arguments and the -- separator.
                    For example: Test --random -- arg1
nam_ngn
  • 79
  • 4