You are here: Home > Dive Into Python > Regression Testing > Putting it all together | << >> | ||||
Dive Into PythonPython from novice to pro |
We've learned enough now to deconstruct the first seven lines of this chapter's code sample: reading a directory and importing selected modules within it.
def regressionTest(): path = os.path.abspath(os.path.dirname(sys.argv[0])) files = os.listdir(path) test = re.compile("test\.py$", re.IGNORECASE) files = filter(test.search, files) filenameToModuleName = lambda f: os.path.splitext(f)[0] moduleNames = map(filenameToModuleName, files) modules = map(__import__, moduleNames) load = unittest.defaultTestLoader.loadTestsFromModule return unittest.TestSuite(map(load, modules))
Let's look at it line by line, interactively. Assume that the current directory is c:\diveintopython\py, which contains the examples that come with this book, including this chapter's script. As we saw in Finding the path, the script directory will end up in the path variable, so let's start hard-code that and go from there.
>>> import sys, os, re, unittest >>> path = r'c:\diveintopython\py' >>> files = os.listdir(path) >>> files['BaseHTMLProcessor.py', 'LICENSE.txt', 'apihelper.py', 'apihelpertest.py', 'argecho.py', 'autosize.py', 'builddialectexamples.py', 'dialect.py', 'fileinfo.py', 'fullpath.py', 'kgptest.py', 'makerealworddoc.py', 'odbchelper.py', 'odbchelpertest.py', 'parsephone.py', 'piglatin.py', 'plural.py', 'pluraltest.py', 'pyfontify.py', 'regression.py', 'roman.py', 'romantest.py', 'uncurly.py', 'unicode2koi8r.py', 'urllister.py', 'kgp', 'plural', 'roman', 'colorize.py']
>>> test = re.compile("test\.py$", re.IGNORECASE)>>> files = filter(test.search, files)
>>> files
['apihelpertest.py', 'kgptest.py', 'odbchelpertest.py', 'pluraltest.py', 'romantest.py']
>>> filenameToModuleName = lambda f: os.path.splitext(f)[0]>>> filenameToModuleName('romantest.py')
'romantest' >>> filenameToModuleName('odchelpertest.py') 'odbchelpertest' >>> moduleNames = map(filenameToModuleName, files)
>>> moduleNames
['apihelpertest', 'kgptest', 'odbchelpertest', 'pluraltest', 'romantest']
![]() |
As we saw in Using lambda functions, lambda is a quick-and-dirty way of creating an inline, one-line function. This one takes a filename with an extension and returns just the filename part, using the standard library function os.path.splitext that we saw in Example 6.17, “Splitting pathnames”. |
![]() |
filenameToModuleName is a function. There's nothing magic about lambda functions as opposed to regular functions that we define with a def statement. We can call the filenameToModuleName function like any other, and it does just what we wanted it to do: strips the file extension off of its argument. |
![]() |
Now we can apply this function to each file in our list of unit test files, using map. |
![]() |
And the result is just what we wanted: a list of modules, as strings. |
>>> modules = map(__import__, moduleNames)>>> modules
[<module 'apihelpertest' from 'apihelpertest.py'>, <module 'kgptest' from 'kgptest.py'>, <module 'odbchelpertest' from 'odbchelpertest.py'>, <module 'pluraltest' from 'pluraltest.py'>, <module 'romantest' from 'romantest.py'>] >>> modules[-1]
<module 'romantest' from 'romantest.py'>
![]() |
As we saw in Dynamically importing modules, we can use a combination of map and __import__ to map a list of module names (as strings) into actual modules (which we can call or access like any other module). |
![]() |
modules is now a list of modules, fully accessible like any other module. |
![]() |
The last module in the list is the romantest module, just as if we had said import romantest. |
>>> load = unittest.defaultTestLoader.loadTestsFromModule >>> map(load, modules)[<unittest.TestSuite tests=[ <unittest.TestSuite tests=[<apihelpertest.BadInput testMethod=testNoObject>]>, <unittest.TestSuite tests=[<apihelpertest.KnownValues testMethod=testApiHelper>]>, <unittest.TestSuite tests=[ <apihelpertest.ParamChecks testMethod=testCollapse>, <apihelpertest.ParamChecks testMethod=testSpacing>]>, ... ] ] >>> unittest.TestSuite(map(load, modules))
![]()
This introspection process is what the unittest module usually does for us. Remember that magic-looking unittest.main() function that our individual test modules called to kick the whole thing off? unittest.main() actually creates an instance of unittest.TestProgram, which in turn creates an instance of a unittest.defaultTestLoader and loads it up with the module that called it. (How does it get a reference to the module that called it if we don't give it one? By using the equally-magic __import__('__main__') command, which dynamically imports the currently-running module. I could write a book on all the tricks and techniques used in the unittest module, but then I'd never finish this one.)
if __name__ == "__main__": unittest.main(defaultTest="regressionTest")![]()
<< Dynamically importing modules |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
Summary >> |