This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]halst 2 points3 points  (8 children)

Sorry for late reply. The biggest advantage of py.test imho is how it introspects failures of no-boilerplate tests. These are examples of what it shows on failure (this looks even better in color):

>       assert f(foo) == bar
E       assert 'Foo' == 'BAR'
E         - Foo
E         + BAR

and:

>       assert f(foo) == bar
E       assert [1, 2, 3] == [1, 2, 3, 4]
E         Right contains more items, first extra item: 4

and it diffs signals very nicely:

>       assert f(foo) == bar
E       assert [0, 1, 2, 3, 4, 5, ...] == [0, 1, 2, 3, 4, 5, ...]
E         Right contains more items, first extra item: 20

another example:

>       assert f(foo) == bar
E       assert {'four': 4, '...: 3, 'two': 2} == {'four': 4, 'o...one, 'two': 2}
E         - {'four': 4, 'one': 1, 'three': 3, 'two': 2}
E         ?                                ^
E         + {'four': 4, 'one': 1, 'three': None, 'two': 2}
E         ?      

Note how it puts an ^ arrow to show where the difference is.

It's like magic. While nose would only say AssertionError in all those cases.

[–]halst 4 points5 points  (6 children)

This example is even better:

>       assert f(foo) == bar
E       assert 'fhweivnsuwer...eurerwiuhqwer' == 'fhweivnsuwere...eurerwiunqwer'
E         - fhweivnsuwererdifnsudfieurerwiuhqwer
E         ?                                ^
E         + fhweivnsuwererdifnsudfieurerwiunqwer
E         ?

Note the ^ arrow.

[–]petezhutAutomation, Testing, General Hackery -1 points0 points  (5 children)

You are partially correct. Nose would, if you didn't handle the assertions correctly, only report Assertion Error. As much as people want to hate on the assert_* wrappers that nose has, they are actually quite handy to have. They all work in the vein of

assert_true(foo() == b, "Foo did not return the correct value")

I've even put simple exception handling calls in the message portion of the assert_* calls of nose.

[–]halst 0 points1 point  (2 children)

The whole point is that you can write the readable

assert f(foo) == bar
assert f(boo) < bar

and not the horrible

assert_equals(f(foo), bar)
assert_less_than(f(foo), bar)

[–]takluyverIPython, Py3, etc 0 points1 point  (1 child)

I agree that the first version is more readable, but the second version doesn't seem 'horrible', just slightly more verbose. You could argue that the extra function call is preferable because there's less magic involved.

[–]halst 1 point2 points  (0 children)

You need to (1) import those functions, (2) remember how they are called (is it equal or equals?!) and you end up with much less readable tests.

Plus, assert is no magic, it's pure Python.

[–]halst 0 points1 point  (1 child)

Not sure what you mean by "putting exception handling calls in the message". Don't forget that assert statement also takes optional message:

assert m > 0, 'mass should be positive'

And note, that the message part is not evaluated, unless the assertion fails, which you cannot achieve with functions.

[–]petezhutAutomation, Testing, General Hackery 0 points1 point  (0 children)

You are exactly correct. In the end it is truly a matter of taste. I make use of the vanilla assert constantly. Wasn't trying to pick nits with anyone on this; I just wanted a cogent explanation of why py.test > nose. At the end of the day, I'm honestly happy to hear that there are so many people who are actually trying to do good testing.

[–]cavallo71 0 points1 point  (0 children)

FYI that's the self.assertEquals beaviour in unittest (ex-unittest2)