Abstract class and abastract Unitest

Question:

I use Django Rest Framework and I wrote something like this:

class Vehicule(ABC):
    wheel = None
    roof = None

    def drive():
        use wheel and roof, blabla...

class Car(Vehicule):
    wheel = 4
    roof = True

class Bike(Vehicule):
    wheel = 2
    roof = False

It’s working good and I want to write unitest with it.I want to write someting similar:

class TestVehicule(ABC, TestCase):
    wheel = None
    roof = None
    factory = None
    
    def test_how_many_wheel(self):
        self.assertEqual(factory.wheel, self.wheel)

    def test_is_roof(self):
        self.assertEqual(factory.roof, self.roof)

class TestCar(TestVehicule)
    wheel = 4
    roof = True
    factory = CarFactory

class TestBike(TestVehicule)
    wheel = 2
    roof = False
    factory = BikeFactory

The goal is to write tests in TestVehicule and inherit in others class change variable and do all the tests with the child variable

Asked By: Kanarpp

||

Answers:

The easiest way around the problem would be to only inherit TestCase for your non-abstract classes:

class TestVehicle(ABC):
    ...

class TestCar(TestVehicle, unittest.TestCase):
    ...

class TestBike(TestVehiule, unittest.TestCase):
    ...

Technically, your TestVehicle doesn’t even need to be abstract at this point, if all you want is for unittest to ignore its cases.

Answered By: Igonato

It seems like you’re trying to create a base test class with some common tests for the Vehicule abstract class and then inherit from it to create specific test classes for the Car and Bike classes.

Here’s an updated version of your code that should work:

    class TestVehicule(TestCase):
    factory = None
    
    def test_how_many_wheel(self):
        self.assertEqual(self.factory().wheel, self.wheel)

    def test_is_roof(self):
        self.assertEqual(self.factory().roof, self.roof)

class TestCar(TestVehicule):
    wheel = 4
    roof = True
    factory = Car

class TestBike(TestVehicule):
    wheel = 2
    roof = False
    factory = Bike

Here are the changes that I made:

Removed the ABC from TestVehicule as it’s not needed.
Removed wheel and roof attributes from TestVehicule as they’re only needed in the child classes.
Changed the factory attribute to be an actual class (e.g. Car) instead of a non-existent class attribute (e.g. CarFactory).
Added () to self.factory() to create an instance of the class.
Now you should be able to run tests on TestCar and TestBike to ensure that they’re working correctly.

Answered By: Madhav Dhungana
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.