Reputation: 1
I have X number of python classes that all inherit from the same abstract base class, which expects children to implement a single method called executeTest()
Class TestCase:
def executeTest():
#do some logic for the test, then return if it passed or failed
In my main program I need to load an instance of each class that inherits this base class one at a time, call executeTest(), and record the result into some sort of collection for later use. The number of classes that implement TestCase will continue to grow over time, as people think up new tests to write.
How can I do this efficiently in python? Do I need to have a separate XML or similar type file which has a list of all individual class names, and then use some sort of class loading function inside a for loop? This is my first night coding in python so I'm not even really sure what techniques or keywords to search for.
Upvotes: 0
Views: 415
Reputation: 887
I will try to do it this way:
1) Save your abstract class in test_case.py
class TestCase:
def executeTest():
#do some logic for the test, then return if it passed or failed
2) Save all your child classes in in test_case_children.py
from test_case import TestCase
class Test_Case_1(TestCase):
def executeTest():
#overriden function
class Test_Case_2(TestCase):
def executeTest():
#overriden function
class Test_Case_3(TestCase):
def executeTest():
#overriden function
3) Save main function in main.py
:
from test_case import TestCase
import test_case_children
def main():
#grab the all the elements in the script 'test_case_children'
items = test_case_children.__dict__
#build list of all 'TestCase' sub-classes
test_classes = []
for (key, value) in items.items():
try:
# check whether the item is a sub-class of 'TestCase' class
if TestCase.__subclasscheck__(value):
test_classes.append(value)
except TypeError: #if item is not of type 'TestCase', ignore it
pass
#run the tests
for test_class in test_classes:
test_runner = test_class()
test_runner.executeTest()
# this will run main() method, only when script is directly executed
# from shell or command prompt ...
if __name__ == "__main__":
main()
4) Execute the main.py
script:
$ python main.py
Note: One more thing, the folder in which you will save these files should also contain an empty __init__.py
file to make that folder as python app(something like packages
in Java
or namespaces
in C++
). If you don't then those import statements will not work, probably.
[ Update for running test_cases from different files ]
1) Keep the files in following heirarchy:
<root>/
------>test_case/
---------------->__init__.py
---------------->main.py
---------------->test_case.py
---------------->test_case_children/
--------------------------------->__init__.py
--------------------------------->test_case_1.py
--------------------------------->test_case_2.py
--------------------------------->test_case_3.py
2) Save your abstract class in test_case/test_case.py
class TestCase:
def executeTest():
#do some logic for the test, then return if it passed or failed
3) Save sub-classes like this:
File: test_case/test_case_children/test_case_1.py
from test_case.test_case import TestCase
class Test_Case_1(TestCase):
def executeTest():
#overriden function
File: test_case/test_case_children/test_case_2.py
from test_case.test_case import TestCase
class Test_Case_2(TestCase):
def executeTest():
#overriden function
File: test_case/test_case_children/test_case_3.py
from test_case.test_case import TestCase
class Test_Case_3(TestCase):
def executeTest():
#overriden function
4) Save main function in main.py
:
from test_case import TestCase
from test_case import test_case_children
def main():
#grab the all the elements in the module 'test_case_children'
items = test_case_children.__dict__
#build list of all 'TestCase' sub-classes
test_classes = []
for (dict_key, dict_value) in items:
#check whether the type of item's value is a module,
# if its a module it's likely to contain a TestCase subclass...
if str(type(dict_value)) == "<type 'module'>":
for (key, value) in dict_value.items():
try:
# check whether the item is a sub-class of 'TestCase' class
if TestCase.__subclasscheck__(value):
test_classes.append(value)
except TypeError: #if item is not of type 'TestCase', ignore it
pass
#run the tests
for test_class in test_classes:
test_runner = test_class()
test_runner.executeTest()
# this will run main() method, only when script is directly executed
# from shell or command prompt ...
if __name__ == "__main__":
main()
5) Execute the main.py
script:
$ cd test_case/
$ python main.py
I hope this would work for you.
Upvotes: 0
Reputation: 4612
This is a meta answer - which means that I think that you should think about your design calling tests.
In python there are well established ways to write tests. [1] And there are also tools which collect all the available tests and executes them (including stats, coverage, xml output, ...). [2]
If I were you I would have a look at them. If you can use them, there is no need to re-invent the wheel.
[1] http://docs.python.org/library/unittest.html
[2] http://readthedocs.org/docs/nose/en/latest/
Upvotes: 2
Reputation: 798754
Use a decorator to enumerate the classes, and execute the methods with a list comprehension.
Upvotes: 0