I've just come up with a better answer to this question. If I was a C/C++ programmer this would have been obvious to me before, and it solves a bunch of annoyances for me at once.
#ifndef UTIL_H #define UTIL_H #include <string> #include <stdio.h> #include <stdarg.h> std::string stringf(const char * format_str, ...) { va_list arg_list; char * c_string; va_start(arg_list, format_str); vasprintf(&c_string, format_str, arg_list); std::string answer = std::string(c_string); free(c_string); va_end(arg_list); return answer; } namespace { int tests = 0; int next_test () { return ++tests; } int current_test () { return tests; } } void ok (bool is_ok, const char * description, ...) { std::string status = stringf("%s %d", is_ok ? "ok" : "not ok", next_test()); va_list arg_list; char * c_string; va_start(arg_list, description); vasprintf(&c_string, description, arg_list); va_end(arg_list); printf("%s: %s\n", status.c_str(), c_string); free(c_string); } void all_done () { printf("1..%d\n", current_test()); } #endif On Tue, Apr 16, 2013 at 6:36 AM, Ben Tilly <bti...@gmail.com> wrote: > On Tue, Apr 16, 2013 at 4:02 AM, David Cantrell <da...@cantrell.org.uk> wrote: >> On 15/04/2013 19:35, Ben Tilly wrote: >> >>> I'm writing some C++ at the moment that fits into the first group >>> (performance-critical code). For unit testing I've been emitting TAP >>> protocol and testing it with prove, but are there better approaches? >>> >>> I get a test file with a lot of code that looks like this: >>> >>> printf( >>> "%s %d: Some useful description and maybe a number %d\n", >>> (expected_value == test_value) ? "ok" : "not ok", ++tests, >>> some_useful_debugging_info >>> ); >> >> >> How about abusing the pre-processor to build a strangely familiar-looking >> mini-language for testing: >> >> #define OK(result, text) printf("%s %d %s\n", (result ? "ok" : "not ok"), >> test_number++, text); if(!(result)) { all_gone_buggerup = 1; } >> #define DONE_TESTING() printf("%s\n", all_gone_buggerup ? "FAILED" : >> "PASSED"); if(all_gone_buggerup) { return 1; } else { return 0; } >> >> obviously you also need to declare and initialise test_number and >> all_gone_buggerup too. >> >> You can then write: >> >> int main(void) { >> int test_number = 0; >> int all_gone_buggerup = 0; >> OK(1 == 1, "it works!"); >> OK(2 == 1, "oh no it doesn't"); >> >> DONE_TESTING(); >> } > > You missed the significant fact that I am passing information into the > description in further parameters. That's essential for me, not a > nice to have. It allows me to do things like have potentially dubious > values appear directly in my test output. (I caught a subtle bug due > to seeing that output just last night!) _______________________________________________ Boston-pm mailing list Boston-pm@mail.pm.org http://mail.pm.org/mailman/listinfo/boston-pm