wxPython制作跑monkey工具(python3)


一. wxPython制作跑monkey工具python文件源代码内容Run Monkey.py如下:

#!/usr/bin/env python

import wx
import os
import sys
import time

from threading import Thread


#执行adb命令函数
#使用到的线程:RunMonkeyThread(),KillMonkeyThread(),ExportLogThread()
def excuOrder(orderName):
    c = os.system(orderName)
    print(c)
    return c

#将指定内容写入指定文件(写入monkey日志报错信息)
#使用到的函数:findException()
def writeFile(FileName, content):
    FName = open(FileName, 'a')
    FName.write(content)
    FName.close()

#查找指定文件里指定字符串的个数,并输出字符串所在行的内容
#使用到的线程:ExportLogThread()
def findException(tfile,sstr):
    try:
        lines=open(tfile,'r').readlines()
        flen=len(lines)-1
        acount = 0
        fileException = "%s_%s" % (tfile,sstr)
        tfileException = "%s.txt" % fileException
        
        writeFile(tfileException,"%s keywords:\n" % fileException)
        for i in range(flen):
            if sstr in lines[i]:
                lineException = '\t%s\n'% lines[i]

                writeFile(tfileException,lineException)
                acount+= 1

        writeFile(tfileException,"%s  frequency:%s" % (fileException,acount))
        print('Please check Exception keywords in the "%s"\n' % tfileException)
    except Exception as e:
        print(e)



class RunMonkeyThread(Thread):


    def __init__(self):
        #线程实例化是立即启动
        Thread.__init__(self)
        self.logNameST = logNameST
        self.start()
        
    def run(self):
        print("Start running monkey ...\n")
        self.packageName=packageText.GetValue()
        self.MonkeyTime=MTText.GetValue()
        self.MonkeyCount=MCText.GetValue()
        self.strTime = time.strftime('%Y%m%d%H%M%S',time.localtime(time.time()))
        self.logName = '%s_%s_monkey.log'%(self.packageName,self.strTime)
        open(r"logname.txt",'w').write(self.logName)
        self.logNameST.SetLabel("%s" % self.logName)
        
        self.orderName1='adb shell "monkey -p %s --throttle %s --ignore-crashes --monitor-native-crashes \
                             --ignore-security-exceptions --ignore-timeouts --ignore-native-crashes --pct-syskeys\
                             0 --pct-nav 20 --pct-majornav 20 --pct-touch 40 --pct-appswitch 10 -v -v -v %s\
                             > /sdcard/%s&" '% (self.packageName,self.MonkeyTime,self.MonkeyCount,self.logName)
        excuOrder(self.orderName1)
        
        print("monkey finished.\n")
        

class KillMonkeyThread(Thread):

    
    def __init__(self):
        #线程实例化时立即启动
        Thread.__init__(self)
        self.start()
        
    def run(self):
        #杀死进程的两种命令
        #1. ps|grep monkey |awk '{print $2}' |xargs kill -9
        #2. PID=`ps |grep monkey|awk '{print $2}'`;kill -9 $PID;
        self.orderName2 = 'adb shell "ps|grep monkey |awk \'{print $2}\' |xargs kill -9"'
        excuOrder(self.orderName2)
        time.sleep(2)
        print ("Kill monkey success!")

            

class ExportLogThread(Thread):

    
    def __init__(self):
        #线程实例化时立即启动
        Thread.__init__(self)
        self.start()
        
    def run(self):
        self.logo = os.path.isfile('logname.txt')
        self.LogNameList = []
        if(self.logo):
            self.Logname_file = open('logname.txt','r')
            self.Lognames = self.Logname_file.readlines()
            self.Logname_file.close()
            for self.Logname in self.Lognames:
                self.LogNameList = self.Logname.split("_")
                self.LogFileName = self.LogNameList[0] + "_" + self.LogNameList[1]
                
                self.orderName4 = "adb pull /sdcard/%s ./MonkeyLog_%s/%s" % (self.Logname,self.LogFileName,self.Logname)
                excuOrder(self.orderName4)

                time.sleep(5)
                print (u"Pull %s success!" % self.Logname)
                findException("./MonkeyLog_%s/%s" % (self.LogFileName,self.Logname) ,"CRASH" )
                findException("./MonkeyLog_%s/%s" % (self.LogFileName,self.Logname) ,"Exception")
                
                self.orderName5 = "adb pull /data/anr/traces.txt ./MonkeyLog_%s/traces.txt" % self.LogFileName
                excuOrder(self.orderName5)
                
            print("Export Log Complete.")
        else:
            print ("logname.txt is not exist!")


        
class InsertFrame(wx.Frame):


    def __init__(self,parent,id):
        wx.Frame.__init__(self,parent,id,title="Run monkey",
                          pos=wx.DefaultPosition,
    size=wx.DefaultSize,style=wx.DEFAULT_FRAME_STYLE,
                            name="frame")
        

        panel = wx.Panel(self,-1)   #创建画板

        #应用包名
        PackageLabel = wx.StaticText(panel, -1, "package name:")
        global packageText
        packageText = wx.TextCtrl(panel, -1, "",
                                size=(260,-1))
        packageText.SetInsertionPoint(0)

        #monkey事件之间的间隔时间(ms)
        MTLabel = wx.StaticText(panel, -1, "Monkey time:")
        global MTText
        MTText = wx.TextCtrl(panel, -1, "",
                                size=(260,-1))

        #monkey事件总次数
        MCLabel = wx.StaticText(panel, -1, "Monkey count:")
        global MCText
        MCText = wx.TextCtrl(panel, -1, "",
                                size=(260,-1))


        global button1
        #点击按钮运行monkey
        button1 = wx.Button(panel,label="Run Monkey")   #将按钮添加到画板

        #杀死monkey
        button2 = wx.Button(panel,label="Kill Monkey")   #将按钮添加到画板

        #导出日志
        button3 = wx.Button(panel,label="Export Log")   #将按钮添加到画板

        #日志名字:
        MonkeyLogName = wx.StaticText(panel, -1, "Monkey logName:")
        global logNameST
        logNameST = wx.TextCtrl(panel,-1,"",
                                size=(260,-1))
        
        #绑定按钮的单击事件
        self.Bind(wx.EVT_BUTTON, self.runMonkey, button1)
        self.Bind(wx.EVT_BUTTON, self.killMonkey, button2)
        self.Bind(wx.EVT_BUTTON, self.exportLog, button3)
        #绑定窗口的关闭事件
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)

        
        sizer = wx.FlexGridSizer(cols=2, hgap=6, vgap=6)
        sizer.AddMany([PackageLabel,packageText,MTLabel,MTText,MCLabel,MCText,MonkeyLogName,logNameST,button1,button2,button3])
        panel.SetSizer(sizer)


    def runMonkey(self, event):
        RunMonkeyThread()

    def killMonkey(self,event):
        KillMonkeyThread()

    def exportLog(self,event):
        ExportLogThread()

    def OnCloseMe(self, event):
        self.Close(True)
    
    def OnCloseWindow(self,event):
        self.Destroy()


class App(wx.App):


    def __init__(self,redirect=True, filename=None):
        wx.App.__init__(self,redirect,filename)


    def OnInit(self):
        print("Program Startup:")
        self.frame = InsertFrame(parent=None,id=-1)   #创建框架
        self.frame.Show()
        self.SetTopWindow(self.frame)
        print(sys.stderr)   #输出到stderr
        return True


    def OnExit(self):
        print("Program running complete.")
        return True

        

if __name__=="__main__":
    app = App(redirect=True)   #1.文本重定向从这开始
    app.MainLoop()
    

二. 将py脚本文件打包成可执行的exe文件命令:

pyinstaller -F -w -i 1.ico --version-file file_version_info.txt "Run Monkey.py"

ico图片生成:

将一般格式的图片(例如png、jpg)转换为ico图片网址:https://www.converticon.com/

版本信息文件内容file_version_info.txt如下:

# UTF-8
#
# For more details about fixed file info 'ffi' see:
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
VSVersionInfo(
  ffi=FixedFileInfo(
    # filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
    # Set not needed items to zero 0.
    filevers=(2, 0, 0, 0),
    prodvers=(2, 0, 0, 0),
    # Contains a bitmask that specifies the valid bits 'flags'r
    mask=0x0,
    # Contains a bitmask that specifies the Boolean attributes of the file.
    flags=0x0,
    # The operating system for which this file was designed.
    # 0x4 - NT and there is no need to change it.
    OS=0x4,
    # The general type of file.
    # 0x1 - the file is an application.
    fileType=0x1,
    # The function of the file.
    # 0x0 - the function is not defined for this fileType
    subtype=0x0,
    # Creation date and time stamp.
    date=(0, 0)
    ),
  kids=[
    StringFileInfo(
      [
      StringTable(
        u'080403a8',
        [StringStruct(u'Comments', u'RunMonkey v2.0'),
        StringStruct(u'CompanyName', u''),
        StringStruct(u'FileDescription', u'RunMonkey Application'),
        StringStruct(u'FileVersion', u'2.0.0.0'),
        StringStruct(u'LegalCopyright', u''),
        StringStruct(u'ProductName', u'RunMonkey'),
        StringStruct(u'ProductVersion', u'2.0.0.0'),
        StringStruct(u'SpecialBuild', u'000000')])
      ]), 
    VarFileInfo([VarStruct(u'Translation', [2052, 936])])
  ]
)

pyinstaller打包工具安装命令:pip install pyinstaller

pyinstaller打包工具安装完成后,查看安装版本号命令:pyinstaller --version

安装wxpython命令:pip install wxPython