Monkey自动化测试工具

概述

MonkeyAndroid中的一个命令行工具,可以运行在模拟器里或实际设备中。它向系统发送伪随机的用户事件流(如按键输入、触摸屏输入、手势输入等),实现对正在开发的应用程序进行压力测试Monkey测试是一种为了测试软件的稳定性、健壮性的快速有效的方法。Monkey自动化测试工具是可视化操作的便利方式工具,提高使用性和效率。


设置monkey种子数,延迟,执行次数

-s <seed> 种子数作用:伪随机数生成器的seed值。如果用相同的seed值再次运行monkey,将生成相同的事件序列。

--throttle <milliseconds>延迟作用:在事件之间插入固定的时间(毫秒)延迟,你可以使用这个设置来减缓Monkey的运行速度,如果你不指定这个参数,则事件之间将没有延迟,事件将以最快的速度生成。

-v 日志输出等级作用:命令行上的每一个-v都将增加反馈信息的详细级别。
简单(默认),除了启动、测试完成和最终结果外只提供较少的信息。
中等,提供了较为详细的测试信息,如逐个发送到Activity的事件信息。
复杂,提供了更多的设置信息,如测试中选中或未选中的Activity信息。

--ignore-crashes作用:通常,应用发生崩溃或异常时Monkey会停止运行。如果设置此项,Monkey将继续发送事件给系统,直到事件计数完成。

--ignore-security-exception 作用:通常,当程序发生许可错误(例如启动一些需要许可的Activity)导致的异常时,Monkey将停止运行。设置此项,Monkey将继续发送事件给系统,直到事件计数完成。


image.png


读取程序包,选择需要测试的包名

-p <allowed-package-name> 程序包作用:如果你指定一个或多个包,Monkey将只允许访问这些包中的Activity。如果你的应用程序需要访问这些包(如选择联系人)以外的Activity,你需要指定这些包。如果你不指定任何包,Monkey将允许系统启动所有包的Activity。指定多个包,使用多个-p,一个-p后面接一个包名。

点击读取程序包通过读取data/data目录下获取所有的程序包名称,首先需要将手机连接到PC,测试连接是否正常,可在cmd里输入adb devices来进行验证;因测试多针对一个特定的APP包,所以需要知道需要测试包的包名;也可以通过 adb shell pm list packages  列出所有包名来进行查找通过全部选择快速选取所有的应用包,通过全部取消取消已选项。


image.png


查看log,生成Monkey log

Monkey开始,通过adb连接手机,并运行logcat,生成logcat到指定目录。

一键monkey可以自动生成默认参数,直接开始monkey测试。


image.png



Monkey的可视化界面是通过python 内置的wx模块来实现,可以快速构建UI界面。

软件主界面的控件排布代码:

1.      MyFrame是整个窗体的主入口,通过实例化wx.Frame来显示窗口

class MyFrame(wx.Frame):

    //设置默认delay时间值

delayDefault = "2"

//设置默认种子数

seedDefault = "5000000"

//设置默认执行次数

    executionFrequencyDefault = "60000000"

logDir = "./"

def __init__(self):

    //执行方式定义

        excuteMode = ["忽略程序崩溃",

                    "忽略程序无响应",

                    "忽略安全异常",

                    "出错中断程序",

                    "本地代码导致的崩溃",

                    "默认"

                    ]

        //日志输出等级区分

        logMode = ["简单","普通","详细"]

        executionModeDefault = excuteMode[0]

        //初始化菜单按钮

        menuBar = wx.MenuBar()

        menu1 = wx.Menu("")

        menuBar.Append(menu1, "File")

        self.SetMenuBar(menuBar)

        //初始化标签栏

        wx.StaticText(panel, -1, "种子数:", pos=(xPos, yPos))

        self.seedCtrl = wx.TextCtrl(panel, -1, "", pos=(xPos1, yPos))

        //绑定点击事件

        self.seedCtrl.Bind(wx.EVT_KILL_FOCUS, self.OnAction)

        self.seedCtrl.SetFocus()

        //初始化标签栏

        wx.StaticText(panel, -1, "执行次数:", pos=(xPos, yPos+yDelta))

        //设置窗口位置

        self.excuteNumCtrl = wx.TextCtrl(panel, -1, "", pos=(xPos1, yPos+yDelta))

        //初始化标签栏

        wx.StaticText(panel, -1, "延时:", pos=(xPos, yPos+2*yDelta))

        self.delayNumCtrl = wx.TextCtrl(panel, -1, "", pos=(xPos1, yPos+2*yDelta))

        //初始化标签栏       

        wx.StaticText(panel, -1, "执行方式:", pos=(xPos, yPos+3*yDelta))

        //设置窗口位置

        self.excuteModeCtrl = wx.ComboBox(panel, -1, "", (xPos1,yPos+3*yDelta), choices=excuteMode,style=wx.CB_DROPDOWN)

       

//设置初始化checklistbox,下拉菜单

        self.checkListBox = wx.CheckListBox(panel, -1, (xPos, yPos+4*yDelta ), (400, 350), [])

        wx.StaticText(panel, -1, "日志输出等级:", pos=(xPos, yPoslayout-yDelta))

        self.logModeCtrl = wx.ComboBox(panel, -1, "", (xPos1,yPoslayout-yDelta), choices=logMode,style=wx.CB_DROPDOWN)

        //初始化按钮,读取程序包按钮绑定readButton事件

        self.readButton = wx.Button(panel, -1, "读取程序包", pos=(xPos, yPoslayout))

        self.Bind(wx.EVT_BUTTON, self.OnReadClick, self.readButton)

        self.readButton.SetDefault()


        //初始化默认参数按钮,绑定defaultButton事件

        self.defaultButton = wx.Button(panel, -1, "默认参数", pos=(xPos, yPoslayout+yDelta))

        self.Bind(wx.EVT_BUTTON, self.OnResetClick, self.defaultButton)

        self.defaultButton.SetDefault()

        //初始化一键monkey按钮,按钮绑定quick事件

        self.quickButton = wx.Button(panel, -1, "一键Monkey", pos=(xPos+120, yPoslayout+yDelta))

        self.Bind(wx.EVT_BUTTON, self.OnQuickStartClick, self.quickButton)

        self.quickButton.SetDefault()

2.      生成log代码:

    //生成log函数

    def OnBuildLog(self,event):

        os.chdir(self.logDir)  

        //通过日期创建唯一标识文件名称

        date = time.strftime('%Y-%m-%d-%H-%M',time.localtime(time.time()))

        dir_m = "Monkey_Log_"+date.replace("-","")

        dir0 = "sdcard0_log"

        创建目标文件目录

        if (os.path.exists(dir_m+"/"+dir0)):

            print "already exists"

        else:

            os.system("mkdir -p "+dir_m+"/"+dir0)

        os.chdir(dir_m)

        //通过adb命令导出log文件到目标文件夹中

        os.system("adb pull /storage/sdcard0/log/ "+dir0)

        //查找异常log文件

        self.BuildFatalLog(os.getcwd())

    //遍历所有的log文件函数

def ListFiles(self,path):

    //遍历文件件

        for root,dirs,files in os.walk(path):

            log_f = ""

            for f in files:

                if(f.find("main") == 0):

                    log_f = f.strip()

                    //切换到目标目录

                    os.chdir(root)

                    //通过grep 命令查找所有的异常文件

                    if (log_f != ""):

            grep_cmd="grep-Eni-B2-A20'FATAL|error|exception|system.err|androidruntime' "+log_f+" > "+log_f+"_fatal.log"

                        os.system(grep_cmd)

    //查找异常文件函数

    def BuildFatalLog(self,path):

        self.ListFiles(path)

3.      读取程序包代码分析:

//读取程序包函数声明

def OnReadClick(self, event):

    //清空控件内容

        self.checkListBox.Clear()

        //通过读取手机data/data目录来确认所有的包名

        os.system("adb shell ls data/data > ~/log.log")

        //解析log.log文件

        home = os.path.expanduser('~')

        f = open(home+"/log.log", 'r')

        line = f.readline()

        while line:

            line = f.readline()

            if (line != ""):

                print "===="+line

                //将解析的包名,添加包名checkbox中显示

                self.checkListBox.Append(line)

        f.close()


猜你喜欢

转载自blog.51cto.com/14367728/2402552