千家信息网

Monkey自动化测试工具

发表于:2024-11-23 作者:千家信息网编辑
千家信息网最后更新 2024年11月23日,概述Monkey是Android中的一个命令行工具,可以运行在模拟器里或实际设备中。它向系统发送伪随机的用户事件流(如按键输入、触摸屏输入、手势输入等),实现对正在开发的应用程序进行压力测试。Monk
千家信息网最后更新 2024年11月23日Monkey自动化测试工具

概述

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


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

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

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

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

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

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



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

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

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



查看log,生成Monkey log

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

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




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()


0