I want to run a set of tests under different conditions and therefore share these tests between two different TestCase-derived classes.
One creates its own standalone session and the other attaches to an existing session and executes the same tests in there.
I guess I'm kind of abusing the unittest framework when testing an API with it but it doesn't feel like it's too far from its original purpose. Am I good so far?
I hacked a few things together and got it kind of running. But the way it's done, doesn't feel right and I'm afraid will cause problems sooner or later.
These are the problems I have with my solution:
- When simply running the thing with PyCharm without limiting the tests, it attempts to run not only the intended - StandaloneSessionTestsand- ExistingSessionTestsbut also- GroupOfTestswhich is only the collection and has no session, i.e. execution context.
- I can make it not run - GroupOfTestsby not deriving that one from- TestCasebut then PyCharm complains that it doesn't know about the- assert...()functions. Rightly so, because- GroupOfTestonly gets indirect access to these functions at runtime when a derived class also inherits from- TestCase. Coming from a C++ background, this feels like black magic and I don't think I should be doing this.
I tried passing the session creation classes to the constructor of GroupOfTests like this: __init__(self, session_class). But this causes problems when the unittest framework attempts to instantiate the tests: It doesn't know what to do with the additional __init__ parameter.
I learned about @classmethod, which seems to be a way to get around the "only one constructor" limitation of Python but I couldn't figure out a way to get it running.
I'm looking for a solution that lets me state something as straightforward as this:
suite = unittest.TestSuite()
suite.addTest(GroupOfTests(UseExistingSession))
suite.addTest(GroupOfTests(CreateStandaloneSession))
...
This is what I got so far:
#!/usr/bin/python3
import unittest
def existing_session():
    return "existingsession"
def create_session():
    return "123"
def close_session(session_id):
    print("close session %s" % session_id)
    return True
def do_thing(session_id):
    return len(session_id)
class GroupOfTests(unittest.TestCase):  # GroupOfTests gets executed, which makes no sense.
#class GroupOfTests:  # use of assertGreaterThan() causes pycharm warning
    session_id = None
    def test_stuff(self):
        the_thing = do_thing(self.session_id)
        self.assertGreater(the_thing, 2)
    # Original code contains many other tests, which must not be duplicated
class UseExistingSession(unittest.TestCase):
    session_id = None
    def setUp(self):
        self.session_id = existing_session()
    def tearDown(self):
        pass  # Nothing to do
class CreateStandaloneSession(unittest.TestCase):
    session_id = None
    def setUp(self):
        self.session_id = create_session()
    def tearDown(self):
        close_session(self.session_id)
# unittest framework runs inherited test_stuff()
class StandaloneSessionTests(CreateStandaloneSession, GroupOfTests):
    pass
# unittest framework runs inherited test_stuff()
class ExistingSessionTests(UseExistingSession, GroupOfTests):
    pass
def main():
    suite = unittest.TestSuite()
    suite.addTest(StandaloneSessionTests)
    suite.addTest(ExistingSessionTests)
    runner = unittest.TextTestRunner()
    runner.run(suite())
if __name__ == '__main__':
    main()
 
     
    