Here's the update necessary to fix this issue. What this allows is the
result formatters to access the underlying ITest instance being run by the
test runner. As you'll see, the changes necessary to do this are fairly
basic:

1- Add a Suite property to NUnitTest that access the ITest used
2- Add a single line to NUnitTestRunner to set the NUnitTest.Suite property
once the suite to run has been instantiated.
3- Change a couple of lines in XmlResultFormatter to if the TestSuite
underneath has a name and use that, or use the default "test".

What do you guys think?

I've attached the three modified files.
--
Tomas Restrepo
[EMAIL PROTECTED]
// NAnt - A .NET build tool
// Copyright (C) 2001-2002 Gerry Shaw
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Ian MacLean ([EMAIL PROTECTED])
// Gerry Shaw ([EMAIL PROTECTED])

using System;
using System.IO;
using System.Text;
using NUnit.Framework;
using System.Xml;

namespace SourceForge.NAnt.Tasks.NUnit {

        /// <summary>Prints detailed information in XML format about running 
tests.</summary>
        public class XmlResultFormatter : IResultFormatter      {
                                 
            const string ElementTestSuites = "testsuites";
            const string ElementTestSuite = "testsuite";
            const string ElementTestCase = "testcase";
            const string ElementError = "error";
            const string ElementFailure = "failure";              
            
            const string AttributePackage = "package";
            const string AttributeName = "name";
            const string AttributeTime = "time";
            const string AttributeErrors = "errors";
            const string AttributeFailures = "failures";
            const string AttributeTests = "tests";
            const string AttributeType = "type";
            const string AttributeMessage = "message";
                                    
            TextWriter _writer;
            
            // Document builder members
            XmlDocument _document;         
            XmlElement _suiteElement;
            XmlElement _currentTest;
            
            DateTime _testStartTime;
        
            public XmlResultFormatter() {
            _document = new XmlDocument();
            }
            
        public TextWriter Writer {
            get { return _writer; }
            set { _writer = value; }
        }
        
            //-------------------------------------------------------------
                // IResultFormatter interface methods
                //-------------------------------------------------------------

        /// <summary>Sets the Writer the formatter is supposed to write its results 
to.</summary>
        public void SetOutput(TextWriter writer) {
            Writer = writer;
        }

                /// <summary>Called when the whole test suite has started.</summary>
        public void StartTestSuite(NUnitTest suite) {
            XmlDeclaration decl = _document.CreateXmlDeclaration("1.0", null, null);   
         
            _document.AppendChild(decl);
            _suiteElement = _document.CreateElement(ElementTestSuite);
            //
            // if this is a testsuite, use it's name
            //
            string suiteName = suite.Suite.ToString();
            if ( suiteName == null || suiteName == string.Empty )
               suiteName = "test"; 
            _suiteElement.SetAttribute(AttributeName, suiteName );
        }

        /// <summary>Called when the whole test suite has ended.</summary>
        public void EndTestSuite(TestResultExtra result) {
            _suiteElement.SetAttribute(AttributeTests , result.RunCount.ToString());
            double time = result.RunTime;
            time /= 1000D; 
            _suiteElement.SetAttribute(AttributeTime, time.ToString("#####0.000"));
            _document.AppendChild(_suiteElement);

            _suiteElement.SetAttribute(AttributeErrors , 
result.ErrorCount.ToString()); 
            _suiteElement.SetAttribute(AttributeFailures , 
result.FailureCount.ToString());
            
            // Send all output to here
            _document.Save(Writer);
            Writer.Flush();
            Writer.Close();
        }

        //-------------------------------------------------------------
                // ITestListener interface methods
                //-------------------------------------------------------------
                
        public void AddError(ITest test, Exception t) {
            FormatError(ElementError, test, t);
        }

        public void AddFailure(ITest test, AssertionFailedError t) {
            FormatError(ElementFailure, test, (Exception)t);
        }

        public void StartTest(ITest test) {
       
            _testStartTime =  DateTime.Now;
            _currentTest = _document.CreateElement(ElementTestCase);
            _currentTest.SetAttribute(AttributeName, ((TestCase ) test).ToString());
            _suiteElement.AppendChild(_currentTest);
        }

        public void EndTest(ITest test) {
            TimeSpan elapsedTime = DateTime.Now - _testStartTime;
            double time = elapsedTime.Milliseconds;
            time /= 1000D; 
            _currentTest.SetAttribute(AttributeTime, time.ToString("#####0.000") ); 
        }
            
            private void FormatError(string type, ITest test, Exception t) {
            if (test != null) {
                EndTest(test);
            }

            XmlElement nested = _document.CreateElement(type);
            if (test != null) {
                _currentTest.AppendChild(nested);
            } else {
                _suiteElement.AppendChild(nested);
            }

            string message = t.Message;
            if (message != null && message.Length > 0) {
                nested.SetAttribute( AttributeMessage, message );
            }
            nested.SetAttribute(AttributeType, t.GetType().FullName);

            string trace = t.StackTrace;
                    
            XmlText traceElement = _document.CreateTextNode(t.StackTrace);
            nested.AppendChild(traceElement);
        }
        }                       
}
// NAnt - A .NET build tool
// Copyright (C) 2001 Gerry Shaw
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Ian MacLean ([EMAIL PROTECTED])
// Gerry Shaw ([EMAIL PROTECTED])

using NUnit.Framework;
using NUnit.Runner;
using System.Reflection;
using System.Runtime.Remoting;

namespace SourceForge.NAnt.Tasks.NUnit {

    using System;
    using System.Reflection;

    public enum RunnerResult {
        Success,
        Failures,
        Errors,
    }

    public class NUnitTestRunner : BaseTestRunner {
        FormatterCollection _formatters = new FormatterCollection();
        NUnitTest           _nunittest = null;
        ITest               _suite = null;
        TestResultExtra     _result = null;
        RunnerResult        _resultCode = RunnerResult.Success;

        /// <summary>Collection of the registered formatters.</summary>
        public FormatterCollection Formatters { get { return _formatters; } }

        public RunnerResult ResultCode        { get { return _resultCode; } }

        public NUnitTestRunner(NUnitTest test) {
            _nunittest = test;
            string nunitsuite = test.Class + "," + test.Assembly;
            _suite = GetSuite(nunitsuite);
            test.Suite = _suite;
        }

        /// <summary>Returns the test suite from a given class.</summary>
        /// <remarks>
        /// The assemblyQualifiedName parameter needs to be in form:
        /// "full.qualified.class.name,Assembly"
        /// </remarks>
        ITest GetSuite(string assemblyQualifiedName) {
            // Don't worry about catching exceptions in this method.  The
            // NUnitTask will catch them and throw a BuildException back to
            // NAnt with the correct location in the build file. [gs]

            StandardLoader loader = new StandardLoader();
            ITest test = loader.LoadTest(assemblyQualifiedName);
            return test;
        }

        /// <summary>Runs a Suite extracted from a TestCase subclass.</summary>
        public void Run() {

            _result = new TestResultExtra();

            _result.AddListener(this);
            long startTime = System.DateTime.Now.Ticks;

            FireStartTestSuite();

            // Fire start events
            _suite.Run(_result);

            // finished test
            long endTime = System.DateTime.Now.Ticks;
            long runTime = (endTime-startTime) / 10000;

            _result.RunTime = runTime;

            // Handle completion
            FireEndTestSuite();

            if (_result.WasSuccessful == false) {
                if (_result.ErrorCount != 0) {
                    _resultCode = RunnerResult.Errors;
                }
                else if (_result.FailureCount !=0) {
                    _resultCode = RunnerResult.Failures;
                }
            }
        }

        //---------------------------------------------------------
        // BaseTestRunner overrides
        //---------------------------------------------------------

        protected override void RunFailed(string message) {
        }

        //---------------------------------------------------------
        // IListener overrides
        //---------------------------------------------------------
        public override void AddError(ITest test, Exception t) {
            foreach (IResultFormatter formatter in Formatters) {
                formatter.AddError(test, t);
            }

            if (_nunittest.HaltOnError) {
                _result.Stop();
            }
        }

        public override void AddFailure(ITest test, AssertionFailedError t) {
            foreach (IResultFormatter formatter in Formatters) {
                formatter.AddFailure(test, t);
            }

            if (_nunittest.HaltOnFailure) {
                _result.Stop();
            }
        }

        public override void StartTest(ITest test) {
            foreach (IResultFormatter formatter in Formatters) {
                formatter.StartTest(test);
            }
        }

        public override void EndTest(ITest test) {
            foreach (IResultFormatter formatter in Formatters) {
                formatter.EndTest(test);
            }
        }

        //---------------------------------------------------------
        // Formatter notification methods
        //---------------------------------------------------------

        void FireStartTestSuite() {
            foreach (IResultFormatter formatter in Formatters) {
                formatter.StartTestSuite(_nunittest);
            }
        }

        void FireEndTestSuite() {
            foreach (IResultFormatter formatter in Formatters) {
                formatter.EndTestSuite(_result);
            }
        }
    }
}
// NAnt - A .NET build tool
// Copyright (C) 2001 Gerry Shaw
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// Ian MacLean ([EMAIL PROTECTED])

using NUnit.Framework;
using NUnit.Runner;
namespace SourceForge.NAnt.Tasks.NUnit {

    using System;
    using System.Xml;
   
    using SourceForge.NAnt.Attributes;
    
    [ElementName("test")]
    public class NUnitTest : BaseTest {
                  
        string _todir = null;               
        string _outfile = null;

        ITest _suite = null;

        public ITest Suite {
           get { return _suite; }
           set { _suite = value; }
        }
             
        /// <summary>Base name of the test result. The full filename is determined by 
this attribute and the extension of formatter</summary>
        [TaskAttribute("outfile")]
        public string OutFile { get { return _outfile; } set {_outfile = value;} }
        
        /// <summary>Directory to write the reports to.</summary>
        [TaskAttribute("todir")]
        public string ToDir { get { return _todir; } set {_todir = value;} }
        
        public FormatterElementCollection FormatterElements { get { return 
_formatterElements; }  }        
        FormatterElementCollection _formatterElements = new 
FormatterElementCollection(); 
    }    
}

Reply via email to