18

I have this test

import unittest

class TestName(unittest.TestCase):

        def setUp(self):
                self.name = "Bob"
                self.expected_name = "Bob"


        def test_name(self):
                # ... some operation over self.name
                print self.name
                self.assertEquals(self.name, self.expected_name)

if __name__ == '__main__':
        unittest.main(verbosity=2)

how I can run instances for the test ?

run the same test for a list of inputs and outputs (["Bob", "Alice", ...]) , maybe like

TestName(name="Bob", expected_name="Bob")
TestName(name="Alice", expected_name="Alice")
Corey Goldberg
  • 59,062
  • 28
  • 129
  • 143
JuanPablo
  • 23,792
  • 39
  • 118
  • 164
  • 1
    Just FYI, take a look at [ddt](https://github.com/txels/ddt) package. – alecxe Feb 24 '14 at 14:30
  • related: https://stackoverflow.com/questions/2798956/python-unittest-generate-multiple-tests-programmatically/2799009#2799009, https://stackoverflow.com/questions/32899/how-do-you-generate-dynamic-parameterized-unit-tests-in-python – Rufus Feb 14 '19 at 03:38

2 Answers2

26

Check out DDT (Data-Driven/Decorated Tests).

DDT allows you to multiply a test case by running it with different test data, making it appear as multiple test cases.

consider this example, using DDT:

import unittest

from ddt import ddt, data, unpack


@ddt
class TestName(unittest.TestCase):

        # simple decorator usage:
        @data(1, 2)
        def test_greater_than_zero(self, value):
            self.assertGreater(value, 0)

        # passing data in tuples to achieve the 
        # scenarios from your given example:
        @data(('Bob', 'Bob'), ('Alice', 'Alice'))
        @unpack
        def test_name(self, first_value, second_value):
            name, expected_name = first_value, second_value
            self.assertEquals(name, expected_name)

if __name__ == '__main__':
        unittest.main(verbosity=2)

I defined 2 test methods in the above code, but 4 test cases will be run, using the data I supplied in the decorator.

Output:

test_greater_than_zero_1 (__main__.TestName) ... ok
test_greater_than_zero_2 (__main__.TestName) ... ok
test_name_('Alice', 'Alice') (__main__.TestName) ... ok
test_name_('Bob', 'Bob') (__main__.TestName) ... ok

----------------------------------------------------------------------
Ran 4 tests in 0.000s

OK
Corey Goldberg
  • 59,062
  • 28
  • 129
  • 143
4

I would use a mixin or a metaclass here, as unittest looks for classes, not instances.

class TestMixin (object):
    def test_name ():
        print self.name

class TestName (unittest.TestCase, TestMixin):
    ...
Bartosz Marcinkowski
  • 6,651
  • 4
  • 39
  • 69