Namespace vs. struct counter

Hello, I am currently making a minimalistic testing framework for on-target unit testing. I am making the framework layered, so that a named testing section contains multiple assertions and a named test case contains multiple sections. For every section that is called within a test case, a counter will increment, so that once the test case is finished, the total number of sections can be sent over a communication protocol (e.g. UART), with additional information on each assertion performed in each section.
What I am wondering is, would it be better to place the entire testing framework in a struct with the relevant counters internally, or each function (for naming and incrementing the total number of sections) in a file along with a namespace containing the counters to limit the scope? As I understand it, if I use the struct method, I will get multiple of the same counter variables while in the namespace method I will only have one, where I use various function calls to increment the counter. Would the namespace method be bad practice in some way, or is this the preferred choice?
Below is the code for the namespace method. The create_id_message doesn't require a template, but I used it so that it will be run at compile time. Feel free to comment on any bad practice or improvements I can make, any help would be greatly appreciated :)
The std::cout statements will be changed for communication protocol message functions that are used on-target


#include <string>
#include <sstream>
#include <iostream>

namespace {
constexpr int message_size = 32;
std::string message = "";
int section_counter = 0;
int test_case_counter = 0;
int assertions_run = 0;
} //namespace

template<typename Type>
static std::string to_string(const Type & value, const int precision = 4){
std::ostringstream value_as_string;
value_as_string << std::fixed << value;
return value_as_string.str();

template<typename Type>
static void create_result_message(const Type & expected_value, const Type & actual_value){
short message_it = 0;
message = " E:" + to_string(expected_value, 15) + " A:" + to_string(actual_value, 15) + "EOM";
while(message.length() > ((message_it)*(message_size-1))){
std::cout << message.substr(message_it*(message_size-1), (message_it+1)*(message_size-1)) << std::endl;

template<typename Type>
static void create_id_message(Type test_id, char result_value){
message = " ID:" + to_string(test_id) + ":" + result_value;
std::cout << message << std::endl;

static void section(std::string section_name){
std::cout << "\nNew section: " << section_name << "\nSection counter: " << section_counter << std::endl;

static void section_end(){
std::cout << "Assertions performed: " << assertions_run << std::endl;
assertions_run = 0;

static void test_case(std::string test_case_name){
std::cout << "\nNew test case: " << test_case_name << "\nTest case counter: " << test_case_counter << std::endl;

static void test_case_end(){
std::cout << "Number of Sections: " << section_counter << std::endl;
section_counter = 0;

template<typename Type>
static void assert(const Type & actual_value, const Type & expected_value){
if(actual_value == expected_value){
create_id_message(assertions_run, '1');
create_id_message(assertions_run, '0');
create_result_message(expected_value, actual_value);

Last edited on
Multiple files can share a namespace, and add declarations to that namespace.

Take std for example, file vector adds vector, utility a whole bunch of disparate things, string basic_string. They're just cooperating parts of a library,

A record is defined once and that definition is static.

The only thing struct and namespace have in common is thy define some kind of scope.
Topic archived. No new replies allowed.