UnitTest++ and main - c++

I want to give TDD a try and I've chosen the UnitTest++ framework, but the documentations is almost non-existent (to my knowledge).
My concern is this: in all the tutorials I've seen, they put UnitTest::RunAllTests() in the main() function. I'm guessing they do it only to simplify the explanation, but I wouldn't want that with my software. Where should I put UnitTest::RunAllTests() so that I can have it executed every time I build the software but not when I run it?

UnitTest::RunAllTests() should be put into the main function of a separate program, which you compile and run as part of your build process.

One thing we've done in the past is to add a command line argument which makes the main executable run all the tests and then exit. It's fairly easy to arrange some #ifdefs such that this code gets compiled out on release builds. Something like this (it's not very C++ but if you weren't parsing command line arguments already this is the simplest way to do it):
int main (int argc, char *argv[])
{
#ifdef DEBUG
if (argc > 1 && !strcmp(argv[2], "-t"))
{
return UnitTest::RunAllTests();
}
#endif
[rest of program]
}

Related

Get command line arguments without arguments in main()

One strange thing took my sleep away. .
I have P7 library. It is library for writing logs.
Library contains few examples.
Example for C++ looks like:
int main(int i_iArgC, char* i_pArgV[])
{
// Some code that don't use i_iArgC or i_pArgV
}
But the trick that program handle command line arguments somehow.
I play a little bit to make sure that this main called.
What I do:
Build in debug and set breakpoint on main (to make sure that exactly
this main is called)
Changemain(int i_iArgC, char* i_pArgV[]) to main() (To make sure that no one use them)
I have no idea how it possible.
Here is minimal steps you can do to look on it by yourself:
Download P7 code from this page (link at top left)
Unzip archive
Run build.sh (It runs few makefiles in some order)
Execute Cpp_Example from Binaries folder
Execute again Cpp_Example /P7.Help to see that app react to command line arguments.
Most systems allow for getting the command line parameters without relying on main(). On Windows for example, you can use GetCommandLineW().
The library has non-portable code to do just that in Shared/Platforms/*/PProcess.h. A quick look at Windows_x86/PProcess.h shows that it uses GetCommandLineW() and the same file in Linux_x86/ reads /proc/self/cmdline.

Is there a way to let IAR CSPY return an error code defined by executed user program?

I am using IAR EWARM's cspybat to run some unit tests for my embedded code using Unity. I would like an easy way for my build server to determine if the unit tests passed or failed. Is there a way for CSPY to return a nonzero error code if my unit tests fail? I have tried changing the return value in main() with no change. Is there a function I can call to force an error to be returned?
My cspybat batch file looks like this:
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 7.4\common\bin\cspybat" -f "C:\Work\Sandbox\ST\stmicroeval\_iar_ewarm_project\settings\Project.UnitTest.general.xcl" --backend -f "C:\Work\Sandbox\ST\stmicroeval\_iar_ewarm_project\settings\Project.UnitTest.driver.xcl"
Unfortunately, no.
I've solved this by replacing "exit" with a function that prints a specific pattern, plus the exit code. I then wrapped the call to cspybat into a script that 1) strips the output of the extra output and 2) exits with the desired exit code.
It's late 2020 and they still don't offer a mechanism to do this.
We solved it by including a macro file with the contents:
execUserExit()
{
__message "program exited with __exit_value = ", __exit_value:%d ;
}
And having our own exit variable in the code:
extern "C" int __exit_value=0xff;
That we set prior to calling exit() (though you could just write your own version of exit())
This makes the debugger always print SOMETHING, even if the program crashes on startup.
Then we parse with a python wrapper:
pattern = "__exit_value =\s([\-|0-9|a-f|A-F|x]*)"
retvalue = int(re.findall(pattern,process.stdout)[0])

Compiling Julia embedded in C++ code

I'm trying to compile the following C++ code
#include <julia.h>
int main(int argc, char *argv[])
{
/* required: setup the julia context */
jl_init(NULL);
/* run julia commands */
jl_eval_string("print(sqrt(2.0))");
/* strongly recommended: notify julia that the
program is about to terminate. this allows
julia time to cleanup pending write requests
and run all finalizers
*/
jl_atexit_hook();
return 0;
}
I compile the code using
gcc -I/usr/include/julia -L/usr/lib/x86_64-linux-gnu/julia -ljulia juliatest.cpp -o test
I get the following error-
juliatest.cpp:19:20:: error: too few arguments to function ‘void jl_atexit_hook(int)’
jl_atexit_hook();
^
In file included from juliatest.cpp:1:0:
/usr/include/julia/julia.h:1188:16: note: declared here
DLLEXPORT void jl_atexit_hook(int status);
^
If I remove jl_atexit_hook(); from the code, I get the following errors-
juliatest.cpp:(.text+0x1a): undefined reference to `jl_init_with_image'
juliatest.cpp:(.text+0x24): undefined reference to `jl_eval_string'
What am I doing wrong?
The example you are trying to compile is a little bit outdated. As already mentioned you need to give an exitcode to the jl_atexit_hook()
function. The linker message is about missing functions defined in libraries. To get rid of distribution details I downloaded and build the tarball. Now the example can be build using this makefile:
JULIA_DIR:=julia-0.4.2
JULIA_LIB:=$(JULIA_DIR)/usr/lib
JULIA_SRC:=$(JULIA_DIR)/src
JULIA_INC:=$(JULIA_DIR)/usr/include
CPPFLAGS:=-I$(JULIA_INC) -I$(JULIA_SRC) -I$(JULIA_SRC)/support
LDFLAGS:=-L$(JULIA_LIB)
LDLIBS=-ljulia
export LD_LIBRARY_PATH:=$(JULIA_LIB):$(JULIA_LIB)/julia
all: main
run: main
#./main
clean:
rm -f main
If you now type make run you will get the next error message about a wrong path the system image is searched in. As Thomas noted here the function jl_init() is creating a context that may fail in this case. We shall give the name and the path of the system image to the init function using jl_init_with_image("julia-0.4.2/usr/lib/julia", "sys.so") instead. This is an ugly hard coded path and can surely be replaced. But for getting started with this example and to get this problem known, it is enough. The corrected example is this:
#include <julia.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
/* required: setup the julia context */
jl_init_with_image("julia-0.4.2/usr/lib/julia", "sys.so");
/* run julia commands */
jl_eval_string("print(sqrt(2.0))");
/* strongly recommended: notify julia that the
program is about to terminate. this allows
julia time to cleanup pending write requests
and run all finalizers
*/
jl_atexit_hook(0);
putchar('\n');
return 0;
}
Running make run will now be a quite complicated way to calculate the square root of 2 :-)
Have fun.

QProcess Multiplatform command

I need to launch some script using QProcess.
For this, under windows, I use QProcess::execute("cmd [...]");.
However, this won't work if I go under some other OS such as Linux.
So, I was wondering if the best solution to make that code portable, would be to interfere with a mutliplatform scripting solution, such as TCL for exemple.
So I use : QProcess:execute("tclsh text.tcl"); and it works.
But, I got three questions concerning that problem. Because I'm not sure of what I've done.
Will execute() execute tclsh with the file test.tcl both under Windows and Linux wherever I execute it ? It seems to do so, but I want to be sure ! Is there any bad scenario that can happen ?
Is this a good solution ? I know lots of people have way more experience than I do, and I'd be grateful for anything I could learn !
Why not using std::system() ? Is it less portable ?
While this isn't a total answer, I can point out a few things.
In particular, tclsh is quite happy under Windows; it's a major supported platform. The main problem that could happen in practice is if you pass a filename with a space in it (this is distinctly more likely under Windows than on a Unix due to differences in community practice). However, the execute() as you have written it has no problems. Well, as long as tclsh is located on the PATH.
The other main option for integrating Tcl script execution with Qt is to link your program against the Tcl binary library and use that. Tcl's API is aimed at C, so it should be pretty simple to use from C++ (if a little clunky from a C++ perspective):
// This holds the description of the API
#include "tcl.h"
// Initialize the Tcl library; *call only once*
Tcl_FindExecutable(NULL);
// Make an evaluation context
Tcl_Interp *interp = Tcl_CreateInterp();
// Execute a script loaded from a file (or whatever)
int resultCode = Tcl_Eval(interp, "source test.tcl");
// Check if an error happened and print the error if it did
if (resultCode == TCL_ERROR) {
std::cerr << "ERROR: " << Tcl_GetString(Tcl_GetObjResult(interp)) << std::endl;
}
// Squelch the evaluation context
Tcl_DeleteInterp(interp);
I'm not a particularly great C++ coder, but this should give the idea. I have no idea about QProcess::execute() vs std::system().
A weak point of your solution is that on windows you'll have to install tclsh. There is no tclsh on Solaris either. May be somewhere else.
Compared to std::system(), QProcess gives you more control and information about the process of executing your command. If all you need is just to execute script (without receiving the output, for example) - std::system() is a good choice.
What I've used in a similar situation:
#ifdef Q_OS_WIN
mCommand = QString("cmd /C %1 %2").arg(command).arg(args);
#else
mCommand = QString("bash %1 %2").arg(command).arg(args);
#endif

Running c++ in browser

I have written some basic c++ programs in one of my classes for school. I was wondering if it was possible to somehow virtually run the program in a broswer. I would like to post the program to my website. Once its posted, a person could access the program, run the program, and, interact with the program. I'm not trying to write C++ for my website, it would be more for an interactive portfolio.
Is this possible?
Use codepad, a website which lets you compile and share code online.
#include <iostream>
int main(int argc, char** argv) {
std::cout << "Hello, Stack Overflow!" << std::endl;
return 0;
}
There is also Google Native Client SDK that allows C++ code to run in browser. Microsoft Active X is also a viable option. I am only saying it is possible not recommended.
You can only run the program on your server, not on the client's machine.
At least not without downloading and manually executing it. Anything else would be an open door for malware...
I see two options, but both very overkill:
Write (or find) a C++ interpreter in JavaScript
Use a VM running an operating system (e.g. jslinux and demonstrate your programs there.
The sensible option is to just give people a way to view and download the source code, I guess.
Google chrome supports this: http://www.readwriteweb.com/cloud/2011/08/google-officially-announces-cc.php
But it's by no means "mainstream" or standards-based.
Another solution (codepad like) would be to use https://ideone.com/ which seems much nicer to use than codepad, more user-friendly, but does the same:
Allow you to write C++ (60 languages possibles) directly from the browser and compile it and render result in the browser (I tried using printf and it worked fine). Possibility of forking source code.
https://ideone.com/baYzfe
The following two programs are quite useful :
1) Ideone
2) Codepad
You can compile, run, and share code online in any browser.
You can use Emscripten to compile C++ to Javascript. Emscripten can compile LLVM bitcode to Javascript. Some demos of Emscripten can be found here, including a raytracer and a text-to-speech engine that was compiled from C++ to Javascript.
To run x86 binaries in a web browser, you could also use an emulator such as v86. This is one possible way to compile and run C++ programs in a browser.
One of the best sites for running C++ and other multiple languages online is Repl.it
This example: repl.it/#abranhe/stackoverflow
#include <iostream>
int main() {
std::cout << "Hello Stackoverflow\n";
return 0;
}
One of the biggest pros it has is that you can work with multiple files, working with header (header.h) files etc. None of the below websites provide this option:
Codepad.org
JSLinux
IDEone
I really recommend it! You will love it!
Also wanted to add Google Colab here as an option:
Cell 1:
%%writefile hello.cpp
#include <iostream>
int main(int argc, char** argv) {
std::cout << "Hello, Stack Overflow!" << std::endl;
return 0;
}
Cell 2:
%%script bash
g++ hello.cpp -o test
ls -laX
./test