[Python-Dev] How far to go with user-friendliness

Ron Adam ron3200 at gmail.com
Mon Jul 20 23:11:51 CEST 2015



On 07/20/2015 01:35 PM, Florian Bruhin wrote:
>>>>> > >>>m.assert_me()
>> >Traceback (most recent call last):
>> >   File "<stdin>", line 1, in <module>
>> >   File "/media/hda2/home/ra/Dev/python-dev/python3.5/cpython-master/Lib/unittest/mock.py",
>> >line 583, in __getattr__
>> >     raise AttributeError(name)
>> >AttributeError: assert_me
>> >
>> >
>> >Why is AttributeError raised here?  Why are methods beginning with assert
>> >special?  (or "unsafe")
> Some things I can think of:
>
> - It's more likely that you use assert_called() instead of
>    assert_called_with() accidentally than that you do a typo in your
>    code under test.
>
> - If you do a typo in your code under test, a linter is more likely to
>    find it than with mocks, because of their nature.
>
> - Other tests (even if they're manual ones) should probably discover
>    the typo in your real code. The always-passing assert won't.

But it doesn't always pass in the above.  It would fail if there is a typo. 
  You would need to make the same typo in the test and the mock the test uses.

With this, the only way to use methods beginning with assert is to set 
unsafe=True.  Then none of this applies.  And after a few times, it's 
likely a developer will get into the habit of doing that.  I wonder if it's 
going to do what the intent was?

Another reason mentioned by Nick, is to avoid shadowing mocks own methods. 
  But I would think a different exception could be used with an explicit 
error message regarding the exact reason would be better, by actually 
detecting the attribute shadows specific mock methods when the mock object 
is created rather than raising an AttributeError when it's called.

I'm thinking that would have been enough to find most of the errors 
including the use of "assret*" in the motivating case.   Which would of 
been a matter of just correcting the spelling.

"assret*" would have raised an Attribute error if it was spelled that way 
in the test, or "assert*" would have raised an Attribute error if it was 
spelled "assret*" in the object used in the test.

Do these seem accurate to you?


The problems seem to only occur be when no spec is given.

Blocking use of "assert*" when a spec is given is more than needed, but 
detecting shadowing of needed mock methods is needed.  That can be done 
sooner with better a better error message I think.

Using "assret*" in the objects being tested will never shadow a mock 
method.  So it seems it's a case of catching a mispelling in a test calling 
a non-existing method.  (But anyother spelling would not be caught.)


I think I'm starting to get it now,
    Ron

























More information about the Python-Dev mailing list