Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

when i use --xunit-output i get UnicodeDecodeError in StringIO.getvalue #337

Closed
wants to merge 6 commits into from

3 participants

@mike-grayhat

because i have 1 unicode string in xml elements coming from

xunit_output.py 93: tc.setAttribute("name", u'| %s |' % u' | '.join(outline.values()))

I think the better way to go is to use unicode strings everywhere instead of converting every string in utf-8 . But this error can be solved by converting this line to utf-8 too.

@gabrielfalcao

Please send also automated tests that proof this bug.

The XUnit output feature was never implemented by myself, I keep getting pull requests that change the code to tweak "this" or "that", and it's absolutely ridiculous form the standpoint of a testing library.

I do not use the XUnit functionality myself, so if you care for this feature, please send a test that proofs your bug is actually a bug.

@FPurchess

looking forward to this merge! thanks mike!

tests/functional/test_xunit_output.py
@@ -194,3 +194,11 @@ def just_pass(step, *args):
assert_equals(1, len(called), "Function not called")
xunit_output.wrt_output = old
+
+
+@with_setup(prepare_stdout, registry.clear)
+def test_xunit_xml_output_with_no_errors():
+ 'Test xunit doc xml output'
+
+ runner = Runner(feature_name('xunit_unicode_and_bytestring_mixing'), enable_xunit=True)
+ runner.run()
@gabrielfalcao Owner

now you can parse the output with lxml:

from sure import expect
from lxml import etree

root = etree.fromstring(content)

testcases = root.xpath('testcase')

expect(testcases).to.have.length_of(...)

But i can't because exception will be raised before xunit_output.wrt_output method. To make an assertion I should create another method that will be called by output_xml (and can be replaced) and then it should call wrt_output. But then anyway i need to check that doc.toxml() do not raise an exception, and really i don't know how an assertion for it should be written.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@gabrielfalcao
pip install sure
def test_it_doesn_raise():
    def try_to_do_something():
        xunit_output.wrt_output ...

    expect(try_to_do_something).when.called.doesnt.throw(UnicodeDecodeError)

sure's documentation

@gabrielfalcao

@mike-grayhat thank you!

@gabrielfalcao

Just released version 0.2.16, thanks for this contribution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 25, 2013
  1. fix StringIO.get_value error on concatenation of strings than contain…

    mike authored
    …s unicode & utf-8 characters
  2. do not encode stepname in utf-8

    mike authored
Commits on Mar 27, 2013
  1. Merge branch 'develop'

    mike authored
  2. Merge branch 'develop'

    Mike authored
This page is out of date. Refresh to see the latest.
View
16 lettuce/plugins/xunit_output.py
@@ -31,6 +31,10 @@ def wrt_output(filename, content):
f.close()
+def write_xml_doc(filename, doc):
+ wrt_output(filename, doc.toxml())
+
+
def total_seconds(td):
return (td.microseconds + (td.seconds + td.days * 24 * 3600) * 1e6) / 1e6
@@ -55,10 +59,10 @@ def create_test_case_step(step):
return
name = getattr(parent, 'name', 'Background') # Background sections are nameless
- classname = utf8_string(u"%s : %s" % (parent.feature.name, name))
+ classname = u"%s : %s" % (parent.feature.name, name)
tc = doc.createElement("testcase")
tc.setAttribute("classname", classname)
- tc.setAttribute("name", step.sentence.encode('utf-8'))
+ tc.setAttribute("name", step.sentence)
try:
tc.setAttribute("time", str(total_seconds((datetime.now() - step.started))))
except AttributeError:
@@ -70,11 +74,11 @@ def create_test_case_step(step):
tc.appendChild(skip)
if step.failed:
- cdata = doc.createCDATASection(step.why.traceback.encode('utf-8'))
+ cdata = doc.createCDATASection(step.why.traceback)
failure = doc.createElement("failure")
if hasattr(step.why, 'cause'):
- failure.setAttribute("message", step.why.cause.encode('utf-8'))
- failure.setAttribute("type", step.why.exception.__class__.__name__.encode('utf-8'))
+ failure.setAttribute("message", step.why.cause)
+ failure.setAttribute("type", step.why.exception.__class__.__name__)
failure.appendChild(cdata)
tc.appendChild(failure)
@@ -109,4 +113,4 @@ def output_xml(total):
root.setAttribute("errors", '0')
root.setAttribute("time", '0')
doc.appendChild(root)
- wrt_output(output_filename, doc.toxml())
+ write_xml_doc(output_filename, doc)
View
9 ...nctional/output_features/xunit_unicode_and_bytestring_mixing/xunit_unicode_and_bytestring_mixing.feature
@@ -0,0 +1,9 @@
+Feature: Mixing of Unicode & bytestrings in xunit xml output
+ Scenario Outline: It should pass
+ Given non ascii characters "<value>" in outline
+ Examples:
+ | value |
+ | Значение |
+
+Scenario Outline: It should pass too
+ Given non ascii characters "Тест" in step
View
11 ...ctional/output_features/xunit_unicode_and_bytestring_mixing/xunit_unicode_and_bytestring_mixing_steps.py
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+from lettuce import step
+
+@step(u'Non ascii characters "(.*)" in outline')
+def non_ascii_characters_in_outline(step, first):
+ assert True
+
+
+@step(u'Non ascii characters "(.*)" in step')
+def define_nonascii_chars(step, word):
+ assert True
View
20 tests/functional/test_xunit_output.py
@@ -22,6 +22,7 @@
from StringIO import StringIO
from nose.tools import assert_equals, assert_true, with_setup
+from sure import expect
from lettuce import registry
from lettuce import Runner
from lettuce import xunit_output
@@ -194,3 +195,22 @@ def just_pass(step, *args):
assert_equals(1, len(called), "Function not called")
xunit_output.wrt_output = old
+
+
+@with_setup(prepare_stdout, registry.clear)
+def test_xunit_xml_output_with_no_errors():
+ 'Test xunit doc xml output'
+
+ called = []
+
+ def assert_correct_xml_output(filename, doc):
+ called.append(True)
+ expect(doc.toxml).when.called.doesnt.throw(UnicodeDecodeError)
+
+ old = xunit_output.write_xml_doc
+ xunit_output.write_xml_doc = assert_correct_xml_output
+ runner = Runner(feature_name('xunit_unicode_and_bytestring_mixing'), enable_xunit=True)
+ try:
+ runner.run()
+ finally:
+ xunit_output.write_xml_doc = old
Something went wrong with that request. Please try again.