diff options
author | Dylan Baker <dylan@pnwbakers.com> | 2016-07-27 14:46:38 -0700 |
---|---|---|
committer | Dylan Baker <dylan@pnwbakers.com> | 2016-08-05 10:45:04 -0700 |
commit | fc0bbc2f560c75058de210d15fe635e23f9e0c96 (patch) | |
tree | 0ec0a6253a255cc68989d5d5f09c627a726af8c8 /unittests | |
parent | eb7ac77185f3e9845caab4a05805d89f4257b448 (diff) |
unittests: Port junit_backends_tests to pytest
Signed-off-by: Dylan Baker <dylanx.c.baker@intel.com>
Diffstat (limited to 'unittests')
-rw-r--r-- | unittests/framework/backends/schema/junit-7.xsd (renamed from unittests/schema/junit-7.xsd) | 0 | ||||
-rw-r--r-- | unittests/framework/backends/test_junit.py | 255 | ||||
-rw-r--r-- | unittests/junit_backends_tests.py | 335 |
3 files changed, 255 insertions, 335 deletions
diff --git a/unittests/schema/junit-7.xsd b/unittests/framework/backends/schema/junit-7.xsd index bc07b52d9..bc07b52d9 100644 --- a/unittests/schema/junit-7.xsd +++ b/unittests/framework/backends/schema/junit-7.xsd diff --git a/unittests/framework/backends/test_junit.py b/unittests/framework/backends/test_junit.py new file mode 100644 index 000000000..a8443db19 --- /dev/null +++ b/unittests/framework/backends/test_junit.py @@ -0,0 +1,255 @@ +# Copyright (c) 2014, 2016 Intel Corporation + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +"""Tests for the Junit backend package.""" + +from __future__ import ( + absolute_import, division, print_function, unicode_literals +) +import os +import textwrap +try: + from lxml import etree +except ImportError: + import xml.etree.cElementTree as etree +try: + import mock +except ImportError: + from unittest import mock + +import pytest +import six + +from framework import backends +from framework import grouptools +from framework import results +from framework import status + +from . import shared + +# pylint: disable=no-self-use + +JUNIT_SCHEMA = os.path.join(os.path.dirname(__file__), 'schema', 'junit-7.xsd') + +_XML = """\ +<?xml version='1.0' encoding='utf-8'?> + <testsuites> + <testsuite name="piglit" tests="1"> + <testcase classname="piglit.foo.bar" name="a-test" status="pass" time="1.12345"> + <system-out>this/is/a/command\nThis is stdout</system-out> + <system-err>this is stderr + +pid: 1934 +time start: 1.0 +time end: 4.5 + </system-err> + </testcase> + </testsuite> + </testsuites> +""" + +@pytest.yield_fixture(autouse=True, scope="module") +def mock_compression(): + with mock.patch('framework.backends.compression.get_mode', + mock.Mock(return_value='none')): + yield + + +class TestProtectedLoad(object): + """Tests for the _load method.""" + + def test_default_name(self, tmpdir): + """backends.junit._load: uses 'junit result' for name as fallback.""" + tmpdir.chdir() + with open('results.xml', 'w') as f: + f.write(_XML) + test = backends.junit.REGISTRY.load('results.xml', 'none') + + assert test.name == 'junit result' + + def test_file_name(self, tmpdir): + """backends.junit._load: uses the filename for name if filename != + 'results' + """ + p = tmpdir.join('foobar.xml') + p.write(_XML) + test = backends.junit.REGISTRY.load(six.text_type(p), 'none') + assert test.name == 'foobar' + + def test_folder_name(self, tmpdir): + """backends.junit._load: uses the folder name if the result is + 'results.' + """ + tmpdir.mkdir('foo') + p = tmpdir.join('foo', 'results.xml') + p.write(_XML) + test = backends.junit.REGISTRY.load(six.text_type(p), 'none') + + assert test.name == 'foo' + + class TestReturned(object): + """Test that the returned object is as expected.""" + + testname = grouptools.join('foo', 'bar', 'a-test') + + @pytest.fixture + def result(self, tmpdir): + p = tmpdir.join('test.xml') + p.write(_XML) + return backends.junit._load(six.text_type(p)) + + def test_testrunresult(self, result): + """backends.junit._load: returns a TestrunResult instance.""" + assert isinstance(result, results.TestrunResult) + + def test_replace_sep(self, result): + """backends.junit._load: replaces '.' with grouptools.SEPARATOR.""" + assert self.testname in result.tests + + def test_testresult_instance(self, result): + """backends.junit._load: replaces result with TestResult instance. + """ + assert isinstance(result.tests[self.testname], results.TestResult) + + def test_status_instance(self, result): + """backends.junit._load: a status is found and loaded.""" + assert isinstance(result.tests[self.testname].result, + status.Status) + + def test_time(self, result): + time = result.tests[self.testname].time + assert isinstance(time, results.TimeAttribute) + assert time.start == 1.0 + assert time.end == 4.5 + + def test_command(self, result): + """backends.junit._load: command is loaded correctly.""" + assert result.tests[self.testname].command == 'this/is/a/command' + + def test_out(self, result): + """backends.junit._load: stdout is loaded correctly.""" + assert result.tests[self.testname].out == 'This is stdout' + + def test_err(self, result): + """backends.junit._load: stderr is loaded correctly.""" + expected = textwrap.dedent("""\ + this is stderr + + pid: 1934 + time start: 1.0 + time end: 4.5""") + assert result.tests[self.testname].err.strip() == expected + + def test_totals(self, result): + """backends.junit._load: Totals are calculated.""" + assert bool(result) + + def test_pid(self, result): + """backends.junit._load: pid is loaded correctly.""" + assert result.tests[self.testname].pid == 1934 + + +class TestJUnitBackend(object): + """Tests for the JUnitBackend class.""" + + class TestFinalize(object): + """Tests for the finalize method.""" + + def test_skips_illformed_tests(self, tmpdir): + """backends.junit.JUnitBackend: skips illformed tests""" + result = results.TestResult() + result.time.end = 1.2345 + result.result = 'pass' + result.out = 'this is stdout' + result.err = 'this is stderr' + result.command = 'foo' + + test = backends.junit.JUnitBackend(six.text_type(tmpdir)) + test.initialize(shared.INITIAL_METADATA) + with test.write_test(grouptools.join('a', 'group', 'test1')) as t: + t(result) + tmpdir.join('tests', '1.xml').write('bad data') + + test.finalize() + + class TestWriteTest(object): + """Tests for the write_test method.""" + + def test_junit_replace(self, tmpdir): + """backends.junit.JUnitBackend.write_test: grouptools.SEPARATOR is + replaced with '.'. + """ + result = results.TestResult() + result.time.end = 1.2345 + result.result = 'pass' + result.out = 'this is stdout' + result.err = 'this is stderr' + result.command = 'foo' + + test = backends.junit.JUnitBackend(six.text_type(tmpdir)) + test.initialize(shared.INITIAL_METADATA) + with test.write_test(grouptools.join('a', 'group', 'test1')) as t: + t(result) + test.finalize() + + test_value = etree.parse(six.text_type(tmpdir.join('results.xml'))) + test_value = test_value.getroot() + + assert test_value.find('.//testcase').attrib['classname'] == \ + 'piglit.a.group' + + class TestValid(object): + @pytest.fixture + def test_file(self, tmpdir): + tmpdir.mkdir('foo') + p = tmpdir.join('foo') + + result = results.TestResult() + result.time.end = 1.2345 + result.result = 'pass' + result.out = 'this is stdout' + result.err = 'this is stderr' + result.command = 'foo' + result.pid = 1034 + + test = backends.junit.JUnitBackend(six.text_type(p)) + test.initialize(shared.INITIAL_METADATA) + with test.write_test(grouptools.join('a', 'group', 'test1')) as t: + t(result) + + result.result = 'fail' + with test.write_test(grouptools.join('a', 'test', 'test1')) as t: + t(result) + test.finalize() + + return six.text_type(p.join('results.xml')) + + def test_xml_well_formed(self, test_file): + """backends.junit.JUnitBackend.write_test: produces well formed xml.""" + etree.parse(test_file) + + @pytest.mark.skipif(etree.__name__ != 'lxml.etree', + reason="This test requires lxml") + def test_xml_valid(self, test_file): + """backends.junit.JUnitBackend.write_test: produces valid JUnit xml.""" + # This XMLSchema class is unique to lxml + schema = etree.XMLSchema(file=JUNIT_SCHEMA) # pylint: disable=no-member + with open(test_file, 'r') as f: + assert schema.validate(etree.parse(f)) diff --git a/unittests/junit_backends_tests.py b/unittests/junit_backends_tests.py deleted file mode 100644 index 4e5100d43..000000000 --- a/unittests/junit_backends_tests.py +++ /dev/null @@ -1,335 +0,0 @@ -# Copyright (c) 2014 Intel Corporation - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -# pylint: disable=missing-docstring - -""" Tests for the backend package """ - -from __future__ import ( - absolute_import, division, print_function, unicode_literals -) -import os - -try: - from lxml import etree -except ImportError: - import xml.etree.cElementTree as etree -import nose.tools as nt - -from framework import results, backends, grouptools, status -from . import utils - -BACKEND_INITIAL_META = { - 'name': 'name', - 'test_count': 0, - 'env': {}, -} - -JUNIT_SCHEMA = os.path.join(os.path.dirname(__file__), 'schema', 'junit-7.xsd') - -doc_formatter = utils.nose.DocFormatter({'separator': grouptools.SEPARATOR}) - -_XML = """\ -<?xml version='1.0' encoding='utf-8'?> - <testsuites> - <testsuite name="piglit" tests="1"> - <testcase classname="piglit.foo.bar" name="a-test" status="pass" time="1.12345"> - <system-out>this/is/a/command\nThis is stdout</system-out> - <system-err>this is stderr - -pid: 1934 -time start: 1.0 -time end: 4.5 - </system-err> - </testcase> - </testsuite> - </testsuites> -""" - - -def setup_module(): - utils.piglit.set_compression('none') - - -def teardown_module(): - utils.piglit.unset_compression() - - -class TestJunitNoTests(utils.nose.StaticDirectory): - @classmethod - def setup_class(cls): - super(TestJunitNoTests, cls).setup_class() - test = backends.junit.JUnitBackend(cls.tdir) - test.initialize(BACKEND_INITIAL_META) - test.finalize() - cls.test_file = os.path.join(cls.tdir, 'results.xml') - - @utils.nose.no_error - def test_xml_well_formed(self): - """backends.junit.JUnitBackend: initialize and finalize produce well formed xml - - While it will produce valid XML, it cannot produc valid JUnit, since - JUnit requires at least one test to be valid - - """ - etree.parse(self.test_file) - - -class TestJUnitSingleTest(TestJunitNoTests): - @classmethod - def setup_class(cls): - super(TestJUnitSingleTest, cls).setup_class() - cls.test_file = os.path.join(cls.tdir, 'results.xml') - - result = results.TestResult() - result.time.end = 1.2345 - result.result = 'pass' - result.out = 'this is stdout' - result.err = 'this is stderr' - result.command = 'foo' - result.pid = 1034 - - test = backends.junit.JUnitBackend(cls.tdir) - test.initialize(BACKEND_INITIAL_META) - with test.write_test(grouptools.join('a', 'test', 'group', 'test1')) as t: - t(result) - test.finalize() - - def test_xml_well_formed(self): - """backends.junit.JUnitBackend.write_test(): (once) produces well formed xml""" - super(TestJUnitSingleTest, self).test_xml_well_formed() - - @utils.nose.Skip.module('lxml', available=True) - def test_xml_valid(self): - """backends.junit.JUnitBackend.write_test(): (once) produces valid xml""" - schema = etree.XMLSchema(file=JUNIT_SCHEMA) - with open(self.test_file, 'r') as f: - nt.ok_(schema.validate(etree.parse(f)), msg='xml is not valid') - - -class TestJUnitMultiTest(TestJUnitSingleTest): - @classmethod - def setup_class(cls): - super(TestJUnitMultiTest, cls).setup_class() - - result = results.TestResult() - result.time.end = 1.2345 - result.result = 'pass' - result.out = 'this is stdout' - result.err = 'this is stderr' - result.command = 'foo' - result.pid = 1034 - - cls.test_file = os.path.join(cls.tdir, 'results.xml') - test = backends.junit.JUnitBackend(cls.tdir) - test.initialize(BACKEND_INITIAL_META) - with test.write_test(grouptools.join('a', 'test', 'group', 'test1')) as t: - t(result) - - result.result = 'fail' - with test.write_test( - grouptools.join('a', 'different', 'test', 'group', 'test2')) as t: - t(result) - test.finalize() - - def test_xml_well_formed(self): - """backends.junit.JUnitBackend.write_test(): (twice) produces well formed xml""" - super(TestJUnitMultiTest, self).test_xml_well_formed() - - def test_xml_valid(self): - """backends.junit.JUnitBackend.write_test(): (twice) produces valid xml""" - super(TestJUnitMultiTest, self).test_xml_valid() - - -@doc_formatter -def test_junit_replace(): - """backends.junit.JUnitBackend.write_test(): '{separator}' is replaced with '.'""" - with utils.nose.tempdir() as tdir: - result = results.TestResult() - result.time.end = 1.2345 - result.result = 'pass' - result.out = 'this is stdout' - result.err = 'this is stderr' - result.command = 'foo' - - test = backends.junit.JUnitBackend(tdir) - test.initialize(BACKEND_INITIAL_META) - with test.write_test(grouptools.join('a', 'test', 'group', 'test1')) as t: - t(result) - test.finalize() - - test_value = etree.parse(os.path.join(tdir, 'results.xml')).getroot() - - nt.assert_equal(test_value.find('.//testcase').attrib['classname'], - 'piglit.a.test.group') - - -@utils.nose.not_raises(etree.ParseError) -def test_junit_skips_bad_tests(): - """backends.junit.JUnitBackend: skips illformed tests""" - with utils.nose.tempdir() as tdir: - result = results.TestResult() - result.time.end = 1.2345 - result.result = 'pass' - result.out = 'this is stdout' - result.err = 'this is stderr' - result.command = 'foo' - - test = backends.junit.JUnitBackend(tdir) - test.initialize(BACKEND_INITIAL_META) - with test.write_test(grouptools.join('a', 'test', 'group', 'test1')) as t: - t(result) - with open(os.path.join(tdir, 'tests', '1.xml'), 'w') as f: - f.write('bad data') - - test.finalize() - - -class TestJUnitLoad(utils.nose.StaticDirectory): - """Methods that test loading JUnit results.""" - __instance = None - - @classmethod - def setup_class(cls): - super(TestJUnitLoad, cls).setup_class() - cls.xml_file = os.path.join(cls.tdir, 'results.xml') - - with open(cls.xml_file, 'w') as f: - f.write(_XML) - - cls.testname = grouptools.join('foo', 'bar', 'a-test') - - @classmethod - def xml(cls): - if cls.__instance is None: - cls.__instance = backends.junit._load(cls.xml_file) - return cls.__instance - - @utils.nose.no_error - def test_no_errors(self): - """backends.junit._load: Raises no errors for valid junit.""" - self.xml() - - def test_return_testrunresult(self): - """backends.junit._load: returns a TestrunResult instance""" - nt.assert_is_instance(self.xml(), results.TestrunResult) - - @doc_formatter - def test_replace_sep(self): - """backends.junit._load: replaces '.' with '{separator}'""" - nt.assert_in(self.testname, self.xml().tests) - - def test_testresult_instance(self): - """backends.junit._load: replaces result with TestResult instance.""" - nt.assert_is_instance(self.xml().tests[self.testname], results.TestResult) - - def test_status_instance(self): - """backends.junit._load: a status is found and loaded.""" - nt.assert_is_instance(self.xml().tests[self.testname].result, - status.Status) - - def test_time_start(self): - """backends.junit._load: Time.start is loaded correctly.""" - time = self.xml().tests[self.testname].time - nt.assert_is_instance(time, results.TimeAttribute) - nt.eq_(time.start, 1.0) - - def test_time_end(self): - """backends.junit._load: Time.end is loaded correctly.""" - time = self.xml().tests[self.testname].time - nt.assert_is_instance(time, results.TimeAttribute) - nt.eq_(time.end, 4.5) - - def test_command(self): - """backends.junit._load: command is loaded correctly.""" - test = self.xml().tests[self.testname].command - nt.assert_equal(test, 'this/is/a/command') - - def test_out(self): - """backends.junit._load: stdout is loaded correctly.""" - test = self.xml().tests[self.testname].out - nt.assert_equal(test, 'This is stdout') - - def test_err(self): - """backends.junit._load: stderr is loaded correctly.""" - test = self.xml().tests[self.testname].err - expected = ('this is stderr\n\n' - 'pid: 1934\n' - 'time start: 1.0\n' - 'time end: 4.5\n' - ' ') - nt.eq_(test, expected) - - def test_totals(self): - """backends.junit._load: Totals are calculated.""" - nt.ok_(bool(self.xml())) - - def test_pid(self): - """backends.junit._load: pid is loaded correctly.""" - test = self.xml().tests[self.testname].pid - nt.eq_(test, 1934) - - - @utils.nose.no_error - def test_load_file(self): - """backends.junit.load: Loads a file directly""" - backends.junit.REGISTRY.load(self.xml_file, 'none') - - @utils.nose.no_error - def test_load_dir(self): - """backends.junit.load: Loads a directory""" - backends.junit.REGISTRY.load(self.tdir, 'none') - - -def test_load_file_name(): - """backends.junit._load: uses the filename for name if filename != 'results' - """ - with utils.nose.tempdir() as tdir: - filename = os.path.join(tdir, 'foobar.xml') - with open(filename, 'w') as f: - f.write(_XML) - - test = backends.junit.REGISTRY.load(filename, 'none') - nt.assert_equal(test.name, 'foobar') - - -def test_load_folder_name(): - """backends.junit._load: uses the folder name if the result is 'results'""" - with utils.nose.tempdir() as tdir: - os.mkdir(os.path.join(tdir, 'a cool test')) - filename = os.path.join(tdir, 'a cool test', 'results.xml') - with open(filename, 'w') as f: - f.write(_XML) - - test = backends.junit.REGISTRY.load(filename, 'none') - nt.assert_equal(test.name, 'a cool test') - - -@utils.nose.test_in_tempdir -def test_load_default_name(): - """backends.junit._load: uses 'junit result' for name as fallback""" - with utils.nose.tempdir() as tdir: - with utils.nose.chdir(tdir): - filename = 'results.xml' - with open(filename, 'w') as f: - f.write(_XML) - test = backends.junit.REGISTRY.load(filename, 'none') - - nt.assert_equal(test.name, 'junit result') |