From cfe722b9e066b5131d87bcefd95b3b069064d8e3 Mon Sep 17 00:00:00 2001 From: David Robertson Date: Sun, 14 Sep 2003 00:38:47 +0000 Subject: [PATCH] Added ability to read values from multiple config file sections, added setUpWsdl utility function, cleaned up loadTestsFromNames, updated comments. --- test/utils.py | 153 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 105 insertions(+), 48 deletions(-) diff --git a/test/utils.py b/test/utils.py index 8279b13..eb4ded5 100644 --- a/test/utils.py +++ b/test/utils.py @@ -3,10 +3,10 @@ # See Copyright for copyright notice! ########################################################################### -import sys, types, os.path, pickle +import sys, os.path, pickle import StringIO, copy, re -import unittest -import ConfigParser +import unittest, ConfigParser +from ZSI.wstools.WSDLTools import WSDLReader """ utils: @@ -19,7 +19,7 @@ utils: thisFileName = sys.modules[__name__].__file__ -class configHandler(ConfigParser.ConfigParser): +class ConfigHandler(ConfigParser.ConfigParser): def __init__(self, name="config.py"): ConfigParser.ConfigParser.__init__(self) @@ -30,25 +30,48 @@ class configHandler(ConfigParser.ConfigParser): self.read(os.path.dirname(thisFileName) + os.sep + name) - def getConfigNames(self, section, numMethods, valueFunc=None): + def getConfigNames(self, sections, numMethods, valueFunc=None): + """A generator which returns one value from a given config + file section at a time. It also optionally calls a + passed-function for that value, and yields the result as well. + """ + result = None - for name, value in self.items(section): - for i in range(0, numMethods): - yield value # indicate which test in all cases - if i == 0: - result = None + for section in sections: + for name, value in self.items(section): + for i in range(0, numMethods): + yield value # indicate which test in all cases + if i == 0: + result = None + if valueFunc: + try: + result = valueFunc(value) + except KeyboardInterrupt: + sys.exit(-1) # for now + except: # don't care, test will be skipped + pass if valueFunc: - try: - result = valueFunc(value) - except KeyboardInterrupt: - sys.exit(-1) # for now - except: # don't care, test will be skipped - pass - if valueFunc: - yield result + yield result + + + def length(self, sections): + """Determines the total number of items in all the + chosen sections from a config file. + """ + total = 0 + for section in sections: + total += len(self.options(section)) + return total - def length(self, section): - return len(self.options(section)) + +def setUpWsdl(path): + """Load a WSDL given a file path or a URL. + """ + if path[:7] == 'http://': + wsdl = WSDLReader().loadFromURL(path) + else: + wsdl = WSDLReader().loadFromFile(path) + return wsdl def loadPickledObj(fname): @@ -165,7 +188,7 @@ class MatchTestLoader(unittest.TestLoader): simpler and less verbose way to select a subset of tests to run. If all tests will always be run, use unittest.TestLoader instead. - If a top-level test invokes test cases in other scripts, + If a top-level test invokes test cases in other modules, MatchTestLoader should be created with topLevel set to True to get the correct results. For example, @@ -177,57 +200,92 @@ class MatchTestLoader(unittest.TestLoader): if no additional arguments beyond the test script name are provided. """ - def __init__(self, topLevel, config, defaultTest): + def __init__(self, topLevel, configName, defaultTest): unittest.TestLoader.__init__(self) self.testMethodPrefix = "test" self.defaultTest = defaultTest self.topLevel = topLevel - self.config = config - self.nameGenerator = None + if configName: + self.config = ConfigHandler(configName) + self.sections = [] + self.nameGenerator = None - def loadTestsFromNames(self, unused, module=None): - """Instead of loading the test names passed into it from - unittest.TestProgram, loadTestsFromNames uses arguments from the - command-line instead. This method is necessary because the - superclass method called from unittest.TestProgram would fail on - sub-string arguments, and because the default test would - not be called properly in some cases, if using the argument - passed in. - - There can be multiple names, both in full or as a substring, on - the command-line. After getting the arguments, this method - calls the corresponding method in the superclass. - """ + def setUpArgs(self): + """Sets up the use of arguments from the command-line to select + tests to run. There can be multiple names, both in full or as + a substring, on the command-line. + """ + sectionList = self.config.sections() self.testArgs = [] - if not self.topLevel or (len(sys.argv) != 1): - for arg in sys.argv[1:]: + argv = [] + # ignore section names in determining what to + # load (sys.argv can be passed into setSection, + # where any section names are extracted) + for name in sys.argv: + if name not in sectionList: + argv.append(name) + if not self.topLevel or (len(argv) != 1): + for arg in argv[1:]: if arg.find("-") != 0: self.testArgs.append(arg) + # has the effect of loading all tests if not self.testArgs: self.testArgs = [None] + + def loadTestsFromNames(self, unused, module=None): + """Hard-wires using the default test. It ignores the names + passed into it from unittest.TestProgram, because the + default loader would fail on substrings or section names. + """ + suites = unittest.TestLoader.loadTestsFromNames(self, (self.defaultTest,), module) return suites - def loadTestsFromConfig(self, testCaseClass, section, fname="config.py", - valueFunc=None): - config = configHandler(fname) + + def setSection(self, args): + """Sets section(s) of config file to read. + """ + sectionList = self.config.sections() + if ((type(args) is list) or + (type(args) is tuple)): + for arg in args: + if arg in sectionList: + self.sections.append(arg) + if self.sections: + return True + elif type(args) is str: + if args in sectionList: + self.sections.append(args) + return True + return False + + + + def loadTestsFromConfig(self, testCaseClass, valueFunc=None): + """Loads n number of instances of testCaseClass, where + n is the number of items in the config file section(s). + getConfigNames is a generator which is used to parcel + out the values in the section(s) to the testCaseClass + instances. + """ + + self.setUpArgs() numTestCases = self.getTestCaseNumber(testCaseClass) - self.nameGenerator = config.getConfigNames(section, + self.nameGenerator = self.config.getConfigNames(self.sections, numTestCases, valueFunc) - configLen = config.length(section) + configLen = self.config.length(self.sections) suite = unittest.TestSuite() - suite.addTest(self.loadTestsFromTestCase(testCaseClass)) - for i in range(1, configLen): + for i in range(0, configLen): suite.addTest(self.loadTestsFromTestCase(testCaseClass)) return suite def getTestCaseNumber(self, testCaseClass): - """looks for any test methods whose name contains testStr, checking + """Looks for any test methods whose name contains testStr, checking if a test method has already been added. If there is not a match, it checks for an exact match with the test case name, and returns the number of test cases. @@ -236,7 +294,6 @@ class MatchTestLoader(unittest.TestLoader): prevAdded = [] counter = 0 for testStr in self.testArgs: -# print "test argument ", testStr if testStr: for m in methods: if m.find(testStr) >= 0 and m not in prevAdded: