For some reason, I can't start gtest tests from commandline, so I can't pass any arguments to it. I want to run InitGoogleTest already with a parameter defined in code.
Somewhere on the Internet I found a solution like this:
int main(int argc, char **argv) {
char *option[] = { "test.exe", //it doesn't have meaning, just dummy
"--gtest_output=xml:filename" };
int argc1 = 2;
::testing::InitGoogleTest(&argc1, option);
return RUN_ALL_TESTS();
}
This solution didn't produce any errors but didn't create any xml with report either.
Can anyone suggest how to force gtest to write xml from Init?
You can override the output flag by adding
::testing::GTEST_FLAG(output) = "xml:filename";
before the call to InitGoogleTest. You can read more on it at Google Test docs.
Related
I'm working with a large C++ project that presently produces 66 different binaries. Each entrypoint contains its own global variables and main() function, though there's a lot of common code that's provided through a shared library.
For ease of distribution, I would like to distribute a single statically-linked binary, like you'd get from a Go or Rust project. Instead of invoking:
./ProgramFoo
./ProgramBar
I'd like to have a single combined binary that "execs" itself into one of those tools behind the scenes based on argv parameters, sort of like how busybox works:
./CombinedProgram ProgramFoo
./CombinedProgram ProgramBar
Look, I get that there's a "right" way to do this — refactor all 66 source files. Replace all global state with class singletons. Replace all the main() functions with entrypoint functions that could be dispatched from a single, unifying main() function. That sounds like a lot of work and a fair amount of disruption to all the other developers on the project. Is there truly no alternative on the compiler/linker level?
(I also don't want to just archive the binaries inside the CombinedProgram, write them to disk, and exec them. Boo. If I wanted a tarball, I'd just use a tarball.)
My understanding of C/C++ binary production is that the compiler will insert a crt0 startup routine that will initialize all my global state and then invoke main() with the appropriate parameters. Could I... perhaps... sneak some code in before that crt0 that peeks at argv and then proceeds down the correct code path?
Is there truly no alternative on the compiler/linker level?
Not really. Refactoring is the best / least work way to accomplish your task.
% cc -o one busy.c ; ln one two ; ./one ; ./two
one
two
The main() needs to look at ARGV[0] to determine how it was called. Then act on that information.
Simplest example:
#include <stdio.h>
#include <string.h>
int one(int argc, char **argv) {
printf("one\n");
return 1;
}
int two(int argc, char **argv) {
printf("two\n");
return 2;
}
int main(int argc, char **argv) {
char *end = argv[0];
int len = strlen(end);
end += len; // jump to the end of the command.
if (argc >= 1) {
if (!strcmp(end-3, "one")) {
return one(argc, argv);
} else if (!strcmp(end-3, "two")) {
return two(argc, argv);
}
}
}
I don't know of a tool that automatically refactors the commands into functions. The alternative is having one file determine what to do and then exec one of the 66 other statically-linked binaries.
Im using gtest as the test framework for my project and I need to use the following parameter value which is passed as a gtest parameter, inside the test case
./gtest_bin --gtest_repeat=5
Currently what I'm doing is, I've created a custom Listener extended from "EmptyTestEventListener" and pass the iteration value to a global variable when the callback to the following function is received as following,
customListener class
class customListener : public testing::EmptyTestEventListener
{
customListener(int *iteration) : m_iteration(iteration) {}
virtual void OnTestIterationStart(const testing::UnitTest& unit_test, int iteration)
{
*m_iteration = iteration;
}
}
main
int g_iteration;
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
if(argc > 1)
g_array_length = atoi(argv[1]);
testing::TestEventListeners& listners = testing::UnitTest::GetInstance()->listeners();
listners.Append(new printers::customListener(&g_iteration));
return RUN_ALL_TESTS();
}
Is there an easier way to get this gtest parameter value?
If generalized, Is there a way to get any gtest specific parameter value that can used inside a testcase?
IMPORTANT NOTE
Please use with great care - as this is not documented feature and
might be changed (i.e. it might stop working) in next gtest/gmock
versions.
You can access any flag by ::testing::GTEST_FLAG(flag_name) - in your case - ::testing::GTEST_FLAG(repeat).
I got this information indirectly from this manual and by examining gtest.h file.
I've configured visual studio for google test. Then I've written some simple google test cases in vs2010, as You can see below:
TEST(simpleTest, test1){
float base = 4.f;
float exponent = 1.f;
float expectedValue = 4.f;
float actualValue = pow(base, exponent);
EXPECT_FLOAT_EQ(expectedValue, actualValue);
}
TEST(simpleTest, test2){
float base = 4.f;
float exponent = 2.f;
float expectedValue = 16.f;
float actualValue = pow(base, exponent);
EXPECT_FLOAT_EQ(expectedValue, actualValue);
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
RUN_ALL_TESTS();
}
My question is how to run not all (RUN_ALL_TESTS) the tests but one specific test case? Is there any macro e.g. RUN(simpleTest.test1); ?
You can compile the command line flags into your test executable if you want by using the GTEST_FLAG macro (see Running Test Programs: Advanced Options)
So for example, in your case you could do:
int main(int argc, char **argv) {
::testing::GTEST_FLAG(filter) = "simpleTest.test1";
::testing::InitGoogleTest(&argc, argv);
RUN_ALL_TESTS();
}
However, hardcoding test filters like this is normally undesirable, since you need to recompile every time you want to change the filter.
As far as passing the flags at run-time via Visual Studio, I guess you know that you can just add --gtest_filter=simpleTest.test1 to the Command Arguments in the "Debugging" option of your target's Property Pages?
There isn't a macro to specify a single test. There is just RUN_ALL_TESTS.
I think this is by design since running all tests usually preferable. However, if you want to put it in code, just fake the command line arguments like this:
const char *testv[2]=
{
"gtest",
"--gtest_filter=simpleTest.test1",
};
int testc=2;
::testing::InitGoogleTest(&testc, (char**)testv);
int result = RUN_ALL_TESTS();
I haven't really understood whether you indeed want to hardcode your single test, or if you want to decide at test execution time which single test shall be run. If the latter is what you want, you can make use of these VS extensions which integrate your tests into VS' test explorer:
Google Test Adapter (VS 2012-2017; disclaimer: I'm one of the authors)
Test Adapter for Google Test (VS 2017; fork of the above adapter provided by Microsoft)
Via the google test adapter, you can execute it like this
class Test
{
public:
int i;
};
int main(int argc, char const *argv[])
{
Test *i = new Test;
return 0;
}
Is it possible to get support for the arrow notation? So if I write i. it automatically gets expand to i->
I am using SublimeClang. If something like this doesn't exist, would it be possible it create such a plugin?
Take a look at Autohotkey for windows, using this tutorial. or on Linux use Autokey, by following this tutorial.
However, how hard can typing one extra character be as chris said? What if not everything is a pointer?
I am trying to learn how to make a program in C++ that when you run it, you can tell it to run and specify options all in one line. For example you can do ipconfig /all in CMD and it runs ipconfig.exe with the option /all. Another example would be shutdown -f which tells the computer to shutdown with the option -f. For example, I want to make a program that downloads something from a URL and call it for example downloader. From command line one would type downloader http://filehere.com /h which would download the file with the /h option which I would define its property in my program. I don't want code or guides on how to make a downloader I am just trying to learn how to specify options like the /h. Are there any guides out there that you know of and could post or any sample code? I have tried searching for guides, but I think I just don't know what this operation is actually called. Thank you.
You typically define your main function to take two arguments: int argc and char *argv[], such as:
int
main(int argc, char *argv[])
{
...
The first argument is how many parameters your program received, argv is a pointer to them. Note, this isn't mandated, you can name them whatever you want, but that's the convention. Just make sure your types match up.
You can use an option-parsing library, but those are often OS-specific. One simple way to check if you received a /h is:
int got_h = 0;
for (int i=0; i<argc; ++i)
if (strcmp(argv[i], "/h") == 0)
got_h = 1;
...
if (got_h)
...
argv[argc] will always be NULL to make iterating through them easier.
Some more information here: http://www.site.uottawa.ca/~lucia/courses/2131-05/labs/Lab3/CommandLineArguments.html
The main function takes two arguments, traditionally named argc and argv:
int main (int argc, char * argv[])
{
// ...
}
argc contains the number of arguments passed on the command line, and the argv array contains such arguments (with argv[0] being the name used to invoke your program); the last element of the argv array (i.e. argv[argc]) contains a NULL pointer.
Depending upon your proficiency and inclination to use pointers, you may prefer to capture the command line as a vector<string>:
// UNTESTED CODE
int main(int argc, char **argv) {
std::vector<std::string> args(argv+1, argv+argc);
if(args.empty()) {
std::cout << "Usage: downloader URL [options]\n";
return 1;
}
if(std::find(args.begin(), args.end(), "/h") != args.end()) {
option_h = true;
}
Download(args[0]);
}