What is the difference between #[test] and #[cfg(test)] in Rust? - unit-testing

The Rust docs mention that the #[test] directive is for marking a function which is only compiled and executed in test mode. What is the reason for having the #[cfg(test)] directive then?

#[cfg(test)], like any other #[cfg], can be applied to any piece of code (constant, module, function, statement...) and filters it out from compilation when not compiling tests. #[test] applies only to functions, and in addition to removing the function when not compiling tests, it also registers it as a unit test.
You can use #[cfg(test)] for example to not compile the whole module of the tests (to save compilation time), or to not compile test-only code such as test helpers or other testing logic in the crate.

#[cfg(test)] tells the Rust compiler that the following code should only be compiled when the test configuration is active.
#[test] tells the Rust compiler that the following code should only be compiled when the test configuration is active and that the following function is a test.
E.g. you might have a helper function test_helper inside mod tests that does not test anything and should not be considered as a seperate test. So you want it to compile only for testing but not to be run as separate test by cargo test.

Related

Can I link multiple BOOST unit tests into a single test binary?

I've recently started trying to put a venerable and large (>1 million lines) program under test. There are currently no unit tests. Also, the program is linked as each individual file being linked together - there are no component libraries. Furthermore, the objects are highly interdependent, and it is difficult (impossible?) to link to any object files without linking to at least half of them.
Yes, I know, my life sucks.
I'd like to do some refactoring (obviously), but I'd like to have some tests in place before I start moving things around. My current idea is to compile a single "test program" which runs all of the tests I create. This would drastically simplify the linking issues that I have and let me focus on the real problems. So I have two questions:
Is it possible to link multiple BOOST unit test files into one test executable?
Is there a better solution?
I guess, this is precisely how to use boost test.
I would keep one short main.cpp file consisting of literally 2 lines:
#define BOOST_TEST_MODULE "C++ Unit Tests for MyTangledLibrary"
#include <boost/test/included/unit_test.hpp>
And then I would keep adding test module *.cpp files compiled together into one executable
#include <boost/test/unit_test.hpp>
<< your include files >>
BOOST_AUTO_TEST_SUITE(FancyShmancyLogic)
BOOST_AUTO_TEST_CASE(TestingIf2x3equals6)
{
...
}
BOOST_AUTO_TEST_CASE(TestingIf2x2equals4)
{
...
}
BOOST_AUTO_TEST_SUITE_END()
Yes, you will be able to compile that main.cpp and all of your modules into one large executable.

relevance of using preprocessor directives for testing unit

I'm using Boost unit tests BOOST_AUTO_TEST_CASE
It requires to remove main() function to execute the test cases.
The question is
What directives should be used for switching between Normal/UnitTest modes? I have cross-platform application for Windows and Unix.
I have only one suggestion: use something like #ifndef TESTING in main.cpp and use manual change #define TESTING line ?
Is there any better solution?
Thanks
Unit tests should go into a separate translation unit. If you have foo.hpp and foo.cpp for your library, you have something like foo_test.cpp for the unit tests. Your build environment would then be made aware of a new "test" target which builds and runs those tests.

Eclipse CDT: how to test functions?

How can I test the functions I write before using them in my main C++ application?
Say I have a main.cpp that uses function foo() declared in mylib.h and defined in mylib.cpp.
I would like to test foo() extensively on "toy" situations, to check that it behaves as expected.
How can I do this in Eclipse? For my need it would be enough to have a test.cpp so that I can test single functions at the occurrence. I just would do this adding a "test" option to my makefile that compiles "test.cpp" rather than "main.cpp" but I don't know how to do this in Eclipse.
Any other less naive advice is appreciated as well.
You should have two projects :
project with your main, that uses the library
project where you implement your library, with the unit test main. This main needs to initialize the unit test framework, and execute tests
So, if you haven't, pick an unit testing framework, and add tests.

"Comment" out Macro Function Definition

I am trying to use GTest to test my code but one of the things that bothers me is that it always gets compiled in. This slows down my release builds. A GTest test looks like this
TEST(CaseName, TestName)
{
ASSERT_EQ(3, 3);
}
I want to be able to comment out all of my test by a simple define. I can wrap every test in #ifdef's but that is really ugly. I would like to not include the GTest headers and instead define TEST myself in a way to get rid of the test.
What I Have So far.
I have a macro that defines it as a static function so that it should get optimized out but the assert's inside the test still get compiled (and are undefined). This means that I would also have to define every ASSERT and EXPECT which is tedious to say the least.
#define TEST(tcase, test) static void uselessFunction##tcase##_##test(void)
I could stick with this but I would much prefer something nicer. Hopefully there are some macro-magicians out there to help.
Rather than using macros like this, it might be better to put all your tests into files which are compiled into a test executable, and put all your production files into a library which is linked by the test exe.
In this way, you can have gtest run against both Debug and Release builds, but only compile the test code when you build the test executable.

Visual C++ class testing

Is there any way to easily test C++ classes in java way.
In java you can add static function main and run it directly from IDE
class Foo{
...
public static void main(String args[])
{
System.out.println("Test class foo here");
}
}
is it possible to do it in Visual C++ ?
Of course you can create another project, but it is bad solution(you sould create project, and then add it to solution or run another copy of Visual Studio)
Another way is to modify main() function, or CWinApp::InitInstance() but if you change file
Foo.h, VS will rebuild all files from project, depending on it (we just want to test Foo.h & Foo.cpp)
The best way i founded is to create another project (console), add Foo.h and Foo.cpp to it, add public static function run() to my class Foo and run it from main() function in console project like this
//unitTester.cpp
include "Foo.h"
int main(...){
Foo::run();
return 0;
}
in such way i can test my class Foo separately (without recompiling the big project)
When I feel like writing unit tests, I usually add another project that links in the test code + the classes being tested. The test code I write using the Boost Test Library, which nicely integrates with Visual Studio. I make my actual project dependent on the test project. The test project runs its executable as a post-build step. Therefore, as long as the tests fail, I cannot even build the main project.
The workaround I use is to use a #define to decide what mode the app is in.
I usually have a def.h file, which would have
#define TEST
Then on the main file you write,
#ifdef TEST
// test code
#else
// main code
#endif
This condition check can be done in several places too if for testing you need to change things in several places. If this testing code needs changes in several files also, all you have to do is to include def.h in those source files.
Hope this helps
Use the Boost Test Library. If your application has a GUI, its a littlebit difficult to integrate, but once it works, its quite simple and straightforward to write tests.