Best Python code snippet using PyHamcrest_python
regressions.py
Source:regressions.py
1#!/usr/bin/python -u2import glob, os, string, sys, thread, time3# import difflib4import libxml25###6#7# This is a "Work in Progress" attempt at a python script to run the8# various regression tests. The rationale for this is that it should be9# possible to run this on most major platforms, including those (such as10# Windows) which don't support gnu Make.11#12# The script is driven by a parameter file which defines the various tests13# to be run, together with the unique settings for each of these tests. A14# script for Linux is included (regressions.xml), with comments indicating15# the significance of the various parameters. To run the tests under Windows,16# edit regressions.xml and remove the comment around the default parameter17# "<execpath>" (i.e. make it point to the location of the binary executables).18#19# Note that this current version requires the Python bindings for libxml2 to20# have been previously installed and accessible21#22# See Copyright for the status of this software.23# William Brack (wbrack@mmm.com.hk)24#25###26defaultParams = {} # will be used as a dictionary to hold the parsed params27# This routine is used for comparing the expected stdout / stdin with the results.28# The expected data has already been read in; the result is a file descriptor.29# Within the two sets of data, lines may begin with a path string. If so, the30# code "relativises" it by removing the path component. The first argument is a31# list already read in by a separate thread; the second is a file descriptor.32# The two 'base' arguments are to let me "relativise" the results files, allowing33# the script to be run from any directory.34def compFiles(res, expected, base1, base2):35 l1 = len(base1)36 exp = expected.readlines()37 expected.close()38 # the "relativisation" is done here39 for i in range(len(res)):40 j = string.find(res[i],base1)41 if (j == 0) or ((j == 2) and (res[i][0:2] == './')):42 col = string.find(res[i],':')43 if col > 0:44 start = string.rfind(res[i][:col], '/')45 if start > 0:46 res[i] = res[i][start+1:]47 for i in range(len(exp)):48 j = string.find(exp[i],base2)49 if (j == 0) or ((j == 2) and (exp[i][0:2] == './')):50 col = string.find(exp[i],':')51 if col > 0:52 start = string.rfind(exp[i][:col], '/')53 if start > 0:54 exp[i] = exp[i][start+1:]55 ret = 056 # ideally we would like to use difflib functions here to do a57 # nice comparison of the two sets. Unfortunately, during testing58 # (using python 2.3.3 and 2.3.4) the following code went into59 # a dead loop under windows. I'll pursue this later.60# diff = difflib.ndiff(res, exp)61# diff = list(diff)62# for line in diff:63# if line[:2] != ' ':64# print string.strip(line)65# ret = -166 # the following simple compare is fine for when the two data sets67 # (actual result vs. expected result) are equal, which should be true for68 # us. Unfortunately, if the test fails it's not nice at all.69 rl = len(res)70 el = len(exp)71 if el != rl:72 print 'Length of expected is %d, result is %d' % (el, rl)73 ret = -174 for i in range(min(el, rl)):75 if string.strip(res[i]) != string.strip(exp[i]):76 print '+:%s-:%s' % (res[i], exp[i])77 ret = -178 if el > rl:79 for i in range(rl, el):80 print '-:%s' % exp[i]81 ret = -182 elif rl > el:83 for i in range (el, rl):84 print '+:%s' % res[i]85 ret = -186 return ret87# Separate threads to handle stdout and stderr are created to run this function88def readPfile(file, list, flag):89 data = file.readlines() # no call by reference, so I cheat90 for l in data:91 list.append(l)92 file.close()93 flag.append('ok')94# This routine runs the test program (e.g. xmllint)95def runOneTest(testDescription, filename, inbase, errbase):96 if 'execpath' in testDescription:97 dir = testDescription['execpath'] + '/'98 else:99 dir = ''100 cmd = os.path.abspath(dir + testDescription['testprog'])101 if 'flag' in testDescription:102 for f in string.split(testDescription['flag']):103 cmd += ' ' + f104 if 'stdin' not in testDescription:105 cmd += ' ' + inbase + filename106 if 'extarg' in testDescription:107 cmd += ' ' + testDescription['extarg']108 noResult = 0109 expout = None110 if 'resext' in testDescription:111 if testDescription['resext'] == 'None':112 noResult = 1113 else:114 ext = '.' + testDescription['resext']115 else:116 ext = ''117 if not noResult:118 try:119 fname = errbase + filename + ext120 expout = open(fname, 'rt')121 except:122 print "Can't open result file %s - bypassing test" % fname123 return124 noErrors = 0125 if 'reserrext' in testDescription:126 if testDescription['reserrext'] == 'None':127 noErrors = 1128 else:129 if len(testDescription['reserrext'])>0:130 ext = '.' + testDescription['reserrext']131 else:132 ext = ''133 else:134 ext = ''135 if not noErrors:136 try:137 fname = errbase + filename + ext138 experr = open(fname, 'rt')139 except:140 experr = None141 else:142 experr = None143 pin, pout, perr = os.popen3(cmd)144 if 'stdin' in testDescription:145 infile = open(inbase + filename, 'rt')146 pin.writelines(infile.readlines())147 infile.close()148 pin.close()149 # popen is great fun, but can lead to the old "deadly embrace", because150 # synchronizing the writing (by the task being run) of stdout and stderr151 # with respect to the reading (by this task) is basically impossible. I152 # tried several ways to cheat, but the only way I have found which works153 # is to do a *very* elementary multi-threading approach. We can only hope154 # that Python threads are implemented on the target system (it's okay for155 # Linux and Windows)156 th1Flag = [] # flags to show when threads finish157 th2Flag = []158 outfile = [] # lists to contain the pipe data159 errfile = []160 th1 = thread.start_new_thread(readPfile, (pout, outfile, th1Flag))161 th2 = thread.start_new_thread(readPfile, (perr, errfile, th2Flag))162 while (len(th1Flag)==0) or (len(th2Flag)==0):163 time.sleep(0.001)164 if not noResult:165 ret = compFiles(outfile, expout, inbase, 'test/')166 if ret != 0:167 print 'trouble with %s' % cmd168 else:169 if len(outfile) != 0:170 for l in outfile:171 print l172 print 'trouble with %s' % cmd173 if experr != None:174 ret = compFiles(errfile, experr, inbase, 'test/')175 if ret != 0:176 print 'trouble with %s' % cmd177 else:178 if not noErrors:179 if len(errfile) != 0:180 for l in errfile:181 print l182 print 'trouble with %s' % cmd183 if 'stdin' not in testDescription:184 pin.close()185# This routine is called by the parameter decoding routine whenever the end of a186# 'test' section is encountered. Depending upon file globbing, a large number of187# individual tests may be run.188def runTest(description):189 testDescription = defaultParams.copy() # set defaults190 testDescription.update(description) # override with current ent191 if 'testname' in testDescription:192 print "## %s" % testDescription['testname']193 if not 'file' in testDescription:194 print "No file specified - can't run this test!"195 return196 # Set up the source and results directory paths from the decoded params197 dir = ''198 if 'srcdir' in testDescription:199 dir += testDescription['srcdir'] + '/'200 if 'srcsub' in testDescription:201 dir += testDescription['srcsub'] + '/'202 rdir = ''203 if 'resdir' in testDescription:204 rdir += testDescription['resdir'] + '/'205 if 'ressub' in testDescription:206 rdir += testDescription['ressub'] + '/'207 testFiles = glob.glob(os.path.abspath(dir + testDescription['file']))208 if testFiles == []:209 print "No files result from '%s'" % testDescription['file']210 return211 # Some test programs just don't work (yet). For now we exclude them.212 count = 0213 excl = []214 if 'exclfile' in testDescription:215 for f in string.split(testDescription['exclfile']):216 glb = glob.glob(dir + f)217 for g in glb:218 excl.append(os.path.abspath(g))219 # Run the specified test program220 for f in testFiles:221 if not os.path.isdir(f):222 if f not in excl:223 count = count + 1224 runOneTest(testDescription, os.path.basename(f), dir, rdir)225#226# The following classes are used with the xmlreader interface to interpret the227# parameter file. Once a test section has been identified, runTest is called228# with a dictionary containing the parsed results of the interpretation.229#230class testDefaults:231 curText = '' # accumulates text content of parameter232 def addToDict(self, key):233 txt = string.strip(self.curText)234# if txt == '':235# return236 if key not in defaultParams:237 defaultParams[key] = txt238 else:239 defaultParams[key] += ' ' + txt240 241 def processNode(self, reader, curClass):242 if reader.Depth() == 2:243 if reader.NodeType() == 1:244 self.curText = '' # clear the working variable245 elif reader.NodeType() == 15:246 if (reader.Name() != '#text') and (reader.Name() != '#comment'):247 self.addToDict(reader.Name())248 elif reader.Depth() == 3:249 if reader.Name() == '#text':250 self.curText += reader.Value()251 elif reader.NodeType() == 15: # end of element252 print "Defaults have been set to:"253 for k in defaultParams.keys():254 print " %s : '%s'" % (k, defaultParams[k])255 curClass = rootClass()256 return curClass257class testClass:258 def __init__(self):259 self.testParams = {} # start with an empty set of params260 self.curText = '' # and empty text261 def addToDict(self, key):262 data = string.strip(self.curText)263 if key not in self.testParams:264 self.testParams[key] = data265 else:266 if self.testParams[key] != '':267 data = ' ' + data268 self.testParams[key] += data269 def processNode(self, reader, curClass):270 if reader.Depth() == 2:271 if reader.NodeType() == 1:272 self.curText = '' # clear the working variable273 if reader.Name() not in self.testParams:274 self.testParams[reader.Name()] = ''275 elif reader.NodeType() == 15:276 if (reader.Name() != '#text') and (reader.Name() != '#comment'):277 self.addToDict(reader.Name())278 elif reader.Depth() == 3:279 if reader.Name() == '#text':280 self.curText += reader.Value()281 elif reader.NodeType() == 15: # end of element282 runTest(self.testParams)283 curClass = rootClass()284 return curClass285class rootClass:286 def processNode(self, reader, curClass):287 if reader.Depth() == 0:288 return curClass289 if reader.Depth() != 1:290 print "Unexpected junk: Level %d, type %d, name %s" % (291 reader.Depth(), reader.NodeType(), reader.Name())292 return curClass293 if reader.Name() == 'test':294 curClass = testClass()295 curClass.testParams = {}296 elif reader.Name() == 'defaults':297 curClass = testDefaults()298 return curClass299def streamFile(filename):300 try:301 reader = libxml2.newTextReaderFilename(filename)302 except:303 print "unable to open %s" % (filename)304 return305 curClass = rootClass()306 ret = reader.Read()307 while ret == 1:308 curClass = curClass.processNode(reader, curClass)309 ret = reader.Read()310 if ret != 0:311 print "%s : failed to parse" % (filename)312# OK, we're finished with all the routines. Now for the main program:-313if len(sys.argv) != 2:314 print "Usage: maketest {filename}"315 sys.exit(-1)...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!