[Python-Dev] PEP: Consolidating names and classes in the `unittest`module (updated 2008年07月15日)

Nick Coghlan ncoghlan at gmail.com
Tue Jul 15 16:16:36 CEST 2008


Nick Coghlan wrote:
> One option for rationalising the API would be to merely keep the
> shortest version of each phrase (i.e. use assert* instead of
> fail_unless* for the positive tests and fail_if* instead of
> assert_not* for the negative tests, and always drop the trailing 's'
> from 'equals').

Disclaimer: I'm not convinced the ideas in this message are actually a 
good idea myself. But I found them intriguing enough to bother posting 
them. To give some idea of how the different styles would look, here's 
an example (based on one of the tests in test_runpy) using a combination 
of assert* and fail_if* names:
 self.fail_if_contains(d1, "result")
 self.assert_identical(d2["initial"], initial)
 self.assert_equal(d2["result"], self.expected_result)
 self.assert_equal(d2["nested"]["x"], 1)
 self.assert_(d2["run_name_in_sys_modules"])
 self.assert_(d2["module_in_sys_modules"])
 self.assert_identical(d2["run_argv0"], file)
 self.assert_identical(sys.argv[0], saved_argv0)
 self.fail_if_contains(sys.modules, name)
A somewhat odd thought that occurred to me is that the shortest possible 
way of writing negative assertions (i.e. asserting that something is not 
the case) is to treat them as denials and use the single word 'deny'.
This approach would give:
Test assertions:
 assert_almost_equal
 assert_identical
 assert_contains
 assert_raises
 assert_equal
 assert_
Test denials (negative assertions):
 deny_almost_equal (17)
 deny_identical (14)
 deny_contains (13)
 deny_equal (10)
 deny (4)
Explicit failure:
 fail (4)
Using the test_runpy example assertions:
 self.deny_contains(d1, "result")
 self.assert_identical(d2["initial"], initial)
 self.assert_equal(d2["result"], self.expected_result)
 self.assert_equal(d2["nested"]["x"], 1)
 self.assert_(d2["run_name_in_sys_modules"])
 self.assert_(d2["module_in_sys_modules"])
 self.assert_identical(d2["run_argv0"], file)
 self.assert_identical(sys.argv[0], saved_argv0)
 self.deny_contains(sys.modules, name)
I actually quite like that - and it saves not only several characters, 
but also an underscore over the fail_if* and assert_not* variants.
The second odd thought was what happens if the 'assert' is made implicit?
Test assertions:
 are_almost_equal
 are_identical
 does_contain
 does_raise
 are_equal
 assert_
Test negative assertions:
 not_almost_equal
 not_identical
 not_contains
 not_equal
 not_
Explicit failure:
 fail
Using the test_runpy example assertions:
 self.not_contains(d1, "result")
 self.are_identical(d2["initial"], initial)
 self.are_equal(d2["result"], self.expected_result)
 self.are_equal(d2["nested"]["x"], 1)
 self.assert_(d2["run_name_in_sys_modules"])
 self.assert_(d2["module_in_sys_modules"])
 self.are_identical(d2["run_argv0"], file)
 self.are_identical(sys.argv[0], saved_argv0)
 self.not_contains(sys.modules, name)
Yecch, I think that idea can be safely consigned to the mental trash heap.
Another late night API concept: create a "check" object with the LHS of 
the binary operation being asserted, then use methods on that check 
object to supply the RHS:
 self.check("result").not_in(d1)
 self.check(d2["initial"]).is_(initial)
 self.check(d2["result"]).equals(self.expected_result)
 self.check(d2["nested"]["x"]).equals(1)
 self.assert_(d2["run_name_in_sys_modules"])
 self.assert_(d2["module_in_sys_modules"])
 self.check(d2["run_argv0"]).is_(file)
 self.check(sys.argv[0]).is_(saved_argv0)
 self.check(name).not_in(sys.modules)
This approach would also be handy if you needed to check multiple 
conditions on a single result:
 check = self.check(result)
 check.is_equal(expected_result) # Right answer
 check.is_not(expected_result) # Fresh object
 check.is_(recent_results[-1]) # Recorded properly
Cheers,
Nick.
-- 
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
 http://www.boredomandlaziness.org


More information about the Python-Dev mailing list

AltStyle によって変換されたページ (->オリジナル) /