Android自动化测试——Monkey与MonkeyRunner

Android自动化测试——Monkey与MonkeyRunner


一、自动化测试概述通常,在设计了测试用例并通过评审之后,由测试人员根据测试用例中描述的规程步步执行测试,得到实际结果与期望结果的比较。在此过程中,为了节省人力、时间或硬件资源,提高测试效率,便引入了自动化测试的概念。自动化测试就是把以人为驱动的测试行为转化为机器执行的一种过程。在Android测试中常用的测试包括:Monkey和MonkeyRunner以及robotium,本文中主要介绍下Monkey和MonkeyRunner自动化测试。

二、Monkey测试与MonkeyRunner测试比较

2.1、MonkeyMonkey是一个命令行工具,可以运行在模拟器里或实际设备中,它是一种轻量级的性能测试工具。它向系统发送伪随机的事件流,实现对正在运行的应用程序进行压力测试。

Monkey包括许多选项,它们大致分为四类:1)基本配置选项,如设置尝试的事件数量。2)运行约束选项,如设置只对单独的一个包进行测试3)事件类型和频率4)调试选项在Monkey运行的时候,它生成事件,并把它们发给系统。

同时,Monkey还对测试中的系统进行监测,对下列三种情况进行特殊处理: 

 1)如果限定了Monkey运行在一个或几个特定的包上,那么它会监测试图转到其它包的操作,并对其进行阻止。

2) 如果应用程序崩溃或接收到任何失控异常,Monkey将停止并报错。

3) 如果应用程序产生了应用程序不响应(application not responding)的错误,Monkey将会停止并报错。按照选定的不同级别的反馈信息,在Monkey中还可以看到其执行过程报告和生成的事件。

2.2、MonkeyRunnerMonkeyRunner工具提供了一个API,使用此API写出的程序可以在Android代码之外控制Android设备和模拟器

通过MonkeyRunner,您可以写出一个Python程序去安装一个Android应用程序或测试包,运行它,向它发送模拟击键,截取它的用户界面图片,并将截图存储于工作站上。MonkeyRunner工具的主要设计目的是用于测试功能/框架水平上的应用程序和设备,或用于运行单元测试套件,但您当然也可以将其用于其它目的。

MonkeyRunner能够实现的功能包括:1)多设备控制:monkeyrunner API可以跨多个设备或模拟器实施测试套件。您可以在同一时间接上所有的设备或一次启动全部模拟器(或统统一起),依据程序依次连接到每一个,然后运行一个或多个测试。您也可以用程序启动一个配置好的模拟器,运行一个或多个测试,然后关闭模拟器。

2)功能测试: monkeyrunner可以为一个应用自动贯彻一次功能测试。您提供按键或触摸事件的输入数值,然后观察输出结果的截屏。

3)回归测试:monkeyrunner可以运行某个应用,并将其结果截屏与既定已知正确的结果截屏相比较,以此测试应用的稳定性。

4)可扩展的自动化:由于monkeyrunner是一个API工具包,您可以基于Python模块和程序开发一整套系统,以此来控制Android设备。除了使用monkeyrunner API之外,您还可以使用标准的Python os和subprocess模块来调用Android Debug Bridge这样的Android工具。

2.3、Monkey与MonkeyRunner的区别Monkey:

Monkey工具直接运行在设备或模拟器的adb shell中,生成用户或系统的伪随机事件流。

MonkeyRunner:MonkeyRunner工具则是在工作站上通过API定义的特定命令和事件控制设备或模拟器。

三、测试环境的搭建见:http://wenku.baidu.com/view/6f8d631e227916888486d75e.html或者http://blog.sina.com.cn/s/blog_a289fd65010155w5.html

四、Monkey与MonkeyRunner测试工具启动

4.1、Monkey的启动可以通过开发机器上的命令行或脚本来启动Monkey。由于Monkey运行在模拟器/设备环境中,所以必须用其环境中的shell来进行启动。可以通过在每条命令前加上adb shell来达到目的,也可以进入Shell后直接输入Monkey命令。基本语法如下: $ adb shell monkey [options]如果不指定options,Monkey将以无反馈模式启动,并把事件任意发送到安装在目标环境中的全部包。下面是一个更为典型的命令行示例,它启动指定的应用程序,并向其发送500个伪随机事件:$ adb shell monkey -p your.package.name -v 500启动Monkey步骤:启动CMD→输入adb shell所在位置(例如下:E:\Program Files (x86)\Android\android-sdk-windows\platform-tools)→键入adb shell如下图1所示,则启动成功。Android自动化测试图1 启动adb工具 启动后就可以输入Monkey命令,使其自动产生随机系列测试应用程序。(注:命令可以直接输入,也可以通过编写脚运行,脚本文档可以是.text)

4.2MonkeyRunner工具的启动 MonkeyRunner自动化测试工具比Monkey测试更具有人的意志,目的性更加明确。启动MonkeyRunner方法如下:CMD→键入MonkeyRunner位置→输入MonkeyRunner,如图2所示:Android自动化测试图2 启动MonkeyRunner(注:运行MonkeyRunner时可以在以上状态下输入指令,也可以通过monkeyrunner命令运行Python脚本,其后缀为.py)

五、Monkey与MonkeyRunner命令介绍5.1Monkey命令介绍下表中列出了Monkey命令行可用的全部选项。类别 选项 说明 常规

 1、--help 列出简单的用法。 

2、-v 命令行的每一个-v将增加反馈信息的级别。Level 0(缺省值)除启动提示、测试完成和最终结果之外,提供较少信息。Level 1提供较为详细的测试信息,如逐个发送到Activity的事件。Level 2提供更加详细的设置信息,如测试中被选中的或未被选中的Activity。 事件

3、 -s 伪随机数生成器的seed值。如果用相同的seed值再次运行Monkey,它将生成相同的事件序列。 

4、--throttle 在事件之间插入固定延迟。通过这个选项可以减缓Monkey的执行速度。如果不指定该选项,Monkey将不会被延迟,事件将尽可能快地被产成。 

5、--pct-touch 调整触摸事件的百分比(触摸事件是一个down-up事件,它发生在屏幕上的某单一位置)。 

6、--pct-motion 调整动作事件的百分比(动作事件由屏幕上某处的一个down事件、一系列的伪随机事件和一个up事件组成)。

 7、--pct-trackball 调整轨迹事件的百分比(轨迹事件由一个或几个随机的移动组成,有时还伴随有点击)。 

8、--pct-nav 调整“基本”导航事件的百分比(导航事件由来自方向输入设备的up/down/left/right组成)。 

9、--pct-majornav 调整“主要”导航事件的百分比(这些导航事件通常引发图形界面中的动作,如:5-way键盘的中间按键、回退按键、菜单按键) 

10、--pct-syskeys 调整“系统”按键事件的百分比(这些按键通常被保留,由系统使用,如Home、Back、Start Call、End Call及音量控制键)。 

11、--pct-appswitch 调整启动Activity的百分比。在随机间隔里,Monkey将执行一个startActivity()调用,作为最大程度覆盖包中全部Activity的一种方法。 

12、--pct-anyevent 调整其它类型事件的百分比。它包罗了所有其它类型的事件,如:按键、其它不常用的设备按钮、等等。 约束限制 

13、-p 如果用此参数指定了一个或几个包,Monkey将只允许系统启动这些包里的Activity。如果你的应用程序还需要访问其它包里的Activity(如选择取一个联系人),那些包也需要在此同时指定。如果不指定任何包,Monkey将允许系统启动全部包里的Activity。要指定多个包,需要使用多个 -p选项,每个-p选项只能用于一个包。 

14、-c 如果用此参数指定了一个或几个类别,Monkey将只允许系统启动被这些类别中的某个类别列出的Activity。如果不指定任何类别,Monkey将选 择下列类别中列出的Activity:Intent.CATEGORY_LAUNCHER或Intent.CATEGORY_MONKEY。要指定多个类别,需要使用多个-c选项,每个-c选 项只能用于一个类别。 调试

15、 --dbg-no-events 设置此选项,Monkey将执行初始启动,进入到一个测试Activity,然后不会再进一步生成事件。为了得到最佳结果,把它与-v、一个或几个包约 束、以及一个保持Monkey运行30秒或更长时间的非零值联合起来,从而提供一个环境,可以监视应用程序所调用的包之间的转换。 

16、--hprof 设置此选项,将在Monkey事件序列之前和之后立即生成profiling报告。这将会在data/misc中生成大文件(~5Mb),所以要小心使用它。 

17、--ignore-crashes 通常,当应用程序崩溃或发生任何失控异常时,Monkey将停止运行。如果设置此选项,Monkey将继续向系统发送事件,直到计数完成。 

18、--ignore-timeouts 通常,当应用程序发生任何超时错误(如“Application Not Responding”对话框)时,Monkey将停止运行。如果设置此选项,Monkey将继续向系统发送事件,直到计数完成。 

19、--ignore-security-exceptions 通常,当应用程序发生许可错误(如启动一个需要某些许可的Activity)时,Monkey将停止运行。如果设置了此选项,Monkey将继续向系统发送事件,直到计数完成。 

20、--kill-process-after-error 通常,当Monkey由于一个错误而停止时,出错的应用程序将继续处于运行状态。当设置了此选项时,将会通知系统停止发生错误的进程。注意,正常的(成功的)结束,并没有停止启动的进程,设备只是在结束事件之后,简单地保持在最后的状态。 

21、--monitor-native-crashes 监视并报告Android系统中本地代码的崩溃事件。如果设置了--kill-process-after-error,系统将停止运行。 

22、--wait-dbg 停止执行中的Monkey,直到有调试器和它相连接5.2MonkeyRunner方法介绍MonkeyRunner帮助 

1、com.android.monkeyrunner.MonkeyRunner.alert 当前脚本的运行过程中显示警告对话框。对话框是模态,因此脚本停止,直到用户关闭对话框。 参数:消息 - 消息显示在对话框。 标题 - 对话框的标题。默认值是“提醒”。 okTitle - 使用对话框中的按钮的文本。默认值是“OK”。 返回:返回任何内容。 

2、com.android.monkeyrunner.MonkeyDevice.broadcastIntent 发送一个广播设备的意图。 参数: URI - 意图的URI。 行动 - 该行动的意图。 数据 - 数据的URI意图 的mimetype - mime类型的意图。 类别 - 迭代的意图类别名称。 演员 - 一个额外的字典添加到意图。这些额外的类型推断的值的Python类型。 组件 - 组件的意图。 标志 - 一个迭代的标志为Intent.All参数是可选的。每个参数的默认值是null。(见android.content.Context.sendBroadcast(意向)) 返回:返回任何内容。 

3、com.android.monkeyrunner.MonkeyRunner.choice 显示一个选择对话框,允许用户选择从一个单一的项目,一个项目清单。 参数: 消息 - 提示信息显示在对话框。 选择 - 一个可迭代的Python类型的选择列表显示 标题 - 对话框的标题。默认的是“输入” 返回:所选项目的抵消了Iterable基于0的数字。 

4、com.android.monkeyrunner.MonkeyImage.convertToBytes 转换成一个特定格式的MonkeyImage作为一个字符串返回结果。使用此获得rawpixels在一个特定的格式。字符串输出是有更好的表现。 参数: 格式 - 目标格式(例如,“PNG便携式网络图形格式)。默认为PNG。 返回:一个String生成的图像。 

5、com.android.monkeyrunner.MonkeyDevice.drag 模拟设备屏幕上拖动(触摸,持有和移动)。 参数: 开始 - 拖动起点(以像素为单位元组(X,Y)) 结束 - 阻力终点(以像素为单位元组(X,Y) 时间 - 在几秒钟内拖时间(默认为1.0秒) 步骤 - 插值点时要采取的步骤。 (默认是10) 返回:返回任何内容。 

6、com.android.monkeyrunner.MonkeyView.getAccessibilityIds 返回当前视图的辅助IDS 返回:视图的辅助IDS作为一个整数列表 

7、com.android.monkeyrunner.MonkeyRect.getCenter 返回一个两个项目清单,其中包含矩形的中心的x和y的值 返回:该中心作为一个整数的两个项目清单坐标 

8、com.android.monkeyrunner.MonkeyView.getChecked 获取视图的选中状态 返回:一个布尔值,该项目是否被选中或不 

9、com.android.monkeyrunner.MonkeyView.getChildren 返回当前视图的孩子们 返回:认为儿童MonkeyView对象名单 

10、com.android.monkeyrunner.MonkeyView.getEnabled 返回启用状态的看法。 返回:作为一个布尔启用状态 

11、com.android.monkeyrunner.MonkeyView.getFocused 视图返回集中状态 返回:集中的状态作为一个布尔 

12、com.android.monkeyrunner.MonkeyRect.getHeight 返回矩形的高度。 返回:作为一个整数的矩形的高度 

13、com.android.monkeyrunner.MonkeyDevice.getHierarchyViewer 获取设备HierarchyViewer对象。 返回一个HierarchyViewer对象 

14、com.android.monkeyrunner.MonkeyView.getLocation 返回视图的位置在一个MonkeyRect形式 返回:视图作为MonkeyRect对象的位置 

15、com.android.monkeyrunner.MonkeyView.getParent 返回当前视图的父 返回:视图的父作为MonkeyView对象 

16、com.android.monkeyrunner.MonkeyDevice.getProperty 由于设备上的变量的名称,返回变量的值 参数:关键 - 变量的名称。可用的名称在http://developer.android.com/guide/topics/testing/monkeyrunner.html上市。 返回:该变量的值 

17、com.android.monkeyrunner.MonkeyDevice.getPropertyList 检索,可以查询的属性 返回:返回任何内容。 

18、com.android.monkeyrunner.MonkeyImage.getRawPixel 一个单一的ARGB(alpha,红色,绿色,蓝色)像素位置的X,Y。参数X和Y是0,表示在像素尺寸。 X增加的权利,对底部的Y增加。此方法返回一个tuple。 参数: X - x偏移的像素 Y - 像素的y偏移量 返回的元组(一R,G,B)的像素。 tuple中的每个项目都有0-255范围内。 

19、com.android.monkeyrunner.MonkeyImage.getRawPixelInt 一个单一的ARGB(alpha,红色,绿色,蓝色)像素位置的X,Y。参数X和Y是0,表示在像素尺寸。 X增加的权利,对底部的Y增加。此方法返回一个整数。 参数: X - x偏移的像素 Y - 像素的y偏移量 返回:X,Y的无符号整数像素。高阶8位是A,followedby 8位为R,G和8 8为B 

20、com.android.monkeyrunner.MonkeyDevice.getRootView 获取当前根视图 返回:根视图对象 

21、com.android.monkeyrunner.MonkeyView.getSelected 返回视图的选中状态 返回:作为一个布尔选中状态 

22、com.android.monkeyrunner.MonkeyImage.getSubImage 复制图像的矩形区域。 参数: 矩形 - 一个元组(X,Y,W,H),说明该地区复制。 x和y指定上左边角落的区域。 w是该地区的像素宽度,h是它的高度。 返回:MonkeyImage对象代表复制的区域。 

23、com.android.monkeyrunner.MonkeyDevice.getSystemProperty 代名词的getProperty() 参数: 关键 - 系统变量的名称。 返回:该变量的值。 

24、com.android.monkeyrunner.MonkeyView.getText 返回视图所载文本 返回:在视图中的文本 

25、com.android.monkeyrunner.MonkeyDevice.getViewByAccessibilityIds 获得指定的无障碍标识的看法。 参数: windowId - 视图来检索窗口的ID。 无障碍标识 - 辅助视图来检索标识。 返回:具有指定ID的视图对象。 

26、com.android.monkeyrunner.MonkeyDevice.getViewById 取得具有指定id的观点。 参数: ID - ID的视图来检索。 返回:具有指定ID的视图对象。 

27、com.android.monkeyrunner.MonkeyView.getViewClass 返回视图类的名称。 返回:类名作为一个字符串的看法 

28、com.android.monkeyrunner.MonkeyDevice.getViewIdList 检索当前应用程序的视图ID 返回:返回任何内容。 

29、com.android.monkeyrunner.MonkeyDevice.getViewsByText 获得一个列表包含指定文本的意见。 参数: 文本 - 文本搜索 返回:包含指定文本的视图对象的名单。 

30、com.android.monkeyrunner.MonkeyRect.getWidth 返回矩形的宽度。 返回:作为一个整数的矩形的宽度 

31、com.android.monkeyrunner.MonkeyRunner.help 格式和API参考显示为MonkeyRunner的。 参数: 格式 - 输出所需的格式,无论是“文本”为纯文本或HTML标记的HTML“。 返回:一个字符串,其中包含所需格式的帮助文本。 

32、com.android.monkeyrunner.MonkeyRunner.input 显示一个对话框,接受输入。对话框,模态,因此脚本停止,直到用户点击两个对话框按钮之一。输入一个值,用户输入的值,并单击“确定”按钮。要退出,而无需输入一个值对话框,用户点击“取消”按钮。使用这种方法提供的参数来定制这些按钮的文本。 参数: 消息 - 提示信息显示在对话框。 初值 - 提供给用户的初始值。默认是一个空字符串) 标题 - 对话框的标题。默认的是“输入” okTitle - 文本中使用对话框的确认按钮。默认的是“OK”。文本中使用对话框的“取消”按钮。默认是“取消”。 cancelTitle - 返回:测试用户,或没有输入,如果用户取消了输入; 

33、com.android.monkeyrunner.MonkeyDevice.installPackage 设备安装到指定的Android包(。apk文件)。如果设备上已经存在的包,它会被替换。 参数: 路径 - 包的主机上的文件系统路径和文件名。 返回:如果安装成功 

34、com.android.monkeyrunner.MonkeyDevice.instrument 与仪器仪表运行指定的包,并返回它产生的输出。使用此运行测试包使用InstrumentationTestRunner。 参数: 的className - 类运行仪表。格式是软件包名/类名。使用软件包名来指定运行,Android包和类名来指定运行该包内的类。对于测试包,这是通常

35、testpackagename / InstrumentationTestRunner 参数 - 包含参数传递给这个仪器(默认值是“无”)的对象映射到一个字符串。 返回:一个字符串映射到从包中输出的对象。对于一个测试包,包含一个单一的键 - 值对:关键是'流'的值是一个字符串,其中包含测试输出。 

35、com.android.monkeyrunner.MonkeyRunner.loadImageFromFile 加载文件MonkeyImage。 参数: 路径 - 要加载的文件的路径。该文件的路径是在计算机上运行MonkeyRunner,而不是在Android设备上的路径。 返回值:一个的新MonkeyImage代表指定的文件 

36、com.android.monkeyrunner.MonkeyDevice.press 发送到指定键的一个关键事件 参数: 名称 - 键的键码按(见android.view.KeyEvent) 如由TouchPressType()返回的类型 - 触摸事件类型。为了模拟输入键,发送DOWN_AND_UP 返回:返回任何内容。 

37、com.android.monkeyrunner.MonkeyDevice.reboot 重新引导到指定的引导程序指定的设备。 参数: - 重启进入引导程序:引导程序,恢复,或没有 返回:返回任何内容。 

38、com.android.monkeyrunner.MonkeyDevice.removePackage 从设备中删除指定的软件包,包括其相关的数据和高速缓存。 参数: 包 - 包的名字删除。 返回:True如果删除成功 

39、com.android.monkeyrunner.MonkeyImage.sameAs 比较这MonkeyImage的对象aother MonkeyImage对象。 参数: 其他 - 其他MonkeyImage的对象。 % - 一个在0.0到1.0的范围内浮动,说明需要是相同的方法,返回“真”的像素的百分比。默认为1.0。 返回:布尔'真',如果两个对象包含相同的图像。 

40、com.android.monkeyrunner.MonkeyView.setFocused 设置视图的集中状态 参数: 重点 - 布尔值设置集中到 返回:返回任何内容。 

41、com.android.monkeyrunner.MonkeyView.setSelected 设置视图的选定状态 参数: 选择 - 布尔值设置选择 返回:返回任何内容。 

42、com.android.monkeyrunner.MonkeyDevice.shell 执行一个adb shell命令,并返回结果,如果有的话。 参数: CMD - adb shell命令来执行。 返回:从命令的输出。 

43、com.android.monkeyrunner.MonkeyRunner.sleep 暂停目前正在运行的程序指定的秒数。 参数: 秒 - 暂停的秒数。 返回:返回任何内容。 

44、com.android.monkeyrunner.MonkeyDevice.startActivity 开始从指定的参数构造一个Intent发送设备上的活动。 参数: URI - 意图的URI。 行动 - 该行动的意图。 数据 - 数据的URI意图 的mimetype - mime类型的意图。 类别 - 一个Python迭代包含的意图类别名称。 演员 - 一个额外的字典添加到意图。这些额外的类型推断的值的Python类型。 组件 - 组件的意图。 标志 - 一个迭代的标志为Intent.All参数是可选的。为每个参数的默认值是null。(见android.content.Intent) 返回:返回任何内容。 

45、com.android.monkeyrunner.MonkeyDevice.takeSnapshot 获取设备的屏幕缓冲区,产生了整个显示器的屏幕捕获。 返回:一个MonkeyImage对象(点阵图包装) 

46、com.android.monkeyrunner.MonkeyDevice.touch 在指定位置发送触摸事件 参数: X - X坐标,以像素为单位 Y - Y坐标,以像素为单位 类型 - 触摸事件类型TouchPressType(返回) 返回:返回任何内容。 

47、com.android.monkeyrunner.MonkeyDevice.type 键盘上的类型指定的字符串。这相当于要求每个字符串中的字符按(键码,DOWN_AND_UP)。 参数: 消息 - 字符串发送到键盘。 返回:返回任何内容。 

48、com.android.monkeyrunner.MonkeyRunner.waitForConnection 等待工作站连接到设备。 参数: 超时 - 在几秒钟等待超时。默认是无限期地等待。 的deviceid - 一个正则表达式指定的设备名称。看到开发指南,了解有关设备名称为“亚行”的文件。 返回:一个ChimpDevice对象代表连接的设备。 

49、com.android.monkeyrunner.MonkeyDevice.wake 在设备屏幕上唤醒 返回:返回任何内容。 

 50、com.android.monkeyrunner.MonkeyImage.writeToFile 写文件MonkeyImage。如果没有指定格式,这种方法猜测输出格式的基础上提供的文件扩展名的扩展。如果是无法猜测的格式,它使用的PNG。 参数: 路径 - 输出文件名,也可以包括其路径 格式 - 目标格式(例如,“PNG便携式网络图形格式。 返回:Boolean如果写成功。

六、MonkeyRunner测试程序的编写示例 MonkeyRunner程序是用Python语言写的,但是由于在此主要目的在于介绍自动化测试,所以不专门介绍Python语言,大家可以通过专门的Python教程进行学习。(辅导教程可用:《Python基础教程(第2版)》或者《Python3程序开发指南(第二版)》)。

6.1MonkeyRunner坐标记录程序的编写 常用的坐标测试程序一般都相同,只要做简单修改就可使用,示例如下:

#This Python file uses the following 

encoding: utf-8#!/usr/bin/env monkeyrunner

# Copyright 2010, The Android Open Source Project#

# Licensed under the Apache License, Version 2.0 (the "License");

# you may not use this file except in compliance with the License.# You may obtain a copy of the License at#

# http://www.apache.org/licenses/LICENSE-2.0#

# Unless required by applicable law or agreed to in writing, software

# distributed under the License is distributed on an "AS IS" BASIS,

# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

# See the License for the specific language governing permissions and

# limitations under the License. from com.android.monkeyrunner import MonkeyRunner as mrfrom com.android.monkeyrunner.recorder import MonkeyRecorder as recorder 

#连接设备device = mr.waitForConnection() mr.sleep(10) 

#安装应用程序#device.installPackage("安装包路径+名字") 

#启动Android应用程序#device.startActivity(component="程序启动的首个Activity名") 

#启动录制程序recorder.start(device)6.2MonnkeyRunner测试程序的编写 运用5.2中提供的命令,就可以编写应用程序,示例程序如下:

# 导入此程序所需的monkeyrunner模块from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice, MonkeyImage

# 连接当前设备,返回一个MonkeyDevice对象device= MonkeyRunner.waitForConnection()

# 安装Android 包,注意,此方法返回的返回值为boolean ,由此您可以判#断安装过程是否正常device.installPackage ('安装路径')

# 运行此应用中的一个活动device.startActivity (component='com.example.android.myapplication.MainActivity')

# 按下菜单按键device.press('KEYCODE_MENU','DOWN_AND_UP' )

# 截取屏幕截图result = device.takeSnapShot

#将截图保存至文件result.writeToFile('myproject/shot1.png' ,'png' )

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值