2

I've written a custom assertion to test if two lists of objects contain objects with the same attributes, and now I want to use the negation of the test to check if two lists are unequal.

from unittest import TestCase
from classes import *

class BaseTestCase(TestCase):
    def assertCountObjectsEqual(self, list1, list2):
        if len(list1) != len(list2):
            raise AssertionError("lists must be the same length")
        elif any(t1.__class__ != t2.__class__ or t1.__dict__ != t2.__dict__ for t1, t2 in zip(list1, list2)):
            raise AssertionError("objects are not the same")
        else:
            pass

The positive case works

class TestFillDemand(BaseTestCase):
    def test_fruit(self):
        self.assertCountObjectsEqual([Apple(), Apple(), Banana()], [Apple(), Apple(), Banana()])

But I want to be able to reuse the code for something like the following:

    def test_fruit_unequal(self):
        self.assertRaises(AssertionError, self.assertCountObjectsEqual([Apple(), Apple(), Banana()], [Apple(), Banana()]))

rather than having to redefine an assertCountObjectsUnequal method. Unfortunately the above code doesn't work.

Is there an easy way to do that?

1 Answer 1

2

One option would be to wrap your list of objects into a custom "Collection" class defining the __eq__() magic method. This way, you will be able to utilize built-in assertion methods - assertEqual() and assertNotEqual():

from unittest import TestCase

class Apple:
    pass


class Banana:
    pass


class Collection:
    def __init__(self, objects):
        self.objects = objects

    def __eq__(self, other):
        if len(self.objects) != len(other.objects):
            return False
        if any(t1.__class__ != t2.__class__ or t1.__dict__ != t2.__dict__ for t1, t2 in zip(self.objects, other.objects)):
            return False

        return True


class BaseTestCase(TestCase):
    def test_fruit_equal(self):
        self.assertEqual(Collection([Apple(), Apple(), Banana()]), Collection([Apple(), Apple(), Banana()]))

    def test_fruit_unequal(self):
        self.assertNotEqual(Collection([Apple(), Apple(), Banana()]), Collection([Apple(), Banana()]))

Both tests pass.

Sign up to request clarification or add additional context in comments.

1 Comment

This works, but I guess I wanted to know whether there was a way to negate a test, without having to define the "Not" version separately.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.