<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>The API for the unittest module has grown fat (the documentation</div><div>is approaching 2,000 lines and 10,000 words like a small book). </div><div>I think we can improve learnability by focusing on the most </div><div>important parts of the API.</div></div><div><br></div><div>I would like to simplify and clean-up the API for the unittest module</div><div><div>by de-documenting assertSetEqual(), assertDictEqual(),</div></div><div>assertListEqual, and assertTupleEqual().</div><div><br></div><div>All of those methods are already called automatically by </div><div>assertEqual(), so those methods never need to be called directly. </div><div>Or, if you need to be more explicit about the type checking for </div><div>sequences, the assertSequenceEqual() method will suffice.</div><div>Either way, there's no need to expose the four type specific methods.</div><div><br></div><div>Besides de-documenting those four redundant methods,</div><div>I propose that assertItemsEqual() be deprecated just like</div><div>its brother assertSameElements(). I haven't found anyone</div><div>who accurately guesses what those methods entail based</div><div>on their method names ("items" usually implies key/value </div><div>pairs elsewhere in the language; nor is it clear whether order is </div><div>important, whether the elements need to be hashable or</div><div>orderable or just define equality tests, nor is is clear whether </div><div>duplicates cause the test to fail).</div><div><br></div><div>Given the purpose of the unittest module, it's important that</div><div>the reader have a crystal clear understanding of what a test</div><div>is doing. Their attention needs to be focused on the subject</div><div>of the test, not on questioning the semantics of the test method.</div><div><br></div><div>IMO, users are far better-off sticking with assertEqual() so they</div><div>can be specific about the nature of the test:</div><div><br></div><div><span class="Apple-style-span" style="font-family: Courier; "> # hashable elements; ignore dups</span></div><div><font class="Apple-style-span" face="Courier"> assertEqual(set(a), set(b))</font></div><div><font class="Apple-style-span" face="Courier"><br></font></div><div><font class="Apple-style-span" face="Courier"> # orderable elements; dups matter, order doesn't</font></div><div><font class="Apple-style-span" face="Courier"> assertEqual(sorted(a), sorted(b))</font></div><div><font class="Apple-style-span" face="Courier"><br></font></div><div><font class="Apple-style-span" face="Courier"> # eq tested elements, dups matter, order matters</font></div><div><font class="Apple-style-span" face="Courier"> assertEqual(list(a), list(b))</font></div><div><font class="Apple-style-span" face="Courier"><br></font></div><div><font class="Apple-style-span" face="Courier"> # hashable keys, eq tested values</font></div><div><font class="Apple-style-span" face="Courier"> # ignore dups, ignore order</font></div><div><font class="Apple-style-span" face="Courier"> assertEqual(dict(a), dict(b))</font></div><div><br></div><div>These take just a few more characters than assertSameElements()</div><div>and assertItemsEqual(), but they are far more clear about their meaning. </div><div>You won't have to second guess what semantics are hidden </div><div>behind the abstraction.</div><div><br></div><div>There are a couple other problems with the new API but it is probably</div><div>too late to do anything about it.</div><div><br></div><div>* elsewhere in Python we spell comparison names with abbreviations</div><div> like eq, ne, lt, le, gt, ge. In unittest, those are spelled in an awkward,</div><div> not easily remembered manner: assertLessEqual(a, b), etc. </div><div> Fortunately, it's clear what the mean; however, it's not easy to guess </div><div> their spelling.</div><div><br></div><div>* the names for assertRegexpMatches() and assertNotRegexpMatches</div><div> are deeply misleading since they are implemented in terms of</div><div> re.search(), not re.match(). </div><div><br></div><div><br></div><div>Raymond</div><div><br></div><div><br></div><div>P.S. I also looked ar assertDictContainsSubset(a,b). It is a bit</div><div>over-specialized, but at least it is crystal clear what is does</div><div>and it beats the awkward alternative using dict views:</div><div><br></div><div> assertLessEqual(a.items(), b.items())</div><div><br></div><div><br></div></body></html>