2 using System
.Collections
.Generic
;
9 public class NUnitReport
11 private static string input_dir
= string.Empty
;
12 private static string output_file
= string.Empty
;
14 static void Main (string[] args
)
16 if (args
.Length
!= 2) {
17 Console
.WriteLine ("Expected Usage:");
18 Console
.WriteLine (" mono NUnitReport.exe input_directory output_file");
22 // Get our input directory and our output file
24 output_file
= args
[1];
26 // Start the output file
27 StreamWriter sw
= new StreamWriter (output_file
);
35 // Loop through the inputs, outputting the results to the output file
36 foreach (string file
in Directory
.GetFiles (input_dir
)) {
39 Dictionary
<string, FailedTest
> failed_tests
= new Dictionary
<string,FailedTest
> ();
40 List
<string> ignored_tests
= new List
<string> ();
42 int tests_passed
= PopulateFailureTable (file
, failed_tests
, ignored_tests
);
44 fail_total
+= failed_tests
.Count
;
45 pass_total
+= tests_passed
;
46 run_total
+= failed_tests
.Count
+ tests_passed
;
48 if (failed_tests
.Count
> 0) {
49 sw
.WriteLine (" <tr class='errorrow' onclick=\"toggle('el{0}')\" onmouseover='highlight(this)' onmouseout='unhighlight(this)'>", assembly
);
50 sw
.WriteLine (@" <td><img src='Media/fail.png' /></td>");
52 sw
.WriteLine (@" <tr>");
53 sw
.WriteLine (@" <td><img src='Media/pass.png' /></td>");
56 sw
.WriteLine (@" <td>{0}</td>", Path
.GetFileName (file
));
57 sw
.WriteLine (@" <td>{0}</td>", failed_tests
.Count
);
58 sw
.WriteLine (@" <td>{0}</td>", tests_passed
);
59 sw
.WriteLine (@" <td>{0}</td>", tests_passed
+ failed_tests
.Count
);
60 sw
.WriteLine (@" </tr>");
62 if (failed_tests
.Count
== 0)
65 sw
.WriteLine (@" <tr id='el{0}' class='errorlist' style='display: none'>", assembly
);
66 sw
.WriteLine (@" <td></td>");
67 sw
.WriteLine (@" <td colspan='4'>");
68 sw
.WriteLine (@" <table cellpadding='2' cellspacing='0' width='100%'>");
72 foreach (FailedTest ft
in failed_tests
.Values
) {
73 sw
.WriteLine (" <tr onclick=\"toggle('as{0}ed{1}')\" onmouseover='highlight(this)' onmouseout='unhighlight(this)'>", assembly
, test_num
);
74 sw
.WriteLine (@" <td style='width: 17px'><img src='Media/bullet.png' /></td>");
75 sw
.WriteLine (@" <td>{0}</td>", ft
.Name
);
76 sw
.WriteLine (@" </tr>");
77 sw
.WriteLine (@" <tr id='as{0}ed{1}' class='errordetail' style='display: none'>", assembly
, test_num
);
78 sw
.WriteLine (@" <td></td>");
79 sw
.WriteLine (@" <td>");
80 sw
.WriteLine (@"{0}", ft
.Message
.Trim ().Trim ('\n').Replace ("\n", "<br/>"));
81 if (!string.IsNullOrEmpty (ft
.StackTrace
.Trim ()))
82 sw
.WriteLine (@"<br /><br /><strong>StackTrace:</strong><br />{0}", ft
.StackTrace
.Replace ("\n", "<br/>"));
83 sw
.WriteLine (@" </td>");
84 sw
.WriteLine (@" </tr>");
89 sw
.WriteLine (@" </table>");
90 sw
.WriteLine (@" </td>");
91 sw
.WriteLine (@" </tr>");
95 WriteTotals (sw
, fail_total
, pass_total
, run_total
);
97 // Finish up the output file
103 public static int PopulateFailureTable (string filename
, Dictionary
<string, FailedTest
> output
, List
<string> ignored
)
105 XmlDocument doc
= new XmlDocument ();
108 return FindTestCases (doc
.DocumentElement
, output
, ignored
);
111 public static int FindTestCases (XmlElement xe
, Dictionary
<string, FailedTest
> output
, List
<string> ignored
)
113 if (xe
.Name
== "test-case") {
114 OutputFailedTestCase (xe
, output
, ignored
);
120 foreach (XmlElement child
in xe
.ChildNodes
)
121 i
+= FindTestCases (child
, output
, ignored
);
126 public static void OutputFailedTestCase (XmlElement xe
, Dictionary
<string, FailedTest
> output
, List
<string> ignored
)
128 if (xe
.GetAttribute ("executed") == "False")
129 ignored
.Add (xe
.GetAttribute ("name"));
131 if (xe
.GetAttribute ("success") == "True" || xe
.GetAttribute ("executed") == "False")
134 FailedTest ft
= new FailedTest (xe
.GetAttribute ("name"), xe
["failure"]["message"].InnerText
, xe
["failure"]["stack-trace"].InnerText
);
135 output
[ft
.Name
] = ft
;
138 public static void StartReport (StreamWriter sw
)
140 sw
.WriteLine (@"<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transitional//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"">");
141 sw
.WriteLine (@"<html xmlns=""http://www.w3.org/1999/xhtml""><head>");
142 sw
.WriteLine (@"<title>Mono: Class Libraries NUnit Test Results</title>");
143 sw
.WriteLine (@"<link rel=""stylesheet"" type=""text/css"" href=""Media/style.css"" />");
144 sw
.WriteLine (@"<script type=""text/ecmascript"" src=""Media/scripts.js""></script></head>");
145 sw
.WriteLine (@"<body>");
146 sw
.WriteLine (@" <div class='header'>");
147 sw
.WriteLine (@" <div class='headerimage'>");
148 sw
.WriteLine (@" <img src='Media/rupert.png' width='48' height='48' />");
149 sw
.WriteLine (@" </div>");
150 sw
.WriteLine (@" <div class='headertext'>Class Libraries NUnit Test Results</div>");
151 sw
.WriteLine (@" </div>");
152 sw
.WriteLine (@" <div class='legend'>");
153 sw
.WriteLine (@" Generated:<br />");
154 sw
.WriteLine (@" {0}<br /><br />", DateTime
.Now
.ToString ());
155 sw
.WriteLine (@" Click on failure row for more details.<br /><br />");
156 sw
.WriteLine (@" Icons courtesy of <a href='http://www.famfamfam.com/lab/icons/silk'>famfamfam</a>");
157 sw
.WriteLine (@" </div>");
158 sw
.WriteLine (@" <table cellpadding='2' cellspacing='0' class='maintable'>");
159 sw
.WriteLine (@" <tr class='tableheader'>");
160 sw
.WriteLine (@" <td style='width: 17px'></td>");
161 sw
.WriteLine (@" <td>Tested Assembly</td>");
162 sw
.WriteLine (@" <td>Failed</td>");
163 sw
.WriteLine (@" <td>Passed</td>");
164 sw
.WriteLine (@" <td>Run</td>");
165 sw
.WriteLine (@" </tr>");
168 public static void WriteTotals (StreamWriter sw
, int failed
, int passed
, int run
)
170 sw
.WriteLine (@" <tr class='tabletotal'>");
171 sw
.WriteLine (@" <td style='width: 17px'></td>");
172 sw
.WriteLine (@" <td>Totals</td>");
173 sw
.WriteLine (@" <td>{0}</td>", failed
);
174 sw
.WriteLine (@" <td>{0}</td>", passed
);
175 sw
.WriteLine (@" <td>{0}</td>", run
);
176 sw
.WriteLine (@" </tr>");
179 public static void FinishReport (StreamWriter sw
)
181 sw
.WriteLine (@" </table>");
182 sw
.WriteLine (@"</body>");
183 sw
.WriteLine (@"</html>");