Tuesday, June 10, 2008

Implement your own NUnit TestRunner - Part 2

After I blogged about creating a basic NUnit TestRunner in Part 1 of this series, this is the follow-up that shows how to extract and display the test results in a simple fashion.
Basically the TestResult object that is being returned from the Run method of the TestRunner contains probably most of the information you need.
Here is the Code:



Imports System.Text
Imports System.Xml
Imports System.IO
Imports System.Reflection
Imports System.Resources
Imports NUnit.Core
Imports NUnit.Util


Public Class Form1

   Private Sub btnRunTests_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRunTests.Click

     Dim objTestRunner As TestRunner = Nothing

     objTestRunner = New RemoteTestRunner()

     Dim strMyFileName As String = Assembly.GetExecutingAssembly().Location
     Dim objPackage As TestPackage = New TestPackage(strMyFileName)


     objTestRunner.Load(objPackage)


     'run the test and create the result
     Dim objTestResult As TestResult = objTestRunner.Run(New NullListener)

     'get the result summary in XML format
     Dim strResultSummary As String = CreateXmlOutput(objTestResult)

     'now transform the XML into more display-friendly code using the default style sheet
     Dim sbResultSummary As New StringBuilder

     Dim objXFormReader As XmlTextReader = GetTransformReader(Nothing)
     Dim objXMLXform As XmlResultTransform = New XmlResultTransform(objXFormReader)
     objXMLXform.Transform(New StringReader(strResultSummary), New StringWriter(sbResultSummary))



     txtResults.Text = sbResultSummary.ToString()


   End Sub


   Private Shared Function CreateXmlOutput(ByVal objResult As TestResult) As String

     Dim sbXML As New StringBuilder()
     Dim objResultVisitor As New XmlResultVisitor(New StringWriter(sbXML), objResult)
     objResult.Accept(objResultVisitor)
     objResultVisitor.Write()

     Return sbXML.ToString()

   End Function 'CreateXmlOutput


   Private Shared Function GetTransformReader(ByVal strXSLFileName As String) As XmlTextReader

     Dim objXMLReader As XmlTextReader = Nothing
     If String.IsNullOrEmpty(strXSLFileName) Then
       Dim objNUnitAssembly As Assembly = Assembly.GetAssembly(GetType(XmlResultVisitor))
       Dim objResourceMgr As New ResourceManager("NUnit.Util.Transform", objNUnitAssembly)
       Dim strXmlData As String = CStr(objResourceMgr.GetObject("Summary.xslt"))

       objXMLReader = New XmlTextReader(New StringReader(strXmlData))
     Else
       Dim objXsltInfo As New FileInfo(strXSLFileName)
       If Not objXsltInfo.Exists Then
         Throw New FileNotFoundException("Transform file: {0} does not exist", objXsltInfo.FullName)
         objXMLReader = Nothing
       Else
         objXMLReader = New XmlTextReader(objXsltInfo.FullName)
       End If
     End If

     Return objXMLReader
   End Function 'GetTransformReader


End Class


this will then show the results in a user-friendly form in the text box txtResults.
Where this comes in handy is if you have a WinForms App and you want to run your Unit tests as part of the WinForms app without having to launch the NUnit GUI (or Console).
This is admittedly a very simple implementation, does not have a lot of the bells and whistles of a more graphical UI, but it tells you which tests failed and how long they took and where they failed.

No comments: