Skip to content
Snippets Groups Projects
Commit cc820e5f authored by Sylvester Joosten's avatar Sylvester Joosten
Browse files

Added new testing API

parent adccf39a
No related branches found
No related tags found
1 merge request!16Resolve "Benchmark definition standard"
#ifndef BENCHMARK_LOADED
#define BENCHMARK_LOADED
#include "exception.hh"
#include <fmt/core.h>
#include <fstream>
#include <iostream>
#include <nlohmann/json.hpp>
#include <string>
// Bookkeeping of test data to store data of one or more tests in a json file to
// facilitate future accounting.
//
// Usage Example 1 (single test):
// ==============================
// 1. define our test
// juggler_util::test_data test1{
// {{"name", "example_test"},
// {"title", "Example Test"},
// {"description", "This is an example of a test definition"},
// {"quantity", "efficiency"},
// {"target", "1"}}};
// 2. set pass/fail/error status and return value (in this case .99)
// test1.pass(0.99)
// 3. write our test data to a json file
// juggler_util::write_test_data(test1, "test1.json");
//
// Usage Example 2 (multiple tests):
// =================================
// 1. define our tests
// juggler_util::test_data test1{
// {{"name", "example_test"},
// {"title", "Example Test"},
// {"description", "This is an example of a test definition"},
// {"quantity", "efficiency"},
// {"target", "1"}}};
// juggler_util::test_data test2{
// {{"name", "another_test"},
// {"title", "Another example Test"},
// {"description", "This is a second example of a test definition"},
// {"quantity", "resolution"},
// {"target", "3."}}};
// 2. set pass/fail/error status and return value (in this case .99)
// test1.fail(10)
// 3. write our test data to a json file
// juggler_util::write_test_data({test1, test2}, "test.json");
// Namespace for utility scripts, FIXME this should be part of an independent
// library
namespace juggler_util {
struct test_definition_error : exception {
test_definition_error(std::string_view msg)
: exception(msg, "test_definition_error") {}
};
// Wrapper for our test data json, with three methods to set the status
// after test completion (to pass, fail or error). The default value
// is error.
// The following fields should be defined in the definitions json
// for the test to make sense:
// - name: unique identifier for this test
// - title: Slightly more verbose identifier for this test
// - description: Concise description of what is tested
// - quantity: What quantity is tested? Unites of value/target
// - target: Target value of <quantity> that we want to reach
// - value: Actual value of <quantity>
// - weight: Weight for this test (this is defaulted to 1.0 if not specified)
// - result: pass/fail/error
struct test_data {
test_data(nlohmann::json definition) : json{std::move(definition)} {
json["weight"] = 1.0;
// initialize with error (as we don't have a value yet)
error();
// Check that all required fields are present
for (const auto& field : {"name", "title", "description", "quantity",
"target", "value", "weight", "result"}) {
if (json.find(field) == json.end()) {
throw test_definition_error{
fmt::format("Error in test definition: field '{}' missing", field)};
}
}
}
// Set this test to pass/fail/error
void pass(double value) { update_result("pass", value); }
void fail(double value) { update_result("fail", value); }
void error(double value = 0) { update_result("error", value); }
nlohmann::json json;
private:
void update_result(std::string_view status, double value) {
json["result"] = status;
json["value"] = value;
}
};
void write_test_data(const std::vector<test_data>& data,
const std::string& fname) {
nlohmann::json test_data;
for (auto& entry : data) {
test_data.push_back(entry.json);
}
std::cout << fmt::format("Writing test data to {}\n", fname);
std::ofstream output_file(fname);
output_file << std::setw(4) << test_data << "\n";
}
void write_test_data(const test_data& data, const std::string& fname) {
std::vector<test_data> vtd{data};
write_test_data(vtd, fname);
}
} // namespace juggler_util
#endif
#ifndef UTIL_EXCEPTION
#define UTIL_EXCEPTION
#include <exception>
#include <string>
namespace juggler_util {
class exception : public std::exception {
public:
exception(std::string_view msg, std::string_view type = "exception")
: msg_{msg}, type_{type} {}
virtual const char* what() const throw() { return msg_.c_str(); }
virtual const char* type() const throw() { return type_.c_str(); }
virtual ~exception() throw() {}
private:
std::string msg_;
std::string type_;
};
} // namespace juggler_util
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment