Mercurial > bitten > bitten-test
changeset 550:6a8dcbffdce2
Added support for nunit (applied patch from silk in #348)
author | dfraser |
---|---|
date | Mon, 06 Apr 2009 08:20:40 +0000 |
parents | cb137f2121b9 |
children | 6b4def531a4e |
files | bitten/build/monotools.py bitten/build/tests/__init__.py bitten/build/tests/monotools.py doc/commands.txt setup.py |
diffstat | 5 files changed, 288 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/bitten/build/monotools.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2005-2007 Christopher Lenz <cmlenz@gmx.de> +# Copyright (C) 2006 Matthew Good <matt@matt-good.net> +# Copyright (C) 2007 Edgewall Software +# Copyright (C) 2009 Grzegorz Sobanski <silk@boktor.net> +# All rights reserved. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at http://bitten.edgewall.org/wiki/License. + +"""Recipe commands for tools commonly used in Mono projects.""" + +from glob import glob +import logging +import os +import posixpath +import shlex +import tempfile + +from bitten.build import CommandLine +from bitten.util import xmlio + +log = logging.getLogger('bitten.build.monotools') + +__docformat__ = 'restructuredtext en' + + +def _parse_suite(element): + for child in element.children('results'): + testcases = list(child.children('test-case')) + if testcases: + yield element, testcases + + for xmlsuite in child.children('test-suite'): + for suite in _parse_suite(xmlsuite): + yield suite + + +def _get_cases(fileobj): + for testsuite in xmlio.parse(fileobj).children('test-suite'): + for suite in _parse_suite(testsuite): + yield suite + + +def nunit(ctxt, file_=None): + """Extract test results from a NUnit XML report. + + :param ctxt: the build context + :type ctxt: `Context` + :param file\_: path to the NUnit XML test results; may contain globbing + wildcards for matching multiple results files + """ + assert file_, 'Missing required attribute "file"' + try: + total, failed = 0, 0 + results = xmlio.Fragment() + for path in glob(ctxt.resolve(file_)): + fileobj = file(path, 'r') + try: + for suite, testcases in _get_cases(fileobj): + for testcase in testcases: + test = xmlio.Element('test') + test.attr['fixture'] = suite.attr['name'] + if 'time' in testcase.attr: + test.attr['duration'] = testcase.attr['time'] + if testcase.attr['executed'] == 'True': + if testcase.attr['success'] != 'True': + test.attr['status'] = 'failure' + failure = list(testcase.children('failure')) + if failure: + stacktraceNode = list(failure[0].children('stack-trace')) + if stacktraceNode: + test.append(xmlio.Element('traceback')[ + stacktraceNode[0].gettext() + ]) + failed += 1 + else: + test.attr['status'] = 'success' + else: + test.attr['status'] = 'ignored' + + results.append(test) + total += 1 + finally: + fileobj.close() + if failed: + ctxt.error('%d of %d test%s failed' % (failed, total, + total != 1 and 's' or '')) + ctxt.report('test', results) + except IOError, e: + log.warning('Error opening NUnit results file (%s)', e) + except xmlio.ParseError, e: + log.warning('Error parsing NUnit results file (%s)', e) + +
--- a/bitten/build/tests/__init__.py +++ b/bitten/build/tests/__init__.py @@ -10,7 +10,8 @@ import unittest -from bitten.build.tests import api, config, ctools, phptools, pythontools, \ +from bitten.build.tests import api, config, ctools, \ + monotools, phptools, pythontools, \ xmltools def suite(): @@ -18,6 +19,7 @@ suite.addTest(api.suite()) suite.addTest(config.suite()) suite.addTest(ctools.suite()) + suite.addTest(monotools.suite()) suite.addTest(phptools.suite()) suite.addTest(pythontools.suite()) suite.addTest(xmltools.suite())
new file mode 100644 --- /dev/null +++ b/bitten/build/tests/monotools.py @@ -0,0 +1,150 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2005-2007 Christopher Lenz <cmlenz@gmx.de> +# Copyright (C) 2008 Matt Good <matt@matt-good.net> +# Copyright (C) 2008 Edgewall Software +# Copyright (C) 2009 Grzegorz Sobanski <silk@boktor.net> +# All rights reserved. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at http://bitten.edgewall.org/wiki/License. + +import os +import cPickle as pickle +import shutil +import tempfile +import unittest + +from bitten.build import monotools +from bitten.build import FileSet +from bitten.recipe import Context, Recipe + + + +class NUnitTestCase(unittest.TestCase): + + def setUp(self): + self.basedir = os.path.realpath(tempfile.mkdtemp()) + self.ctxt = Context(self.basedir) + self.results_xml = open(os.path.join(self.basedir, 'test-results.xml'), 'w') + + def tearDown(self): + shutil.rmtree(self.basedir) + + def test_missing_file_param(self): + self.results_xml.close() + self.assertRaises(AssertionError, monotools.nunit, self.ctxt) + + def test_empty_results(self): + self.results_xml.write('<?xml version="1.0"?>' + '<test-results>' + '</test-results>') + self.results_xml.close() + monotools.nunit(self.ctxt, self.results_xml.name) + type, category, generator, xml = self.ctxt.output.pop() + self.assertEqual(Recipe.REPORT, type) + self.assertEqual('test', category) + self.assertEqual(0, len(xml.children)) + + def test_successful_test_simple(self): + self.results_xml.write( +'<?xml version="1.0" encoding="utf-8" standalone="no"?>' +'<!--This file represents the results of running a test suite-->' +'<test-results name="Test.dll" total="3" failures="1" not-run="0" date="2009-01-05" time="16:32:46">' +' <environment nunit-version="2.4.7.0" clr-version="2.0.50727.42" os-version="Unix 2.6.26.1" platform="Unix" cwd="/home/silk/devel/trac/testcheckout" machine-name="tango" user="silk" user-domain="tango" />' +' <culture-info current-culture="en-US" current-uiculture="en-US" />' +' <test-suite name="Test.dll" success="False" time="0.081" asserts="0">' +' <results>' +' <test-case name="Lib.Test.KlasaTests.Test2" executed="True" success="True" time="0.001" asserts="1" />' +' </results>' +' </test-suite>' +'</test-results>' +) + self.results_xml.close() + monotools.nunit(self.ctxt, self.results_xml.name) + type, category, generator, xml = self.ctxt.output.pop() + self.assertEqual(1, len(xml.children)) + test_elem = xml.children[0] + self.assertEqual('test', test_elem.name) + self.assertEqual('0.001', test_elem.attr['duration']) + self.assertEqual('success', test_elem.attr['status']) + self.assertEqual('Test.dll', test_elem.attr['fixture']) + + + def test_failure_test_simple(self): + self.results_xml.write( +'<?xml version="1.0" encoding="utf-8" standalone="no"?>' +'<!--This file represents the results of running a test suite-->' +'<test-results name="Test.dll" total="3" failures="1" not-run="0" date="2009-01-05" time="16:32:46">' +' <environment nunit-version="2.4.7.0" clr-version="2.0.50727.42" os-version="Unix 2.6.26.1" platform="Unix" cwd="/home/silk/devel/trac/testcheckout" machine-name="tango" user="silk" user-domain="tango" />' +' <culture-info current-culture="en-US" current-uiculture="en-US" />' +' <test-suite name="Test.dll" success="False" time="0.081" asserts="0">' +' <results>' +' <test-case name="Lib.Test.KlasaTests.Test2" executed="True" success="False" time="0.001" asserts="1">' +' <failure>' +' <message><![CDATA[ Expected: 2' +' But was: 3' +']]></message>' +' <stack-trace><![CDATA[at Lib.Test.KlasaTests.Test1 () [0x00000]' +'at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (object,object[],System.Exception&)' +'at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000]' +']]></stack-trace>' +' </failure>' +' </test-case>' +' </results>' +' </test-suite>' +'</test-results>' +) + self.results_xml.close() + monotools.nunit(self.ctxt, self.results_xml.name) + type, category, generator, xml = self.ctxt.output.pop() + self.assertEqual(1, len(xml.children)) + test_elem = xml.children[0] + self.assertEqual('test', test_elem.name) + self.assertEqual('0.001', test_elem.attr['duration']) + self.assertEqual('failure', test_elem.attr['status']) + self.assertEqual('Test.dll', test_elem.attr['fixture']) + self.assertEqual(1, len(test_elem.children)) + + + def test_successful_test_recursive(self): + self.results_xml.write( +'<?xml version="1.0" encoding="utf-8" standalone="no"?>' +'<!--This file represents the results of running a test suite-->' +'<test-results name="Test.dll" total="3" failures="1" not-run="0" date="2009-01-05" time="16:32:46">' +' <environment nunit-version="2.4.7.0" clr-version="2.0.50727.42" os-version="Unix 2.6.26.1" platform="Unix" cwd="/home/silk/devel/trac/testcheckout" machine-name="tango" user="silk" user-domain="tango" />' +' <culture-info current-culture="en-US" current-uiculture="en-US" />' +' <test-suite name="Test.dll" success="False" time="0.081" asserts="0">' +' <results>' + ' <test-suite name="Lib" success="False" time="0.078" asserts="0">' + ' <results>' + ' <test-suite name="Test" success="False" time="0.078" asserts="0">' + ' <results>' + ' <test-case name="Lib.Test.KlasaTests.Test2" executed="True" success="True" time="0.001" asserts="1" />' + ' </results>' + ' </test-suite>' + ' </results>' + ' </test-suite>' +' </results>' +' </test-suite>' +'</test-results>' +) + self.results_xml.close() + monotools.nunit(self.ctxt, self.results_xml.name) + type, category, generator, xml = self.ctxt.output.pop() + self.assertEqual(1, len(xml.children)) + test_elem = xml.children[0] + self.assertEqual('test', test_elem.name) + self.assertEqual('0.001', test_elem.attr['duration']) + self.assertEqual('success', test_elem.attr['status']) + self.assertEqual('Test', test_elem.attr['fixture']) + + +def suite(): + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(NUnitTestCase, 'test')) + return suite + +if __name__ == '__main__': + unittest.main(defaultTest='suite')
--- a/doc/commands.txt +++ b/doc/commands.txt @@ -428,6 +428,43 @@ files to Java source files in the directory `src/tests`. +Mono Tools +========== + +A bundle of recipe commands that support tools commonly used by Mono/.NET projects. + +:Namespace: ``http://bitten.cmlenz.net/tools/mono`` +:Common prefix: ``mono`` + +---------------- +``<mono:nunit>`` +---------------- + +Extracts information about unit test results from a files in NUnit_ XML format. + +.. _nunit: http://nunit.org/ + +Parameters +---------- + ++----------------+-----------------------------------------------------------+ +| Name | Description | ++================+===========================================================+ +| ``file`` | Path to the NUnit XML test results file. This can include | +| | wildcards, in which case all the file matching the | +| | pattern will be included. | ++----------------+-----------------------------------------------------------+ + +The ``file`` attribute is required. + +Examples +-------- + +.. code-block:: xml + + <mono:nunit file="build/tests/TestResult.xml" /> + + PHP Tools =========
--- a/setup.py +++ b/setup.py @@ -71,6 +71,7 @@ NS + 'c#cunit = bitten.build.ctools:cunit', NS + 'c#gcov = bitten.build.ctools:gcov', NS + 'c#make = bitten.build.ctools:make', + NS + 'mono#nunit = bitten.build.monotools:nunit', NS + 'java#ant = bitten.build.javatools:ant', NS + 'java#junit = bitten.build.javatools:junit', NS + 'java#cobertura = bitten.build.javatools:cobertura',