# -*- coding: GBK -*- #write:zb # ##@package PythonTrack.py # Ä£¿éµÄ¼òҪ˵Ã÷:´úÂëÖ´ÐÐÂÊ×·×ÙÄ£¿é # @author:zb # @date 2010-01-01 00:00 # @version 2.0 # # ÐÞ¸Äʱ¼ä ÐÞ¸ÄÈË ÐÞ¸ÄÄÚÈÝ # @change: "2010-05-14 09:35" zb ¸ü¸Ä´úÂë×¢ÊÍ # @change: "2010-06-09 17:50" zfl ÐÞ¸ÄPY½âÎöÂß¼­¡¢ÐÂÔö²¿·Ö¹¦ÄÜ # @change: "2010-07-02 17:30" zfl ÐÞÕýPY½âÎö£¬¶ªÊ§ÎÞË«#×¢Êͺ¯ÊýµÄBug£¬Ð޸ı¨¸æÄÚÈÝ£¬´úÂëÈ«²¿ÏÔʾ£¬ÐǺŴú±íΪִÐÐ # @change: "2010-07-14 13:55" zfl Ð޸ı¨¸æÄÚÈÝ,·Ö½çÃæÏÔʾºÍдÈëÎļþ£»¼°ÐÐºÅµÄ¶ÔÆëÏÔʾ # @change: "2010-07-20 14:25" zfl ÐÞ¸ÄPYÄÚ²¿´¢´æÀàΪ¶ÀÁ¢Ä£¿é # @change: "2010-07-26 15:00" zfl мӲâÊÔ±¨¸æÔØÈ빦ÄÜ # @change: "2010-08-03 11:50" zfl мӷµ»ØPy¸²¸ÇÂʹ¦ÄÜ # @change: "2010-08-06 11:50" zfl мӷµ»Ø¿ÉÖ´ÐÐÓï¾ä×ÜÐÐÊý¹¦ÄÜ # @change: "2010-11-03 10:00" zfl мÓÉú³É×ÜÖ´ÐÐÂʱ¨¸æ # @change: "2012-02-23 15:30" Alee ¿ÕÎļþ±¨´í·À·¶£¬¾ßÌåÔ­Òòδ²é # # Ä£¿éÏêϸ˵Ã÷:´úÂëÖ´ÐÐÂÊ×·×ÙÄ£¿é # #------------------------------------------------------------------------------- """Version = 2012-02-23 15:30""" #------------------------------------------------------------------------------- #µ¼Èë import os import time import traceback import PyTrackObj import ReportAnalyzer #------------------------------------------------------------------------------- #È«¾Ö±äÁ¿ FORM_NAME = "PythonTrack" g_pyObjDic = {} # py¶ÔÏó×Öµä #IGNORE_FUNC_LIST = eval(GameWorld.GetGui().GetIniData("PythonTrack",'IgnoreFunc')) #ºöÂÔº¯ÊýÁбí IGNORE_FUNC_LIST = [] SCRIPT_PATH = os.getcwd() + '\\' + 'Script' # Script·¾¶ REPORT_PATH = os.getcwd() + '\\' + 'TestReport' # TestReport·¾¶ #--µ÷ÊÔº¯Êý---------------------------------------------------------------------- NOW_TIME = 'log%s%s%s%s%s%s.txt'%tuple(['%02d'%time.localtime()[i] for i in range(6)]) MD5_KEY = "renshk" ## дlogº¯Êý # @param *varlist ²»¶¨²Î # @return ÎÞ·µ»ØÖµ # @remarks ½«´«ÈëµÄlogÐÅϢдÈëÖ¸¶¨logÎļþ def LogEx(*varlist): info='[%s%s%s%s%s%s]'%tuple(['%02d'%time.localtime()[i] for i in range(6)]) for i in range(1,len(varlist)): curValue = varlist[i] info+="( "+str(type(curValue))+":"+str(curValue)+" )," logfile = open("log\\" + NOW_TIME, 'a') logfile.write('\t'*int(varlist[0])+info+'\n') logfile.close() LogEx(0, "SCRIPT_PATH=%s"%SCRIPT_PATH) ## ¼Ç¼ִÐÐÇé¿ö # @param pyName£º±»Ö´ÐеÄPyÃû£¬º¯ÊýÃû£¬µÚ¼¸ÐÐ # @return ÎÞ # @remarks £º¼Ç¼ִÐÐÇé¿ö def DoTrack(pyName, funcName, rowIndex, returnValue): # LogEx(0, 'DoTrack() pyName=%s, funcName=%s, rowIndex=%d, returnValue=%s'%(pyName, funcName, rowIndex, returnValue)) global g_pyObjDic try: # δ´´½¨¸Ãpy¶ÔÏó if not g_pyObjDic.has_key(pyName): # print pyName g_pyObjDic[pyName] = PyTrackObj.GetPyObj(pyName, MD5_KEY, SCRIPT_PATH)# ´´½¨py¶ÔÏó # ¸üк¯Êý¶ÔÏó״̬ g_pyObjDic[pyName].UpdateFuncState(funcName, int(rowIndex), returnValue) # LogEx(0, "g_pyObjDic.keys()=%s"%g_pyObjDic.keys()) except: LogEx(1, "Error--%s"%traceback.format_exc()) ## ¼ÆËãÖ¸¶¨Ä¿Â¼ÏÂPYÎļþµÄÖ´ÐÐÇé¿ö£¬²¢·µ»Ø½á¹û # @param path£ºÖ¸¶¨Ä¿Â¼ # @param pathCoverageList£º±£´æÖ¸¶¨Ä¿Â¼µÄÖ´ÐÐÇé¿ö # @return ·µ»ØÖ¸¶¨Ä¿Â¼ÏÂPYÎļþµÄµÄÖ´ÐÐÇé¿ö(ÒÑÖ´ÐÐÐÐÊý£¬×ÜÐÐÊý) # @remarks º¯ÊýÏêϸ˵Ã÷£º¼ÆËãÖ¸¶¨Ä¿Â¼ÏÂPYÎļþµÄµÄÖ´ÐÐÇé¿ö£¬²¢·µ»Ø½á¹û def CalcPathCoverage(path, pathCoverageList=None): global g_pyObjDic execRowCount = 0 totalRowCount = 0 # LogEx(0, path) for dir in os.listdir(path): curPath = path + "\\" + dir # ÊÇÎļþ if os.path.isfile(curPath) and (dir.endswith(".py") or dir.endswith(".PY")): # δ´´½¨¸Ãpy¶ÔÏó if not g_pyObjDic.has_key(dir): # ´´½¨py¶ÔÏó g_pyObjDic[dir] = PyTrackObj.GetPyObj(dir, MD5_KEY, SCRIPT_PATH) pyObj = g_pyObjDic[dir] pyExecCount, pyTotalCount = pyObj.GetExecRowCount() execRowCount += pyExecCount totalRowCount += pyTotalCount # LogEx(1, pyObj.GetName(), pyExecCount, pyTotalCount) # ÊÇÎļþ¼Ð if os.path.isdir(curPath) and not dir.startswith("."): if pathCoverageList != None: pyExecCount, pyTotalCount = CalcPathCoverage(curPath, pathCoverageList) else: pyExecCount, pyTotalCount = CalcPathCoverage(curPath) execRowCount += pyExecCount totalRowCount += pyTotalCount if pathCoverageList != None: if totalRowCount == 0: percent = 0.0 else: percent = float(execRowCount)/totalRowCount*100 pathCoverageList.append([path, percent]) return execRowCount, totalRowCount ## ·µ»Ø²âÊÔ±¨¸æ¸²¸ÇÂÊ # @param filePath: PYÎļþÃû»òPyĿ¼·¾¶ # @return ²âÊÔ±¨¸æ¸²¸ÇÂÊ·µ»Ø # @remarks º¯ÊýÏêϸ˵Ã÷£º½«²âÊÔ±¨¸æ¸²¸ÇÂÊ·µ»Ø def GetCoverage(sPath): LogEx(0, "GetCoverage(filePath=%s)"%sPath) global g_pyObjDic if sPath.find("\\") == -1 and sPath.endswith(".py") or sPath.endswith(".PY"): fileName = sPath # δ´´½¨¸Ãpy¶ÔÏó if not g_pyObjDic.has_key(fileName): g_pyObjDic[fileName] = PyTrackObj.GetPyObj(fileName, MD5_KEY, SCRIPT_PATH) # ´´½¨py¶ÔÏó return g_pyObjDic[fileName].GetExecPercent() if not os.path.isdir(sPath): LogEx(1, sPath + " is not exist!") return 0.0 pyExecCount, pyTotalCount = CalcPathCoverage(sPath) if pyTotalCount == 0: return 0.0 return float(pyExecCount)/pyTotalCount*100 ## ·µ»Ø²âÊÔ±¨¸æ×Ü¿ÉÖ´ÐÐÐÐÊý # @param filePath: PYÎļþÃû»òPyĿ¼·¾¶ # @return ²âÊÔ±¨¸æ×Ü¿ÉÖ´ÐÐÐÐÊý·µ»Ø # @remarks º¯ÊýÏêϸ˵Ã÷£º½«²âÊÔ±¨¸æ×Ü¿ÉÖ´ÐÐÐÐÊý·µ»Ø def GetTotalLineCount(sPath): LogEx(0, "GetCoverage(filePath=%s£©"%sPath) global g_pyObjDic if sPath.find("\\") == -1 and (sPath.endswith(".py") or sPath.endswith(".PY")): fileName = sPath # δ´´½¨¸Ãpy¶ÔÏó if not g_pyObjDic.has_key(fileName): g_pyObjDic[fileName] = PyTrackObj.GetPyObj(fileName, MD5_KEY, SCRIPT_PATH) # ´´½¨py¶ÔÏó return g_pyObjDic[fileName].CalcFuncExecCount()[1] if not os.path.isdir(sPath): LogEx(1, sPath + "is not exist!") return 0 return CalcPathCoverage(sPath)[1] ## ·µ»ØÈ«²¿PYÖ´ÐÐÇé¿ö×ܱ¨¸æ # @param filePath: PYÎļþ·¾¶ # @param MD5Key: MD5ÃÜÔ¿ # @returnÈ«²¿PYÖ´ÐÐÇé¿ö×ܱ¨¸æ # @remarks º¯ÊýÏêϸ˵Ã÷£º def GetDirPercent(filePath, MD5Key): # ²âÊÔ±¨¸æ testReport = "" pathCoverageList = [] CRLF = "\r\n" # ¼ÆËã¸÷Ä£¿é£¬Ö´ÐÐÇé¿ö CalcPathCoverage(filePath, pathCoverageList) pathCoverageList.reverse() # Éú³É±¨¸æÎļþ for pathCoverage in pathCoverageList: path = pathCoverage[0].replace(SCRIPT_PATH, "")[1:] gradeCnt = path.count("\\") if gradeCnt == 0: testReport += "Script: %0.2f%%%s"%(pathCoverage[1], CRLF) else: if gradeCnt == 1: testReport += CRLF testReport += "\t"*gradeCnt + "%s: %0.2f%%%s"%(path[path.rfind("\\")+1:], pathCoverage[1], CRLF) reportMD5 = PyTrackObj.CalcStringMD5(testReport, MD5Key) testReport += '%s²âÊÔ±¨¸æMD5:[%s]%s'%(CRLF*2, reportMD5, CRLF*2) testReport += '±£´æÊ±¼ä:[%s-%s-%s %s:%s:%s]'%tuple(['%02d'%time.localtime()[i] for i in range(6)]) return testReport ## ·µ»Ø²âÊÔ±¨¸æ # @param fileName: PYÎļþÃû # @param funcName: º¯ÊýÃû # @param trackMode: ×·×Ùģʽ£¬1 Îļþ¡¢2 º¯Êý # @param showMode: Êä³öģʽ£¬0 ½çÃæ¡¢1 Îļþ # @param MD5Key: MD5ÃÜÔ¿ # @return Ö´Ðб¨¸æ # @remarks º¯ÊýÏêϸ˵Ã÷£º½«ËùÓб»Ö´Ðе½µÄÎļþÄÚÈÝºÏÆðÀ´·µ»Ø def GetTestResport(fileName, funcName, trackMode, outputMode=0, MD5Key=""): LogEx(0, "GetTestResport(fileName=%s, funcName=%s, trackMode=%d, outputMode=%d)"%(fileName, funcName, trackMode, outputMode)) global g_pyObjDic if os.path.isdir(fileName): # ·µ»ØÈ«²¿PYÖ´ÐÐÇé¿ö×ܱ¨¸æ return GetDirPercent(fileName, MD5Key) # δ´´½¨¸Ãpy¶ÔÏó if not g_pyObjDic.has_key(fileName): g_pyObjDic[fileName] = PyTrackObj.GetPyObj(fileName, MD5_KEY, SCRIPT_PATH) # ´´½¨py¶ÔÏó pyFileObj = g_pyObjDic[fileName] testReport = pyFileObj.GetTestReport(funcName, trackMode, outputMode) return testReport ## ·µ»ØÔØÈë²âÊÔ±¨¸æ # @param fileName: ±¨¸æÎļþÃû # @param MD5Key: MD5ÃÜÔ¿ # @return ·µ»ØÖµ # @remarks º¯ÊýÏêϸ˵Ã÷£ºÔØÈë²âÊÔ±¨¸æ def SetTestResport(fileName, MD5Key=""): LogEx(0, "SetTestResport(fileName=%s)"%(fileName)) global g_pyObjDic # pyÃû¶ÔÓ¦µÄÎļþ²»´æÔÚ if not os.path.isfile(fileName): LogEx(1, "SetTestResport fileName=%s is not exist"%fileName) return 0 # ¶ÁÈ¡Îļþ infile = open(fileName,'r') contentList = infile.readlines() infile.close() if len(contentList) == 0: LogEx(1, "error: fileName=%s empty report!"%fileName) return 0 # »ñµÃpy¶ÔÏó tempPyObj = ReportAnalyzer.ReportAnalyzer(fileName, contentList, MD5Key) # ÔØÈëʧ°Ü if tempPyObj == None: LogEx(1, "SetTestResport fileName=%s Load Error"%fileName) return 0 pyName = tempPyObj.GetName() # LogEx(1, "SetTestResport pyName=%s fileName=%s Load OK == %s"%(pyName, fileName, tempPyObj.GetTestReport("", 1, 1))) # ¸²¸ÇÔ­ÏȵÄPyObj if not g_pyObjDic.has_key(pyName): g_pyObjDic[pyName] = PyTrackObj.GetPyObj(pyName, MD5_KEY, SCRIPT_PATH) # ´´½¨py¶ÔÏó g_pyObjDic[pyName].AddPyObj(tempPyObj) # LogEx(1, "SetTestResport pyName=%s fileName=%s Load OK == %s"%(pyName, fileName, g_pyObjDic[pyName].GetTestReport("", 1, 1))) # ÔØÈë³É¹¦ return 1 ## Çå²âÊÔ±¨¸æ # @param ²ÎÊý # @return ·µ»ØÖµ # @remarks º¯ÊýÏêϸ˵Ã÷£ºÈ«¾Ö±äÁ¿±»Ö´Ðе½µÄpy×ÖµäÇå¿Õ def Clear(): LogEx(0, "Clear()") global g_pyObjDic #Çå¿Õ×Öµä g_pyObjDic = {} ##¸üÐÂÓû§×·×Ùº¯ÊýÁбí # @param funcName: º¯ÊýÃû # @param type: ÊÇ·ñ×·×Ù # @return ·µ»ØÖµ # @remarks ¸üÐÂÓû§×·×Ùº¯ÊýÁбí def UpDateTrackFuncList(fileName, funcName, type): LogEx(0, "UpDateTrackFuncList(fileName=%s, funcName=%s, type=%d)"%(fileName, funcName, type)) global g_pyObjDic # ÊÇ·ñ×·×Ù isTracking = bool(type) # δ´´½¨¸Ãpy¶ÔÏó if not g_pyObjDic.has_key(fileName): g_pyObjDic[fileName] = PyTrackObj.GetPyObj(fileName, MD5_KEY, SCRIPT_PATH) # ´´½¨py¶ÔÏó pyObj = g_pyObjDic[fileName] if isTracking == True: pyObj.SetTrack(isTracking) if funcName: pyObj.FindFuncObj(funcName).SetTrack(isTracking) else: pyObj.SetAllFuncTrack(isTracking) ## ÖØÖÃ×·×Ùº¯ÊýÁбí # @param ²ÎÊý # @return ·µ»ØÖµ # @remarks ÖØÖÃ×·×Ùº¯ÊýÁбí def ResetTrackFuncList(fileName): LogEx(0, "ResetTrackFuncList(fileName=%s)"%fileName) global g_pyObjDic # δ´´½¨¸Ãpy¶ÔÏó if not g_pyObjDic.has_key(fileName): # LogEx(1, "ResetTrackFuncList: No File=%s"%fileName) return pyObj = g_pyObjDic[fileName] pyObj.SetTrack(False) # ±éÀúfuncObj for funcObj in pyObj.GetFuncObjList(): funcObj.SetTrack(False) #-------------------------------------------------------------------------------