Allowing assertEqual etc to take multiple items
Hi guys! I'm a unittest newbie, so it's possible there's a better solution than what I'm proposing here. If there is, please let me know. I recently submitted this PR <https://github.com/more-itertools/more-itertools/pull/430/files>, and I had to use assertSequenceEqual twice, just because I wanted to compare 3 sequences to each other rather than 2. Wouldn't it be possible to make assertEqual and its entire family (including assertSequenceEqual and the dozen of other methods) accept an arbitrary number of arguments, and compare all of them to each other? That way I could do this: self.assertSequenceEqual(sliced_tuple_0, sliced_tuple_1, sliced_range) We could discuss whether they'll do the faster version of a == b == c, or a more extensive check between every 2 items individually. What do you think?
Hi Ram, this is not possible without breaking a lot of code, assertSequenceEqual() already takes a third argument: Help on function assertSequenceEqual in module unittest.case: assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None) An equality assertion for ordered sequences (like lists and tuples). For the purposes of this function, a valid ordered sequence type is one which can be indexed, has a length, and has an equality operator. Args: seq1: The first sequence to compare. seq2: The second sequence to compare. seq_type: The expected datatype of the sequences, or None if no datatype should be enforced. msg: Optional message to use on failure instead of a list of differences.
28.05.20 11:02, Ram Rachum пише:
I recently submitted this PR <https://github.com/more-itertools/more-itertools/pull/430/files>, and I had to use assertSequenceEqual twice, just because I wanted to compare 3 sequences to each other rather than 2.
You have wrote much more text in this message that you would save by not typing assertSequenceEqual twice.
Wouldn't it be possible to make assertEqual and its entire family (including assertSequenceEqual and the dozen of other methods) accept an arbitrary number of arguments, and compare all of them to each other? That way I could do this:
self.assertSequenceEqual(sliced_tuple_0, sliced_tuple_1, sliced_range)
As Rémi said, it is breaking change.
We could discuss whether they'll do the faster version of a == b == c, or a more extensive check between every 2 items individually.
Why do you think it will be faster? `a == b == c` is the same as `a == b and b == c`, but a tiny bit slower. You always can write self.assertTrue(a == b == c) But the advantage of two separate assertions is that you know what comparison fails if it fails and get more informative report.
On Thu, May 28, 2020 at 11:42 AM Serhiy Storchaka <storchaka@gmail.com> wrote:
28.05.20 11:02, Ram Rachum пише:
I recently submitted this PR <https://github.com/more-itertools/more-itertools/pull/430/files>, and I had to use assertSequenceEqual twice, just because I wanted to compare 3 sequences to each other rather than 2.
You have wrote much more text in this message that you would save by not typing assertSequenceEqual twice.
I see text written in emails as about x10,000 cheaper than text written in code.
Wouldn't it be possible to make assertEqual and its entire family (including assertSequenceEqual and the dozen of other methods) accept an arbitrary number of arguments, and compare all of them to each other? That way I could do this:
self.assertSequenceEqual(sliced_tuple_0, sliced_tuple_1, sliced_range)
As Rémi said, it is breaking change.
I understand. We *could *slowly move towards having these keyword arguments be keyword-only arguments, with a patient deprecation cycle. This would probably be a good thing regardless. But I know that's a hard case to make here.
On Thu, May 28, 2020 at 11:40:52AM +0300, Serhiy Storchaka wrote:
Why do you think it will be faster? `a == b == c` is the same as `a == b and b == c`, but a tiny bit slower.
That surprises me. I thought that the big advantage of chained comparisons is that results are only evaluated once. a == expensive_expression == c should be faster than calculating the expensive expression twice: a == expensive_expression and expensive_expression == c and even if the expression is just a name lookup, isn't one name lookup cheaper than two?
You always can write
self.assertTrue(a == b == c)
But the advantage of two separate assertions is that you know what comparison fails if it fails and get more informative report.
I agree that this is a very good argument for writing separate assertions. -- Steven
participants (4)
-
Ram Rachum
-
remi.lapeyre@henki.fr
-
Serhiy Storchaka
-
Steven D'Aprano