Hello

Another possible improvement to the assert repr of py.test (IMHO) is
how attributes are represented.  One thing I often find myself doing
is code like this:

def test_foo():
    i = SomeClass()
    print i.attribute_name
    assert i.attribute_name == "some_value"

The printing of the attribute name is simply to work around the
slightly annoying (IMHO) default representation of attributes, it
could have been a one-liner test otherwise (assuming no side-effects
in the call).  While it is really nice to see where it came from, just
knowing the value is often very useful (e.g. when it could be None or
a meaning value).

So the attached patch addresses this.  It's just a one-line change
really, and I think the output is a lot nicer.  Personally I can't see
what could be wrong with this approach so don't think moving this to a
plugin or making it otherwise optional is needed.

I hope this can be a useful addition.

Regards
Floris


-- 
Debian GNU/Linux -- The Power of Freedom
www.debian.org | www.gnu.org | www.kernel.org
diff --git a/doc/example/assertion/failure_demo.py b/doc/example/assertion/failure_demo.py
--- a/doc/example/assertion/failure_demo.py
+++ b/doc/example/assertion/failure_demo.py
@@ -159,5 +159,27 @@ class TestSpecialisedExplanations(object
         assert 1 in [0, 2, 3, 4, 5]
 
 
+def test_attribute():
+    class Foo(object):
+        b = 1
+    i = Foo()
+    assert i.b == 2
+
+
+def test_attribute_instance():
+    class Foo(object):
+        b = 1
+    assert Foo().b == 2
+
+
+def test_attribute_failure():
+    class Foo(object):
+        def _get_b(self):
+            raise Exception('Failed to get attrib')
+        b = property(_get_b)
+    i = Foo()
+    assert i.b == 2
+
+
 def globf(x):
     return x+1
diff --git a/doc/example/assertion/test_failures.py b/doc/example/assertion/test_failures.py
--- a/doc/example/assertion/test_failures.py
+++ b/doc/example/assertion/test_failures.py
@@ -10,6 +10,6 @@ def test_failure_demo_fails_properly(tes
     failure_demo.copy(testdir.tmpdir.join(failure_demo.basename))
     result = testdir.runpytest(target)
     result.stdout.fnmatch_lines([
-        "*31 failed*"
+        "*34 failed*"
     ])
     assert result.ret != 0
diff --git a/py/_code/_assertionnew.py b/py/_code/_assertionnew.py
--- a/py/_code/_assertionnew.py
+++ b/py/_code/_assertionnew.py
@@ -298,6 +298,7 @@ class DebugInterpreter(ast.NodeVisitor):
             result = self.frame.eval(co, __exprinfo_expr=source_result)
         except Exception:
             raise Failure(explanation)
+        explanation = "%s\n{%s\n}" % (self.frame.repr(result), explanation)
         # Check if the attr is from an instance.
         source = "%r in getattr(__exprinfo_expr, '__dict__', {})"
         source = source % (attr.attr,)
diff --git a/testing/code/test_assertion.py b/testing/code/test_assertion.py
--- a/testing/code/test_assertion.py
+++ b/testing/code/test_assertion.py
@@ -81,6 +81,27 @@ def test_is():
         s = str(e)
         assert s.startswith("assert 1 is 2")
 
+def test_attrib():
+    class Foo(object):
+        b = 1
+    i = Foo()
+    try:
+        assert i.b == 2
+    except AssertionError:
+        e = exvalue()
+        s = str(e)
+        assert s.startswith("assert 1 == 2")
+
+def test_attrib_inst():
+    class Foo(object):
+        b = 1
+    try:
+        assert Foo().b == 2
+    except AssertionError:
+        e = exvalue()
+        s = str(e)
+        assert s.startswith("assert 1 == 2")
+
 def test_assert_non_string_message():
     class A:
         def __str__(self):
_______________________________________________
py-dev mailing list
py-dev@codespeak.net
http://codespeak.net/mailman/listinfo/py-dev

Reply via email to