Barebones JUnit XML output
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
diff --git a/tests/clar.c b/tests/clar.c
index 38359dc..fd5fcb6 100644
--- a/tests/clar.c
+++ b/tests/clar.c
@@ -138,6 +138,7 @@ static struct {
int report_errors_only;
int exit_on_error;
int report_suite_names;
+ int write_summary;
struct clar_explicit *explicit;
struct clar_explicit *last_explicit;
@@ -353,6 +354,7 @@ clar_usage(const char *arg)
printf(" -q \tOnly report tests that had an error\n");
printf(" -Q \tQuit as soon as a test fails\n");
printf(" -l \tPrint suite names\n");
+ printf(" -r \tWrite summary file\n");
exit(-1);
}
@@ -366,7 +368,7 @@ clar_parse_args(int argc, char **argv)
char *argument = argv[i];
if (argument[0] != '-' || argument[1] == '\0'
- || strchr("sixvqQl", argument[1]) == NULL) {
+ || strchr("sixvqQlr", argument[1]) == NULL) {
clar_usage(argv[0]);
}
}
@@ -462,6 +464,10 @@ clar_parse_args(int argc, char **argv)
_clar.report_suite_names = 1;
break;
+ case 'r':
+ _clar.write_summary = 1;
+ break;
+
default:
assert(!"Unexpected commandline argument!");
}
@@ -503,6 +509,8 @@ clar_test_run(void)
return _clar.total_errors;
}
+static void clar_summary_write(void);
+
void
clar_test_shutdown(void)
{
@@ -517,6 +525,9 @@ clar_test_shutdown(void)
clar_unsandbox();
+ if (_clar.write_summary)
+ clar_summary_write();
+
for (explicit = _clar.explicit; explicit; explicit = explicit_next) {
explicit_next = explicit->next;
free(explicit);
@@ -730,3 +741,4 @@ void cl_set_cleanup(void (*cleanup)(void *), void *opaque)
#include "clar/fixtures.h"
#include "clar/fs.h"
#include "clar/print.h"
+#include "clar/summary.h"
diff --git a/tests/clar/summary.h b/tests/clar/summary.h
new file mode 100644
index 0000000..e3a5d78
--- /dev/null
+++ b/tests/clar/summary.h
@@ -0,0 +1,98 @@
+
+#include <stdio.h>
+#include <time.h>
+
+static FILE *summary;
+
+int clar_summary_close_tag(const char *tag, int indent)
+{
+ const char *indt;
+
+ if (indent == 0) indt = "";
+ else if (indent == 1) indt = "\t";
+ else indt = "\t\t";
+
+ return fprintf(summary, "%s</%s>\n", indt, tag);
+}
+
+int clar_summary_testsuites(void)
+{
+ return fprintf(summary, "<testsuites>\n");
+}
+
+int clar_summary_testsuite(int idn, const char *name, const char *pkg, time_t timestamp, double time, int test_count, int fail_count, int error_count)
+{
+ struct tm *tm = localtime(×tamp);
+ char iso_dt[20];
+
+ if (strftime(iso_dt, sizeof(iso_dt), "%FT%T", tm) == 0)
+ return -1;
+
+ return fprintf(summary, "\t<testsuite "
+ " id=\"%d\""
+ " name=\"%s\""
+ " package=\"%s\""
+ " hostname=\"localhost\""
+ " timestamp=\"%s\""
+ " time=\"%.2f\""
+ " tests=\"%d\""
+ " failures=\"%d\""
+ " errors=\"%d\">\n",
+ idn, name, pkg, iso_dt, time, test_count, fail_count, error_count);
+}
+
+int clar_summary_testcase(const char *name, const char *classname, double time)
+{
+ return fprintf(summary, "\t\t<testcase name=\"%s\" classname=\"%s\" time=\"%.2f\">\n", name, classname, time);
+}
+
+int clar_summary_failure(const char *type, const char *message, const char *desc)
+{
+ return fprintf(summary, "\t\t\t<failure type=\"%s\"><![CDATA[%s\n%s]]></failure>\n", type, message, desc);
+}
+
+void clar_summary_write(void)
+{
+ struct clar_report *report;
+ const char *last_suite = NULL;
+ char wd[1024];
+
+ summary = fopen("summary.xml", "w");
+ if (!summary) {
+ printf("failed to open summary.xml for writing\n");
+ return;
+ }
+
+ clar_summary_testsuites();
+
+ report = _clar.reports;
+ while (report != NULL) {
+ struct clar_error *error = report->errors;
+
+ if (last_suite == NULL || strcmp(last_suite, report->suite) != 0) {
+ clar_summary_testsuite(0, report->suite, "", time(NULL), 0, _clar.tests_ran, _clar.total_errors, 0);
+ }
+
+ last_suite = report->suite;
+
+ clar_summary_testcase(report->test, "what", 0);
+
+ while (error != NULL) {
+ clar_summary_failure("assert", error->error_msg, error->description);
+ error = error->next;
+ }
+
+ clar_summary_close_tag("testcase", 2);
+
+ report = report->next;
+
+ if (!report || strcmp(last_suite, report->suite) != 0)
+ clar_summary_close_tag("testsuite", 1);
+ }
+
+ clar_summary_close_tag("testsuites", 0);
+
+ fclose(summary);
+
+ printf("written summary file to %s\n", getcwd((char *)&wd, sizeof(wd)));
+}