1 // ****************************************************************
\r
2 // This is free software licensed under the NUnit license. You
\r
3 // may obtain a copy of the license as well as information regarding
\r
4 // copyright ownership at http://nunit.org/?p=license&r=2.4.
\r
5 // ****************************************************************
\r
10 using System.Globalization;
\r
13 using System.Reflection;
\r
17 /// Summary description for XmlResultVisitor.
\r
19 public class XmlResultVisitor : ResultVisitor
\r
21 private XmlTextWriter xmlWriter;
\r
22 private TextWriter writer;
\r
23 private MemoryStream memoryStream;
\r
25 public XmlResultVisitor(string fileName, TestResult result)
\r
27 xmlWriter = new XmlTextWriter( new StreamWriter(fileName, false, System.Text.Encoding.UTF8) );
\r
31 public XmlResultVisitor( TextWriter writer, TestResult result )
\r
33 this.memoryStream = new MemoryStream();
\r
34 this.writer = writer;
\r
35 this.xmlWriter = new XmlTextWriter( new StreamWriter( memoryStream, System.Text.Encoding.UTF8 ) );
\r
36 Initialize( result );
\r
39 private void Initialize(TestResult result)
\r
41 ResultSummarizer summaryResults = new ResultSummarizer(result);
\r
43 xmlWriter.Formatting = Formatting.Indented;
\r
44 xmlWriter.WriteStartDocument(false);
\r
45 xmlWriter.WriteComment("This file represents the results of running a test suite");
\r
47 xmlWriter.WriteStartElement("test-results");
\r
49 xmlWriter.WriteAttributeString("name", summaryResults.Name);
\r
50 xmlWriter.WriteAttributeString("total", summaryResults.ResultCount.ToString());
\r
51 xmlWriter.WriteAttributeString("failures", summaryResults.FailureCount.ToString());
\r
52 xmlWriter.WriteAttributeString("not-run", summaryResults.TestsNotRun.ToString());
\r
54 DateTime now = DateTime.Now;
\r
55 xmlWriter.WriteAttributeString("date", XmlConvert.ToString( now, "yyyy-MM-dd" ) );
\r
56 xmlWriter.WriteAttributeString("time", XmlConvert.ToString( now, "HH:mm:ss" ));
\r
61 private void WriteCultureInfo() {
\r
62 xmlWriter.WriteStartElement("culture-info");
\r
63 xmlWriter.WriteAttributeString("current-culture",
\r
64 CultureInfo.CurrentCulture.ToString());
\r
65 xmlWriter.WriteAttributeString("current-uiculture",
\r
66 CultureInfo.CurrentUICulture.ToString());
\r
67 xmlWriter.WriteEndElement();
\r
70 private void WriteEnvironment() {
\r
71 xmlWriter.WriteStartElement("environment");
\r
72 xmlWriter.WriteAttributeString("nunit-version",
\r
73 Assembly.GetExecutingAssembly().GetName().Version.ToString());
\r
74 xmlWriter.WriteAttributeString("clr-version",
\r
75 Environment.Version.ToString());
\r
76 xmlWriter.WriteAttributeString("os-version",
\r
77 Environment.OSVersion.ToString());
\r
78 xmlWriter.WriteAttributeString("platform",
\r
79 Environment.OSVersion.Platform.ToString());
\r
80 xmlWriter.WriteAttributeString("cwd",
\r
81 Environment.CurrentDirectory);
\r
82 xmlWriter.WriteAttributeString("machine-name",
\r
83 Environment.MachineName);
\r
84 xmlWriter.WriteAttributeString("user",
\r
85 Environment.UserName);
\r
86 xmlWriter.WriteAttributeString("user-domain",
\r
87 Environment.UserDomainName);
\r
88 xmlWriter.WriteEndElement();
\r
91 public void Visit(TestCaseResult caseResult)
\r
93 xmlWriter.WriteStartElement("test-case");
\r
94 xmlWriter.WriteAttributeString("name",caseResult.Name);
\r
96 if(caseResult.Description != null)
\r
97 xmlWriter.WriteAttributeString("description", caseResult.Description);
\r
99 xmlWriter.WriteAttributeString("executed", caseResult.Executed.ToString());
\r
100 if(caseResult.Executed)
\r
102 xmlWriter.WriteAttributeString("success", caseResult.IsSuccess.ToString() );
\r
104 xmlWriter.WriteAttributeString("time", caseResult.Time.ToString("#####0.000", NumberFormatInfo.InvariantInfo));
\r
106 xmlWriter.WriteAttributeString("asserts", caseResult.AssertCount.ToString() );
\r
107 WriteCategories(caseResult);
\r
108 WriteProperties(caseResult);
\r
109 if(caseResult.IsFailure)
\r
111 if(caseResult.IsFailure)
\r
112 xmlWriter.WriteStartElement("failure");
\r
114 xmlWriter.WriteStartElement("error");
\r
116 xmlWriter.WriteStartElement("message");
\r
117 xmlWriter.WriteCData( EncodeCData( caseResult.Message ) );
\r
118 xmlWriter.WriteEndElement();
\r
120 xmlWriter.WriteStartElement("stack-trace");
\r
121 if(caseResult.StackTrace != null)
\r
122 xmlWriter.WriteCData( EncodeCData( StackTraceFilter.Filter( caseResult.StackTrace ) ) );
\r
123 xmlWriter.WriteEndElement();
\r
125 xmlWriter.WriteEndElement();
\r
131 WriteCategories(caseResult);
\r
132 WriteProperties(caseResult);
\r
133 xmlWriter.WriteStartElement("reason");
\r
134 xmlWriter.WriteStartElement("message");
\r
135 xmlWriter.WriteCData(caseResult.Message);
\r
136 xmlWriter.WriteEndElement();
\r
137 xmlWriter.WriteEndElement();
\r
140 xmlWriter.WriteEndElement();
\r
144 /// Makes string safe for xml parsing, replacing control chars with '?'
\r
146 /// <param name="encodedString">string to make safe</param>
\r
147 /// <returns>xml safe string</returns>
\r
148 private static string CharacterSafeString(string encodedString)
\r
150 /*The default code page for the system will be used.
\r
151 Since all code pages use the same lower 128 bytes, this should be sufficient
\r
152 for finding uprintable control characters that make the xslt processor error.
\r
153 We use characters encoded by the default code page to avoid mistaking bytes as
\r
154 individual characters on non-latin code pages.*/
\r
155 char[] encodedChars = System.Text.Encoding.Default.GetChars(System.Text.Encoding.Default.GetBytes(encodedString));
\r
157 System.Collections.ArrayList pos = new System.Collections.ArrayList();
\r
158 for(int x = 0 ; x < encodedChars.Length ; x++)
\r
160 char currentChar = encodedChars[x];
\r
161 //unprintable characters are below 0x20 in Unicode tables
\r
162 //some control characters are acceptable. (carriage return 0x0D, line feed 0x0A, horizontal tab 0x09)
\r
163 if(currentChar < 32 && (currentChar != 9 && currentChar != 10 && currentChar != 13))
\r
165 //save the array index for later replacement.
\r
169 foreach(int index in pos)
\r
171 encodedChars[index] = '?';//replace unprintable control characters with ?(3F)
\r
173 return System.Text.Encoding.Default.GetString(System.Text.Encoding.Default.GetBytes(encodedChars));
\r
176 private string EncodeCData( string text )
\r
178 return CharacterSafeString( text ).Replace( "]]>", "]]>" );
\r
181 public void WriteCategories(TestResult result)
\r
183 if (result.Test.Categories != null && result.Test.Categories.Count > 0)
\r
185 xmlWriter.WriteStartElement("categories");
\r
186 foreach (string category in result.Test.Categories)
\r
188 xmlWriter.WriteStartElement("category");
\r
189 xmlWriter.WriteAttributeString("name", category);
\r
190 xmlWriter.WriteEndElement();
\r
192 xmlWriter.WriteEndElement();
\r
196 public void WriteProperties(TestResult result)
\r
198 if (result.Test.Properties != null && result.Test.Properties.Count > 0)
\r
200 xmlWriter.WriteStartElement("properties");
\r
201 foreach (string key in result.Test.Properties.Keys)
\r
203 xmlWriter.WriteStartElement("property");
\r
204 xmlWriter.WriteAttributeString("name", key);
\r
205 xmlWriter.WriteAttributeString("value", result.Test.Properties[key].ToString() );
\r
206 xmlWriter.WriteEndElement();
\r
208 xmlWriter.WriteEndElement();
\r
212 public void Visit(TestSuiteResult suiteResult)
\r
214 xmlWriter.WriteStartElement("test-suite");
\r
215 xmlWriter.WriteAttributeString("name",suiteResult.Name);
\r
216 if(suiteResult.Description != null)
\r
217 xmlWriter.WriteAttributeString("description", suiteResult.Description);
\r
219 xmlWriter.WriteAttributeString("success", suiteResult.IsSuccess.ToString());
\r
220 xmlWriter.WriteAttributeString("time", suiteResult.Time.ToString("#####0.000", NumberFormatInfo.InvariantInfo));
\r
221 xmlWriter.WriteAttributeString("asserts", suiteResult.AssertCount.ToString() );
\r
223 WriteCategories(suiteResult);
\r
224 WriteProperties(suiteResult);
\r
226 if ( suiteResult.IsFailure && suiteResult.FailureSite == FailureSite.SetUp )
\r
228 xmlWriter.WriteStartElement("failure");
\r
230 xmlWriter.WriteStartElement("message");
\r
231 xmlWriter.WriteCData( EncodeCData( suiteResult.Message ) );
\r
232 xmlWriter.WriteEndElement();
\r
234 xmlWriter.WriteStartElement("stack-trace");
\r
235 if(suiteResult.StackTrace != null)
\r
236 xmlWriter.WriteCData( EncodeCData( StackTraceFilter.Filter( suiteResult.StackTrace ) ) );
\r
237 xmlWriter.WriteEndElement();
\r
239 xmlWriter.WriteEndElement();
\r
242 xmlWriter.WriteStartElement("results");
\r
243 foreach (TestResult result in suiteResult.Results)
\r
245 result.Accept(this);
\r
247 xmlWriter.WriteEndElement();
\r
249 xmlWriter.WriteEndElement();
\r
252 public void Write()
\r
256 xmlWriter.WriteEndElement();
\r
257 xmlWriter.WriteEndDocument();
\r
260 if ( memoryStream != null && writer != null )
\r
262 memoryStream.Position = 0;
\r
263 using ( StreamReader rdr = new StreamReader( memoryStream ) )
\r
265 writer.Write( rdr.ReadToEnd() );
\r