An easy to use Unity 3D library for creating illustrated Interactive Fiction games and more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

303 lines
10 KiB

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Security;
using System.Text;
using UnityEngine;
namespace UnityTest
{
public class XmlResultWriter
{
private readonly StringBuilder m_ResultWriter = new StringBuilder();
private int m_Indend;
private readonly string m_SuiteName;
private readonly ITestResult[] m_Results;
string m_Platform;
public XmlResultWriter(string suiteName, string platform, ITestResult[] results)
{
m_SuiteName = suiteName;
m_Results = results;
m_Platform = platform;
}
private const string k_NUnitVersion = "2.6.2-Unity";
public string GetTestResult()
{
InitializeXmlFile(m_SuiteName, new ResultSummarizer(m_Results));
foreach (var result in m_Results)
{
WriteResultElement(result);
}
TerminateXmlFile();
return m_ResultWriter.ToString();
}
private void InitializeXmlFile(string resultsName, ResultSummarizer summaryResults)
{
WriteHeader();
DateTime now = DateTime.Now;
var attributes = new Dictionary<string, string>
{
{"name", "Unity Tests"},
{"total", summaryResults.TestsRun.ToString()},
{"errors", summaryResults.Errors.ToString()},
{"failures", summaryResults.Failures.ToString()},
{"not-run", summaryResults.TestsNotRun.ToString()},
{"inconclusive", summaryResults.Inconclusive.ToString()},
{"ignored", summaryResults.Ignored.ToString()},
{"skipped", summaryResults.Skipped.ToString()},
{"invalid", summaryResults.NotRunnable.ToString()},
{"date", now.ToString("yyyy-MM-dd")},
{"time", now.ToString("HH:mm:ss")}
};
WriteOpeningElement("test-results", attributes);
WriteEnvironment(m_Platform);
WriteCultureInfo();
WriteTestSuite(resultsName, summaryResults);
WriteOpeningElement("results");
}
private void WriteOpeningElement(string elementName)
{
WriteOpeningElement(elementName, new Dictionary<string, string>());
}
private void WriteOpeningElement(string elementName, Dictionary<string, string> attributes)
{
WriteOpeningElement(elementName, attributes, false);
}
private void WriteOpeningElement(string elementName, Dictionary<string, string> attributes, bool closeImmediatelly)
{
WriteIndend();
m_Indend++;
m_ResultWriter.Append("<");
m_ResultWriter.Append(elementName);
foreach (var attribute in attributes)
{
m_ResultWriter.AppendFormat(" {0}=\"{1}\"", attribute.Key, SecurityElement.Escape(attribute.Value));
}
if (closeImmediatelly)
{
m_ResultWriter.Append(" /");
m_Indend--;
}
m_ResultWriter.AppendLine(">");
}
private void WriteIndend()
{
for (int i = 0; i < m_Indend; i++)
{
m_ResultWriter.Append(" ");
}
}
private void WriteClosingElement(string elementName)
{
m_Indend--;
WriteIndend();
m_ResultWriter.AppendLine("</" + elementName + ">");
}
private void WriteHeader()
{
m_ResultWriter.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
m_ResultWriter.AppendLine("<!--This file represents the results of running a test suite-->");
}
static string GetEnvironmentUserName()
{
return Environment.UserName;
}
static string GetEnvironmentMachineName()
{
return Environment.MachineName;
}
static string GetEnvironmentUserDomainName()
{
return Environment.UserDomainName;
}
static string GetEnvironmentVersion()
{
return Environment.Version.ToString();
}
static string GetEnvironmentOSVersion()
{
return Environment.OSVersion.ToString();
}
static string GetEnvironmentOSVersionPlatform()
{
return Environment.OSVersion.Platform.ToString();
}
static string EnvironmentGetCurrentDirectory()
{
return Environment.CurrentDirectory;
}
private void WriteEnvironment( string targetPlatform )
{
var attributes = new Dictionary<string, string>
{
{"nunit-version", k_NUnitVersion},
{"clr-version", GetEnvironmentVersion()},
{"os-version", GetEnvironmentOSVersion()},
{"platform", GetEnvironmentOSVersionPlatform()},
{"cwd", EnvironmentGetCurrentDirectory()},
{"machine-name", GetEnvironmentMachineName()},
{"user", GetEnvironmentUserName()},
{"user-domain", GetEnvironmentUserDomainName()},
{"unity-version", Application.unityVersion},
{"unity-platform", targetPlatform}
};
WriteOpeningElement("environment", attributes, true);
}
private void WriteCultureInfo()
{
var attributes = new Dictionary<string, string>
{
{"current-culture", CultureInfo.CurrentCulture.ToString()},
{"current-uiculture", CultureInfo.CurrentUICulture.ToString()}
};
WriteOpeningElement("culture-info", attributes, true);
}
private void WriteTestSuite(string resultsName, ResultSummarizer summaryResults)
{
var attributes = new Dictionary<string, string>
{
{"name", resultsName},
{"type", "Assembly"},
{"executed", "True"},
{"result", summaryResults.Success ? "Success" : "Failure"},
{"success", summaryResults.Success ? "True" : "False"},
{"time", summaryResults.Duration.ToString("#####0.000", NumberFormatInfo.InvariantInfo)}
};
WriteOpeningElement("test-suite", attributes);
}
private void WriteResultElement(ITestResult result)
{
StartTestElement(result);
switch (result.ResultState)
{
case TestResultState.Ignored:
case TestResultState.NotRunnable:
case TestResultState.Skipped:
WriteReasonElement(result);
break;
case TestResultState.Failure:
case TestResultState.Error:
case TestResultState.Cancelled:
WriteFailureElement(result);
break;
case TestResultState.Success:
case TestResultState.Inconclusive:
if (result.Message != null)
WriteReasonElement(result);
break;
};
WriteClosingElement("test-case");
}
private void TerminateXmlFile()
{
WriteClosingElement("results");
WriteClosingElement("test-suite");
WriteClosingElement("test-results");
}
#region Element Creation Helpers
private void StartTestElement(ITestResult result)
{
var attributes = new Dictionary<string, string>
{
{"name", result.FullName},
{"executed", result.Executed.ToString()}
};
string resultString;
switch (result.ResultState)
{
case TestResultState.Cancelled:
resultString = TestResultState.Failure.ToString();
break;
default:
resultString = result.ResultState.ToString();
break;
}
attributes.Add("result", resultString);
if (result.Executed)
{
attributes.Add("success", result.IsSuccess.ToString());
attributes.Add("time", result.Duration.ToString("#####0.000", NumberFormatInfo.InvariantInfo));
}
WriteOpeningElement("test-case", attributes);
}
private void WriteReasonElement(ITestResult result)
{
WriteOpeningElement("reason");
WriteOpeningElement("message");
WriteCData(result.Message);
WriteClosingElement("message");
WriteClosingElement("reason");
}
private void WriteFailureElement(ITestResult result)
{
WriteOpeningElement("failure");
WriteOpeningElement("message");
WriteCData(result.Message);
WriteClosingElement("message");
WriteOpeningElement("stack-trace");
if (result.StackTrace != null)
WriteCData(StackTraceFilter.Filter(result.StackTrace));
WriteClosingElement("stack-trace");
WriteClosingElement("failure");
}
#endregion
private void WriteCData(string text)
{
if (string.IsNullOrEmpty(text))
return;
m_ResultWriter.AppendFormat("<![CDATA[{0}]]>", text);
m_ResultWriter.AppendLine();
}
public void WriteToFile(string resultDestiantion, string resultFileName)
{
try
{
var path = Path.Combine(resultDestiantion, resultFileName);
Debug.Log("Saving results in " + path);
File.WriteAllText(path, GetTestResult(), Encoding.UTF8);
}
catch (Exception e)
{
Debug.LogError("Error while opening file");
Debug.LogException(e);
}
}
}
}