I am developing a Python module with several source files, each with its own test class derived from unittest right in the source. Consider the directory structure:
dirFoo\ test.py dirBar\ __init__.py Foo.py Bar.py
To test either Foo.py or Bar.py, I would add this at the end of the Foo.py and Bar.py source files:
if __name__ == "__main__": unittest.main()
And run Python on either source, i.e.
$ python Foo.py ........... ---------------------------------------------------------------------- Ran 11 tests in 2.314s OK
Ideally, I would have "test.py" automagically search dirBar for any unittest derived classes and make one call to "unittest.main()". What's the best way to do this in practice?
I tried using Python to call execfile for every *.py file in dirBar, which runs once for the first .py file found & exits the calling test.py, plus then I have to duplicate my code by adding unittest.main() in every source file--which violates DRY principles.
TestCase is used to create test cases by subclassing it. The last block of the code at the bottom allows us to run all the tests just by running the file.
Internally, unittest. main() is using a few tricks to figure out the name of the module (source file) that contains the call to main() . It then imports this modules, examines it, gets a list of all classes and functions which could be tests (according the configuration) and then creates a test case for each of them.
To run all the tests in a default group, choose the Run icon and then choose the group on the menu. Select the individual tests that you want to run, open the right-click menu for a selected test and then choose Run Selected Tests (or press Ctrl + R, T).
As of Python 2.7, test discovery is automated in the unittest package. From the docs:
Unittest supports simple test discovery. In order to be compatible with test discovery, all of the test files must be modules or packages importable from the top-level directory of the project (this means that their filenames must be valid identifiers).
Test discovery is implemented in
TestLoader.discover()
, but can also be used from the command line. The basic command-line usage is:cd project_directory python -m unittest discover
By default it looks for packages named test*.py
, but this can be changed so you might use something like
python -m unittest discover --pattern=*.py
In place of your test.py script.
Here is my test discovery code that seems to do the job. I wanted to make sure I can extend the tests easily without having to list them in any of the involved files, but also avoid writing all tests in one single Übertest file.
So the structure is
myTests.py testDir\ __init__.py testA.py testB.py
myTest.py look like this:
import unittest if __name__ == '__main__': testsuite = unittest.TestLoader().discover('.') unittest.TextTestRunner(verbosity=1).run(testsuite)
I believe this is the simplest solution for writing several test cases in one directory. The solution requires Python 2.7 or Python 3.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With