junit_report/
lib.rs
1mod collections;
51mod reports;
52
53pub use quick_xml::Error;
54pub use time::{macros::datetime, Duration, OffsetDateTime};
55
56pub use crate::{
57 collections::{TestCase, TestCaseBuilder, TestResult, TestSuite, TestSuiteBuilder},
58 reports::{Report, ReportBuilder},
59};
60
61#[cfg(test)]
62mod tests {
63 use crate::{
64 datetime, Duration, Report, ReportBuilder, TestCase, TestCaseBuilder, TestSuite,
65 TestSuiteBuilder,
66 };
67
68 #[test]
69 fn empty_testsuites() {
70 let r = Report::new();
71
72 let mut out: Vec<u8> = Vec::new();
73
74 r.write_xml(&mut out).unwrap();
75
76 assert_eq!(
78 String::from_utf8(out).unwrap(),
79 "<?xml version=\"1.0\" encoding=\"utf-8\"?><testsuites/>",
80 );
81 }
82
83 #[test]
84 fn add_empty_testsuite_single() {
85 let timestamp = datetime!(1970-01-01 01:01 UTC);
86
87 let ts1 = TestSuiteBuilder::new("ts1")
88 .set_timestamp(timestamp)
89 .build();
90 let mut tsb = TestSuiteBuilder::new("ts2");
91 tsb.set_timestamp(timestamp);
92 let ts2 = tsb.build();
93
94 let r = ReportBuilder::new()
95 .add_testsuite(ts1)
96 .add_testsuite(ts2)
97 .build();
98
99 let mut out: Vec<u8> = Vec::new();
100
101 r.write_xml(&mut out).unwrap();
102
103 assert_eq!(
105 String::from_utf8(out).unwrap(),
106 "\
107<?xml version=\"1.0\" encoding=\"utf-8\"?>\
108<testsuites>\
109 <testsuite id=\"0\" name=\"ts1\" package=\"testsuite/ts1\" tests=\"0\" errors=\"0\" failures=\"0\" hostname=\"localhost\" timestamp=\"1970-01-01T01:01:00Z\" time=\"0\"/>\
110 <testsuite id=\"1\" name=\"ts2\" package=\"testsuite/ts2\" tests=\"0\" errors=\"0\" failures=\"0\" hostname=\"localhost\" timestamp=\"1970-01-01T01:01:00Z\" time=\"0\"/>\
111</testsuites>",
112 );
113 }
114
115 #[test]
116 fn add_empty_testsuite_single_with_sysout() {
117 let timestamp = datetime!(1970-01-01 01:01 UTC);
118
119 let ts1 = TestSuiteBuilder::new("ts1")
120 .set_system_out("Test sysout")
121 .set_timestamp(timestamp)
122 .build();
123
124 let r = ReportBuilder::new().add_testsuite(ts1).build();
125
126 let mut out: Vec<u8> = Vec::new();
127
128 r.write_xml(&mut out).unwrap();
129
130 assert_eq!(
132 String::from_utf8(out).unwrap(),
133 "\
134<?xml version=\"1.0\" encoding=\"utf-8\"?>\
135<testsuites>\
136 <testsuite id=\"0\" name=\"ts1\" package=\"testsuite/ts1\" tests=\"0\" errors=\"0\" failures=\"0\" hostname=\"localhost\" timestamp=\"1970-01-01T01:01:00Z\" time=\"0\">\
137 <system-out><![CDATA[Test sysout]]></system-out>\
138 </testsuite>\
139</testsuites>",
140 );
141 }
142
143 #[test]
144 fn add_empty_testsuite_single_with_syserror() {
145 let timestamp = datetime!(1970-01-01 01:01 UTC);
146
147 let ts1 = TestSuiteBuilder::new("ts1")
148 .set_system_err("Test syserror")
149 .set_timestamp(timestamp)
150 .build();
151
152 let r = ReportBuilder::new().add_testsuite(ts1).build();
153
154 let mut out: Vec<u8> = Vec::new();
155
156 r.write_xml(&mut out).unwrap();
157
158 assert_eq!(
160 String::from_utf8(out).unwrap(),
161 "\
162<?xml version=\"1.0\" encoding=\"utf-8\"?>\
163<testsuites>\
164 <testsuite id=\"0\" name=\"ts1\" package=\"testsuite/ts1\" tests=\"0\" errors=\"0\" failures=\"0\" hostname=\"localhost\" timestamp=\"1970-01-01T01:01:00Z\" time=\"0\">\
165 <system-err><![CDATA[Test syserror]]></system-err>\
166 </testsuite>\
167</testsuites>",
168 );
169 }
170
171 #[test]
172 fn add_empty_testsuite_batch() {
173 let timestamp = datetime!(1970-01-01 01:01 UTC);
174
175 let ts1 = TestSuiteBuilder::new("ts1")
176 .set_timestamp(timestamp)
177 .build();
178 let ts2 = TestSuiteBuilder::new("ts2")
179 .set_timestamp(timestamp)
180 .build();
181
182 let v = vec![ts1, ts2];
183
184 let r = ReportBuilder::new().add_testsuites(v).build();
185
186 let mut out: Vec<u8> = Vec::new();
187
188 r.write_xml(&mut out).unwrap();
189
190 assert_eq!(
192 String::from_utf8(out).unwrap(),
193 "\
194<?xml version=\"1.0\" encoding=\"utf-8\"?>\
195<testsuites>\
196 <testsuite id=\"0\" name=\"ts1\" package=\"testsuite/ts1\" tests=\"0\" errors=\"0\" failures=\"0\" hostname=\"localhost\" timestamp=\"1970-01-01T01:01:00Z\" time=\"0\"/>\
197 <testsuite id=\"1\" name=\"ts2\" package=\"testsuite/ts2\" tests=\"0\" errors=\"0\" failures=\"0\" hostname=\"localhost\" timestamp=\"1970-01-01T01:01:00Z\" time=\"0\"/>\
198</testsuites>",
199 );
200 }
201
202 #[test]
203 fn count_tests() {
204 let mut ts = TestSuite::new("ts");
205
206 let tc1 = TestCase::success("mysuccess", Duration::milliseconds(6001));
207 let tc2 = TestCase::error(
208 "myerror",
209 Duration::seconds(6),
210 "Some Error",
211 "An Error happened",
212 );
213 let tc3 = TestCase::failure(
214 "myerror",
215 Duration::seconds(6),
216 "Some failure",
217 "A Failure happened",
218 );
219
220 assert_eq!(0, ts.tests());
221 assert_eq!(0, ts.errors());
222 assert_eq!(0, ts.failures());
223
224 ts.add_testcase(tc1);
225
226 assert_eq!(1, ts.tests());
227 assert_eq!(0, ts.errors());
228 assert_eq!(0, ts.failures());
229
230 ts.add_testcase(tc2);
231
232 assert_eq!(2, ts.tests());
233 assert_eq!(1, ts.errors());
234 assert_eq!(0, ts.failures());
235
236 ts.add_testcase(tc3);
237
238 assert_eq!(3, ts.tests());
239 assert_eq!(1, ts.errors());
240 assert_eq!(1, ts.failures());
241 }
242
243 #[test]
244 fn testcases_no_stdout_stderr() {
245 let timestamp = datetime!(1970-01-01 01:01 UTC);
246
247 let test_success = TestCaseBuilder::success("good test", Duration::milliseconds(15001))
248 .set_classname("MyClass")
249 .set_filepath("./foo.rs")
250 .build();
251 let test_error = TestCaseBuilder::error(
252 "error test",
253 Duration::seconds(5),
254 "git error",
255 "unable to fetch",
256 )
257 .build();
258 let test_failure = TestCaseBuilder::failure(
259 "failure test",
260 Duration::seconds(10),
261 "assert_eq",
262 "not equal",
263 )
264 .build();
265
266 let ts1 = TestSuiteBuilder::new("ts1")
267 .set_timestamp(timestamp)
268 .build();
269 let ts2 = TestSuiteBuilder::new("ts2")
270 .set_timestamp(timestamp)
271 .add_testcase(test_success)
272 .add_testcase(test_error)
273 .add_testcase(test_failure)
274 .build();
275
276 let r = ReportBuilder::new()
277 .add_testsuite(ts1)
278 .add_testsuite(ts2)
279 .build();
280
281 let mut out: Vec<u8> = Vec::new();
282
283 r.write_xml(&mut out).unwrap();
284
285 assert_eq!(
287 String::from_utf8(out).unwrap(),
288 "\
289<?xml version=\"1.0\" encoding=\"utf-8\"?>\
290<testsuites>\
291 <testsuite id=\"0\" name=\"ts1\" package=\"testsuite/ts1\" tests=\"0\" errors=\"0\" failures=\"0\" hostname=\"localhost\" timestamp=\"1970-01-01T01:01:00Z\" time=\"0\"/>\
292 <testsuite id=\"1\" name=\"ts2\" package=\"testsuite/ts2\" tests=\"3\" errors=\"1\" failures=\"1\" hostname=\"localhost\" timestamp=\"1970-01-01T01:01:00Z\" time=\"30.001\">\
293 <testcase name=\"good test\" time=\"15.001\" classname=\"MyClass\" file=\"./foo.rs\"/>\
294 <testcase name=\"error test\" time=\"5\">\
295 <error type=\"git error\" message=\"unable to fetch\"/>\
296 </testcase>\
297 <testcase name=\"failure test\" time=\"10\">\
298 <failure type=\"assert_eq\" message=\"not equal\"/>\
299 </testcase>\
300 </testsuite>\
301</testsuites>",
302 );
303 }
304
305 #[test]
306 fn test_cases_with_sysout_and_syserr() {
307 let timestamp = datetime!(1970-01-01 01:01 UTC);
308
309 let test_success = TestCaseBuilder::success("good test", Duration::milliseconds(15001))
310 .set_classname("MyClass")
311 .set_filepath("./foo.rs")
312 .set_system_out("Some sysout message")
313 .build();
314 let test_error = TestCaseBuilder::error(
315 "error test",
316 Duration::seconds(5),
317 "git error",
318 "unable to fetch",
319 )
320 .set_system_err("Some syserror message")
321 .build();
322 let test_failure = TestCaseBuilder::failure(
323 "failure test",
324 Duration::seconds(10),
325 "assert_eq",
326 "not equal",
327 )
328 .set_system_out("System out or error message")
329 .set_system_err("Another system error message")
330 .build();
331
332 let ts1 = TestSuiteBuilder::new("ts1")
333 .set_timestamp(timestamp)
334 .build();
335 let ts2 = TestSuiteBuilder::new("ts2")
336 .set_timestamp(timestamp)
337 .add_testcase(test_success)
338 .add_testcase(test_error)
339 .add_testcase(test_failure)
340 .build();
341
342 let r = ReportBuilder::new()
343 .add_testsuite(ts1)
344 .add_testsuite(ts2)
345 .build();
346
347 let mut out: Vec<u8> = Vec::new();
348
349 r.write_xml(&mut out).unwrap();
350
351 assert_eq!(
353 String::from_utf8(out).unwrap(),
354 "\
355<?xml version=\"1.0\" encoding=\"utf-8\"?>\
356<testsuites>\
357 <testsuite id=\"0\" name=\"ts1\" package=\"testsuite/ts1\" tests=\"0\" errors=\"0\" failures=\"0\" hostname=\"localhost\" timestamp=\"1970-01-01T01:01:00Z\" time=\"0\"/>\
358 <testsuite id=\"1\" name=\"ts2\" package=\"testsuite/ts2\" tests=\"3\" errors=\"1\" failures=\"1\" hostname=\"localhost\" timestamp=\"1970-01-01T01:01:00Z\" time=\"30.001\">\
359 <testcase name=\"good test\" time=\"15.001\" classname=\"MyClass\" file=\"./foo.rs\">\
360 <system-out><![CDATA[Some sysout message]]></system-out>\
361 </testcase>\
362 <testcase name=\"error test\" time=\"5\">\
363 <error type=\"git error\" message=\"unable to fetch\"><![CDATA[Some syserror message]]></error>\
364 </testcase>\
365 <testcase name=\"failure test\" time=\"10\">\
366 <failure type=\"assert_eq\" message=\"not equal\"><![CDATA[System out or error message]]><![CDATA[Another system error message]]></failure>\
367 </testcase>\
368 </testsuite>\
369</testsuites>",
370 );
371 }
372}