40

For the following code:

import unittest

class Test(unittest.TestCase):
    def test1(self):
        assert(True == True)

if __name__ == "__main__":
    suite = unittest.TestSuite()
    suite.addTest(Test())
    unittest.TextTestRunner().run(suite)

Using Python 3 to execute it, the following error is raised:

Traceback (most recent call last):
  File "test.py", line 10, in <module>
    unittest.TextTestRunner().run(suite)
  File "/usr/lib/python3.2/unittest/runner.py", line 168, in run
    test(result)
  File "/usr/lib/python3.2/unittest/suite.py", line 67, in __call__
    return self.run(*args, **kwds)
  File "/usr/lib/python3.2/unittest/suite.py", line 105, in run
    test(result)
  File "/usr/lib/python3.2/unittest/case.py", line 477, in __call__
    return self.run(*args, **kwds)
  File "/usr/lib/python3.2/unittest/case.py", line 408, in run
    testMethod = getattr(self, self._testMethodName)
AttributeError: 'Test' object has no attribute 'runTest'

But unittest.main() works.

6 Answers 6

49

You need to invoke a TestLoader:

if __name__ == "__main__":
    suite = unittest.defaultTestLoader.loadTestsFromTestCase(Test)
    unittest.TextTestRunner().run(suite)
Sign up to request clarification or add additional context in comments.

Comments

15

You have to specify the test method name (test1):

import unittest

class Test(unittest.TestCase):
    def test1(self):
        assert(True == True)

if __name__ == "__main__":
    suite = unittest.TestSuite()
    suite.addTest(Test('test1')) # <----------------
    unittest.TextTestRunner().run(suite)

Or, if you want to run all tests in the file, Just calling unittest.main() is enough:

if __name__ == "__main__":
    unittest.main()

Comments

0

Adding to the answer of Janne:

If the tests included in several TestCase classes need to be run, addTests() will do:

suite = unittest.TestSuite()
suite.addTests(unittest.defaultTestLoader.loadTestsFromTestCase(TestCase1)))
suite.addTests(unittest.defaultTestLoader.loadTestsFromTestCase(TestCase2)))

Comments

0

Update Jan 2025, Python 3

This error is happening becuse you have not add Test in Suite

suite = unittest.TestSuite()
suite.addTest(Test())  ^<----- Need to pass method name to run here
unittest.TextTestRunner().run(suite)

Complet Answer with example

Suppose you have a Test class with 2 tests:

import unittest


class TestMainApp(unittest.TestCase):

    def setUp(self):
        print("staring TestMainApp")

    def tearDown(self):
        print("stopping TestMainApp")

    def test_something(self):
        print("testing something")
        self.assertEqual(True, True)  # add assertion here

    def test_something_else(self):
        print("testing something else")
        self.assertEqual(True, True)  # add assertion here


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

2 Ways to create Test Suite

Now to create test suite you can either instruct to include all methods in Test class and you can disable tests in test class itself.

OR

Or you can you can select methods you want to run under a test suite.

Here is an example of both. I am loading slected tests by calling load_tests method here

import unittest

from tests.app.app_test import TestMainApp

def create_suite():
    # Load and Run partial Test
    testToRun = [TestMainApp(TestMainApp.test_something.__name__)]
    test_suite = load_tests(testToRun)

    # Uncomment below to Load and Run all Tests
    # test_suite = load_all_tests()

    return test_suite

def load_tests(tests_to_run):
    test_suite = unittest.TestSuite()

    # Add selected tests to the test suite
    for test in tests_to_run:
        test_suite.addTest(test)

    return test_suite


def load_all_tests():
    # Add all tests to the test suite
    test_suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestMainApp)
    return test_suite


if __name__ == '__main__':
    unittest.TextTestRunner().run(create_suite())

Output of creating suite with load_tests will ignore test_something_else

staring TestMainApp
testing something
stopping TestMainApp

Output with load_all_tests method to create test suite will include all tests:

staring TestMainApp
testing something
stopping TestMainApp
staring TestMainApp
testing something else
stopping TestMainApp

Comments

-1

The actual test for any TestCase subclass is performed in the runTest() method. Simply change your code to:

class Test(unittest.TestCase):
    def runTest(self):
        assert(True == True)

3 Comments

Yes, it works. But is there a way to make it work without changing the Test class? @bhajun-singh.
Just say pass instead of assert(True == True)
This documentation seems to say otherwise. To wit: "Each instance of TestCase will run a single base method: the method named methodName. In most uses of TestCase, you will neither change the methodName nor reimplement the default runTest() method."
-1

You can run it like this:

python -m unittest <your-module-name>

I don't fully understand why it works though.

Comments

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.