CppUnitTestingFramework with templated TEST_CLASSes - templates

Firstly, there is a question with a similar goal described here: C++ unit test testing, using template test class.
This question is regarding my attempt to solve the same problem.
Using the Microsoft CppUnitTestFramework, we can create unit tests using something like the following:
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace MyUnitTests {
TEST_CLASS(NameOfMyTestClass) {
public:
TEST_METHOD(MyMethod1) {
Assert::IsTrue(false);
}
};
}
I'd like to test a collection of similar tests (without using a For loop to put all of the Asserts in a single TEST_METHOD), so I looked at the TEST_CLASS macro:
#define TEST_CLASS(className) \
ONLY_USED_AT_NAMESPACE_SCOPE class className : public ::Microsoft::VisualStudio::CppUnitTestFramework::TestClass<className>
This can't be used with a template directly - as far as I can see there is no way to specify a className value that would include template parameters with the correct syntax to compile.
As a result, I attempted the following:
namespace MyUnitTests {
ONLY_USED_AT_NAMESPACE_SCOPE
template<MyEnumClass MeasurementType, char ExpectedShift>
class templatedScaleTestClass : public TestClass<templatedScaleTestClass<MeasurementType,ExpectedShift>>
{
public:
TEST_METHOD(Test_ExpectedShift) {
Assert::AreEqual(ExpectedShift, Calculations::getShiftAmount(MeasurementType));
}
};
ONLY_USED_AT_NAMESPACE_SCOPE template class templatedScaleTestClass<MyEnumClass::FIRST,3>;
ONLY_USED_AT_NAMESPACE_SCOPE template class templatedScaleTestClass<MyEnumClass::THIRD,1>;
}
This compiles, and looks to me like it should allow me to define a collection of TEST_METHODs in the template class, then just instantiate the necessary collection of Enums and constant values to set them up (perhaps using some sort of constructor for other parameters in the future, although looking at CppUnitTest.h makes me wonder if that might be another problem...)
However, the class never appears in the test explorer, and trying to right click on the test (in the template code) and clicking "Run Test(s)" produces the following output:
[datetime Informational] Executing test method 'MyUnitTests.templatedScaleTestClass<MeasurementType, ExpectedShift>.Test_ExpectedShift'
[datetime Informational] No tests found to run.
Edit: Not sure how relevant the last part ("No tests found to run") is - doing the same with a normal test (no user-side templates) produces the same output. Clicking away from a specific test runs all tests in the .cpp file. Perhaps I'm using the right-click menu wrongly.

Despite having tried several attempts at getting this to display, and checking the output of a function like the following:
template<typename T>
void debugMethod(TestClass<T> *tc) {
const TestClassInfo* classInfo = tc->__GetTestClassInfo();
std::stringstream msg;
msg << "Tag: " << classInfo->metadata->tag << std::endl;
msg << "helpMethodName: " << classInfo->metadata->helpMethodName << std::endl;
msg << "helpMethodDecoratedName: " << classInfo->metadata->helpMethodDecoratedName << std::endl;
msg << "New method address: " << &(classInfo->pNewMethod) << std::endl;
const MemberMethodInfo* methodInfo = T::__GetTestMethodInfo_Debug();
msg << "methodInfo - Tag: " << methodInfo->metadata->tag << std::endl;
msg << "methodInfo - methodName: " << methodInfo->metadata->methodName << std::endl;
msg << "methodInfo - helpMethodName: " << methodInfo->metadata->helpMethodName << std::endl;
msg << "methodInfo - helpMethodDecoratedName: " << methodInfo->metadata->helpMethodDecoratedName << std::endl;
msg << "methodInfo - lineNo: " << methodInfo->metadata->lineNo << std::endl;
Logger::WriteMessage(msg.str().c_str());
}
... (namespace, test class etc)
TEST_METHOD(Debug) { debugMethod(this); }
and observing similar results in both a standard TEST_CLASS and my templated class, I was unable to get templated classes to display in the Test Explorer.
It is possible to template a class then call the test functions from a non-templated class:
template <MyEnum val>
class myClass : public TestClass<myClass<val>>
{
public:
TEST_METHOD(MyTest) {
Assert::AreEqual(val, MyEnum::exampleValue);
}
}
TEST_CLASS(DummyTests) {
TEST_METHOD(Test_across) {
auto a = myClass<MyEnum::MyEnumValue>();
a.MyTest();
}
}
but this still provides less than ideal feedback in the Test Explorer.
A further alternative (ugly as it is...) is to define a macro function that takes the parameter you want to template on, and then define your entire class inside the macro:
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
#define SCALING_TEST(TYPE_TO_TEST, EXPECTED_SHIFT)\
TEST_CLASS(CATNAME(ScalingTest_, TYPE_TO_TEST)) {\
private:\
MyEnum type = MyEnum::TYPE_TO_TEST;\
public:\
TEST_METHOD(HasExpectedShift) {\
Assert::AreEqual((char)EXPECTED_SHIFT, Calculations::getShiftAmount(type));\
}\
}
namespace ScalingTests {
SCALING_TEST(SPEED, 3);
}

Related

Where to put function declaration?

Let's say I'm developing a logging functionality. Inside logging.h I declare the function to be used by the application later on.
// logging.h
#include <string>
namespace logging {
void LogThis(const std::string& text);
}; // namespace logging
Its definition is obviously inside logging.cpp:
// logging.cpp
void logging::LogThis(const std::string& text) {
std::cout << "Log: " << text << '\n';
}
Now lets pretent that my LogThis function's work is split up into some smaller helper functions. They're not part of the logging interface. Let's take a Prettify function as an example.
// logging.cpp
void logging::LogThis(const std::string& text) {
Prettify(text);
std::cout << "Log: " << text << '\n';
}
My question is: Where do I put the function declaration of Prettify? I shouldn't include it in the logging.h header file, because then it can be called by other compilation units and its not part of the interface. So just put it inside logging.cpp instead like this?
// logging.cpp
namespace logging {
void Prettify(std::string& ugly_text);
void LogThis(const std::string& text) {
Prettify(text);
std::cout << "Log: " << text << '\n';
}
void Prettify(std::string& ugly_text) {
// making it pretty...
}
}
I'm looking for some best practices / rules of thumb / opinions on this :) Thanks in advance!
For things that are only needed within the file, I would just place it in an anonymous namespace within the C++ file itself, sort of the modern equivalent of the legacy C static keyword on functions(a):
namespace {
void WeaveMagic(std::string& ugly_text) {
WeaveMoreMagic(ugly_text);
}
void Prettify(std::string& ugly_text) {
WeaveMagic(ugly_text);
}
}
If you place this before any use of the functions, and ensure a strict hierarchy of calls, you can skip the declarations since the definitions provides the required information, as shown above.
Of course, if there are any circular dependencies between multiple anonymous functions (i.e., circular recursion), you will still need to provide declarations:
#include <iostream>
namespace {
int DivThree(int val); // needed to implement AddOne()
int AddOne(int val) {
std::cout << "AddOne " << val << " -> " << (val + 1) << '\n';
if (val > 0) return DivThree(val + 1);
return val;
}
int DivThree(int val) {
std::cout << "DivThree " << val << " -> " << (val / 3) << '\n';
return AddOne(val / 3);
}
}
int main(){
int final = AddOne(18);
std::cout << "Final " << final << '\n';
return 0;
}
And, yes, that's very contrived, but good examples of circular recursion are few and far between :-) The output is:
AddOne 18 -> 19
DivThree 19 -> 6
AddOne 6 -> 7
DivThree 7 -> 2
AddOne 2 -> 3
DivThree 3 -> 1
AddOne 1 -> 2
DivThree 2 -> 0
AddOne 0 -> 1
Final 0
(a) CPP Core Guidline SF.22 actually covers this:
Use an unnamed (anonymous) namespace for all internal/non-exported entities.
Reason: Nothing external can depend on an entity in a nested unnamed namespace. Consider putting every definition in an implementation source file in an unnamed namespace unless that is defining an "external/exported" entity.
An API class and its members can't live in an unnamed namespace; but any "helper" class or function that is defined in an implementation source file should be at an unnamed namespace scope.
If you are operating on functions only, as #paxdiablo have written, you can use anonymous namespace (look at his answer).
I have some C-based habits, so personally I would also see it as static function. But I'm not sure how C++ fanatics will look at it :). static (in this context) makes functions local for compilation unit (logging.cpp), so it cannot be linked from outside.
//logging.cpp
static void Prettify(std::string& ugly);
void LogThis(const std::string& text) {
Prettify(text);
std::cout << "Log: " << text << '\n';
}
static void Prettify(std::string& ugly) { }
However if your logging utility would be object-oriented. I suggest you to use D-pointer and Q-Pointer design pattern (known also as PImpl idiom) - https://en.cppreference.com/w/cpp/language/pimpl .
//logging.h
#include <string>
class loggingImpl;
class logging {
public :
logging();
virtual ~logging();
void LogThis(const std::string& text);
protected :
loggingImpl *impl;
};
//logging.cpp
class loggingImpl
{
public :
loggingImpl(logging *p) : qptr(p) { }
void Prettify(std::string& ugly) { }
//anything what you need and should be hided
// access parent through qptr
protected :
logging *qptr;
};
logging::logging() : impl(new loggingImpl) { }
logging::~logging() { delete impl; }
void logging::LogThis(const std::string& text) {
impl->Prettify(text);
std::cout << "Log: " << text << '\n';
}
As you have written, putting declaration in header file is not proper due to limiting visibility of unused symbols.

Check if a type DIRECTLY derives from (is a child of) another type in an "enable if" context

C++ has is_base_of<Base,Derived>. However, this also includes “grandparent” types.
Is there a way to get have is_child_of<Parent,Child> functionality? The purpose is to use types as sentinel 'interface' markers in an SFINAE context, without being affected by sentinels that may or may not be added to parent types.
That is, the following output is expected to be "true, false". (The output with is_base_of is "true, true".)
#include <iostream>
#include <type_traits>
class A {};
class B : A {};
class C : B {};
int main()
{
std::cout << std::boolalpha;
std::cout << "a2b: " << std::is_child_of<A, B>::value << '\n';
std::cout << "a2c: " << std::is_child_of<A, C>::value << '\n';
}
C++ doesn't have reflection, child's storage contain's parent's storage and it's hard to draw a line between one subobject and another. Some metaprogramming must be dome, mimicking libraries similar to Qt or MFC\WFC
#include <iostream>
#include <type_traits>
#define DECLARE_CLASS(Name, ParentName) using Parent = ParentName;
#define PARENT_CLASS(Name) Name::Parent
class LibBase {
public:
DECLARE_CLASS(LibBase, void)
};
class A : public LibBase {
public:
DECLARE_CLASS(A, LibBase)
};
class B : public A {
public:
DECLARE_CLASS(B, A)
};
int main()
{
std::cout << std::boolalpha;
std::cout << std::is_same<PARENT_CLASS(B), A>::value << std::endl;
std::cout << std::is_same<PARENT_CLASS(B), LibBase>::value << std::endl;
}
Clearly this simple approach have pitfall that we don't get an error if class is not defined using our macro., and it is static only,
First issue can worked around by creating a "trait" nested class by declaration, which got name based on class name passed to DECLARE_OBJECT. This would make result of PARENT_CLASS(Name) unique, e.g.
#define DECLARE_CLASS(Name, ParentName) struct TraitsOf##Name { \
using Parent = ParentName; \
};
#define PARENT_CLASS(Name) Name::TraitsOf##Name::Parent
Second issue can be worked around by creating own RTTI function within macro-definition
Sadly form is_child_of<LibBase, A>::value is unattainable with this because macro substitution happens before template substitution. Perhaps some static registering approach can be used to give classes unique traits in wait how BOOST_TYPEOF does but getting rid of macrodefinitions in user code would be nigh-impossible.

Using CRTP To Deterministically Generate Code

I've been recently getting into template wizardry and in particular CRTP. I know that templates are used to make the compiler generate code for us so I was wondering if it were possible to make a template "decide" which parts of a function we would like it to include for a particular class. For example if I have the following code:
crtp.h
#include <iostream>
using std::endl;
using std::cout;
template<class T>
class A {
public:
void func() {
constexpr unsigned short mask = T::GetMask();
if (mask & 1) {
/*
Do Something
*/
cout << "Mask 1" << endl;
}
if (mask & 1 << 3) {
/*
Do Something else
*/
cout << "Mask 2" << endl;
}
}
};
class B : public A<B> {
friend class A<B>;
protected:
static constexpr unsigned short GetMask() { return 0x0001; }
};
class C : public A<C> {
friend class A<C>;
protected:
static constexpr unsigned short GetMask() { return 0x0009; }
};
main.cpp
#include "ctrp.h"
#include <iostream>
#include <vector>
using std::cout;
using std::vector;
using std::getchar;
using std::endl;
int main() {
B b;
C c;
cout << "B:" << endl;
b.func();
cout << endl << "C:" << endl;
c.func();
getchar();
}
Which when executed produces:
B:
Mask 1
C:
Mask 1
Mask 2
This works great, does exactly what I want it to. The problem is from my standpoint the if statements should be unnecessary. As I am dealing with constant expressions the compiler should have everything it needs to simply skip the branching and know to execute the first part for class B and both parts for class C.
I would like to cash in on this and specifically tell the compiler to remove the sections that are unnecessary for the particular class to avoid unnecessary branching at runtime. Unfortunately I have no idea how to do this, any ideas? Thanks in advance
Edit
In response to some of the awesome suggestions C++17's constexpr if expression is a near perfect solution that I had no idea existed, but am unfortunately unable to use. I am limited to using C++14.
If you care about performance, the compiler will very likely optimize out all "dead" branches and even the if condition, if it can evaluate it during compile time.
What is worse, all the branches need to be well formed until C++17 constexpr if. In this case, you can "outsource" the functionality to special (static member) functions and use specialization to invoke the right one. See #R Sahu's answer for the example.
Emulating if/else at compile time using template metaprogramming does not work that way. You have to imagine if/else using a different mindset.
Instead of
if (mask & 1) {
/*
Do Something
*/
cout << "Mask 1" << endl;
}
if (mask & 1 << 3) {
/*
Do Something else
*/
cout << "Mask 2" << endl;
}
you'll have to use something along the lines of:
function1_selector<mask & 1>::dostuff();
function2_selector<mask & 1 << 3 >::dostuff();
where
template <bool> struct function1_selector
{
static void dostuff() { /* Do nothing */ }
};
template <> struct function1_selector<true> // Specialize for true
{
static void dostuff() { /* Do something useful */ }
};
Add code for function2_selector similarly.

cannot declare c++ function without template

i have a relatively small c++ project and i decided to make a Utils header file which would just contain some small helper functions etc. It was all working fine when i was declaring functions that were using a template, then i tried to make a function which didnt need a template, and suddently it doesn't work.
The result i get is a linker error; already defined in (file).obj
I cannot even declare a simple void function, everything without template gives a linker error.
I have NO IDEA whatsoever what could be causing this. Here is the code for the header file... Thanks in advance.
#pragma once
namespace Utils
{
std::string GetActiveWindowTitle()
{
// This doesnt work either, also gives linker error.
return active_window;
}
template<typename T>
void Print(char * value, T printValue)
{
std::cout << value << ": " << printValue << std::endl;
}
template<typename T>
void Print(T printValue)
{
std::cout << "DEBUG: " << printValue << std::endl;
}
void PrintStr(std::string str)
{
// This doesn't work because it doesnt have the template, it gives a linker error
std::cout << "DEBUG: " << str.c_str() << std::endl;
}
}
A function-template is implicitly inline. Thus, when defined in a header file, it doesn't violate ODR (One Definition Rule). For non-template functions in header files, you should either define them as inline, or define them in a separate translation unit.
So, you could do:
#pragma once
namespace Utils
{
inline std::string GetActiveWindowTitle()
{
return active_window;
}
template<typename T>
void Print(char * value, T printValue)
{
std::cout << value << ": " << printValue << std::endl;
}
template<typename T>
void Print(T printValue)
{
std::cout << "DEBUG: " << printValue << std::endl;
}
inline void PrintStr(std::string str)
{
std::cout << "DEBUG: " << str.c_str() << std::endl;
}
}
See Inline keyword vs header definition
If you include your header to more than one cpp, the function will be defined more than once and the linker will give you the error described above. See What is the difference between a definition and a declaration? or What are forward declarations in C++?

How to use my logging class like a std C++ stream?

I've a working logger class, which outputs some text into a richtextbox (Win32, C++).
Problem is, i always end up using it like this:
stringstream ss;
ss << someInt << someString;
debugLogger.log(ss.str());
instead, it would be much more convenient to use it like a stream as in:
debugLogger << someInt << someString;
Is there a better way than forwarding everything to an internal stringstream instance? If'd do this, when would i need to flush?
You need to implement operator << appropriately for your class. The general pattern looks like this:
template <typename T>
logger& operator <<(logger& log, T const& value) {
log.your_stringstream << value;
return log;
}
Notice that this deals with (non-const) references since the operation modifies your logger. Also notice that you need to return the log parameter in order for chaining to work:
log << 1 << 2 << endl;
// is the same as:
((log << 1) << 2) << endl;
If the innermost operation didn't return the current log instance, all other operations would either fail at compile-time (wrong method signature) or would be swallowed at run-time.
Overloading the insertion operator<< is not the way to go. You will have to add overloads for all the endl or any other user defined functions.
The way to go is to define your own streambuf, and to bind it into a stream. Then, you just have to use the stream.
Here are a few simple examples:
Logging In C++ by Petru Marginean, DDJ Sept 05th 2007
Rutger E.W. van Beusekom's logstream class, check also the .hpp alongside with this file
As Luc Hermitte noted, there is "Logging In C++" article which describes very neat approach to solve this problem. In a nutshell, given you have a function like the following:
void LogFunction(const std::string& str) {
// write to socket, file, console, e.t.c
std::cout << str << std::endl;
}
it is possible to write a wrapper to use it in std::cout like way:
#include <sstream>
#include <functional>
#define LOG(loggingFuntion) \
Log(loggingFuntion).GetStream()
class Log {
using LogFunctionType = std::function<void(const std::string&)>;
public:
explicit Log(LogFunctionType logFunction) : m_logFunction(std::move(logFunction)) { }
std::ostringstream& GetStream() { return m_stringStream; }
~Log() { m_logFunction(m_stringStream.str()); }
private:
std::ostringstream m_stringStream;
LogFunctionType m_logFunction;
};
int main() {
LOG(LogFunction) << "some string " << 5 << " smth";
}
(online demo)
Also, there is very nice solution provided by Stewart.
An elegant solution that also solves the flushing issues is the following:
#include <string>
#include <memory>
#include <sstream>
#include <iostream>
class Logger
{
using Stream = std::ostringstream;
using Buffer_p = std::unique_ptr<Stream, std::function<void(Stream*)>>;
public:
void log(const std::string& cmd) {
std::cout << "INFO: " << cmd << std::endl;
}
Buffer_p log() {
return Buffer_p(new Stream, [&](Stream* st) {
log(st->str());
});
}
};
#define LOG(instance) *(instance.log())
int main()
{
Logger logger;
LOG(logger) << "e.g. Log a number: " << 3;
return 0;
}
In the Logger class, override the << operator.
Click Here to know how to implement the << operator.
You can also avoid the logging statements inside the code
using Aspect Oriented programming.