开源自动化测试平台使用手册

  • 使用手册
    • 系统介绍
      • 1. 系统管理
      • 2. 系统监控
      • 3. 系统工具
      • 4. 测试管理
      • 5. 测试执行
    • 语法手册
      • 1. 测试驱动(接口)自动化语法说明
      • 2. Web UI自动化语法说明
      • 3. 移动端自动化语法说明
      • 4. HTTP&Socket模板自动化语法说明
      • 5. 步骤动作关键字
    • 示例手册
      • 1. API接口自动化示例
      • 2. APP自动化示例
    • API驱动关键字
      • 1:数据库操作
      • 2:redis操作
      • 3:字符串操作
      • 4:其它通用操作
    • 常见问题

使用手册

本手册是测试人员搭建环境以及使用系统的指导教程,当你有一定的计算机基础且了解一点环境部署方面的知识,那么阅读完此手册后,可以将测试平台的环境搭建运行起来并且应用到项目的实际测试工作中。

本手册中主要包括相关环境、应用软件的准备安装,平台的相关配置,系统使用的介绍等说明

系统介绍

基础管理模板主要分成三部分,【系统管理】【系统监控】【系统工具】:

1. 系统管理

 主要用来维护系统级别的基础数据,有用户、角色、部门、项目、客户端、参数、日志等管理模块。其中用户、角色、岗位、部门这四个模块主要用来维护基础的用户信息,以及用户对应的权限,用户权限可以控制项目权限以及菜单的访问权限,如下图![在这里插入图片描述](https://img-blog.csdnimg.cn/20200731153837400.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW9taV8zMjE=,size_16,color_FFFFFF,t_70)

项目管理主要用来维护测试项目的基础信息,项目一旦被使用,产生测试数据,是不允许被删除的,只能修改。如果要删除,必须先删除所有的关联测试数据。
项目标识主要用于此项目下的用例编号前缀,所以建议使用项目名称的拼音首字母大写即可

日志管理主要包含了用户的登录日志以及操作,相关的活动全部记录入库,一目了然的可以看到用户活动轨迹

2. 系统监控

系统监控主要分为【在线用户监控】【定时任务监控】【应用级别监控】【硬件资源监控】四大部分
在线用户监控主要用来查询在线用户的基础信息,包括IP、使用的浏览器、操作系统等,同时也可以强制用户退出登录

定时任务监控主要用来查询系统所有定时任务的明细,包括测试调度的定时任务,也包括了客户端的轮询心跳

数据监控主要用来查询Web服务各个应用层面的监控数据,可以用来更好的监控Web服务的运行状态以及异常,更加方便的定位问题。

服务监控主要用来监控Web服务器的硬件资源情况,更好的查看硬件资源的实时情况,方便判断定位问题

3. 系统工具

系统工具菜单可以针对普通使用者进行屏蔽,因为此菜单主要是针对开发者设定的,如果你打算进行二次开发,或是小幅度的优化,可以参照此章节,否则不建议阅读,浪费你时间
【表单构建】主要通过拖拽控件到右侧区域,来自动生成HTML代码,方便更快的对页面进行布局设置
【代码生成】只要事先在数据库创建一张新表,此处就能检测出已经创建的新表,然后点击生成代码,即可生成对应这张表的HTML以及对应的后台代码,COPY到项目中,重启服务即可,这样一个基础的功能管理界面雏形就有了,可以简化80%的开发代码工作

其他功能【系统接口】【字典管理】【菜单管理】等功能请谨慎使用,建议在没有二次开发的需求下,不要改动,以防止系统因为缺失或是被篡改默认数据后,出现异常

4. 测试管理

测试管理菜单包含了【用例管理】【用例模块】【协议模板】【测试计划】【公共参数】五大模块
1、用例管理
支持在线直接编辑用例,并且直接点开【+】号后也可以查看编辑用例中的步骤

复制用例(选择要复制的用例有且只有一条)

选择用例后,点击【复制用例】,复制的用例需要修改用例名即可提交
用例步骤(选择要编辑的用例有且只有一条)
选择用例后,点击【用例步骤】。

点击右侧的操作图标,即可新增【+】、复制【∨】、删除【-】、上移【↑】、下移【↓】当前步骤。

如果当前用例的类型是HTTP接口或是API驱动,那么当前页面的调试按钮可用,您可以在点击以后在当前页面实现用例调试,调试时需要确保项目已经配置了客户端且上传了代码。如果不是这两种类型的用例,调试按钮默认隐藏。

当前步骤如果是UI自动化类型的步骤(包括Web或是移动端),那么在【方法|操作】列会自动联想出UI自动化支持的方法。

2、用例模块
用例模块主要是为了方便对测试用例进行树形管理,通过模块归属的管理,更好的对测试用例在项目中进行归类查询

3、协议模板
HTTP接口测试的时候,需要构建一个请求内容的模板。此处定义的是一个默认请求模板,当你在编辑用例步骤的时候,步骤的类型选择了HTTP,那么点击【扩展字段】列,就能自动联想出对应项目的所有模板,选择其中一个即可。

点击【新增模板】,可以为对应的项目新增一个协议模板。

模版参数的请求头域可配置,每个请求参数名与值之间以 ; 隔开。当您的参数值中本来带有 ; 时,请以;的方式进行转义注释。
设置了头域的模板,可以在用例步骤中对头域参数值进行替换,如果模板中头域参数为空,则在步骤中不可设置。

在协议模板列表中,点击复选框选择一个模板,点击【模板参数】,进入到参数配置页面。

参数配置页面有两个标签页,一个是纯文件的方式,一般用于JSON类,RESTFUL风格的比较多。一个是表单提交类,一般用于普通的表单提交,文件上传下载等操作比较多,当然表单方式也可以兼容RESTFUL风格的HTTP请求,具体可参照官网的其他说明文章即可。
备注:参数中的默认值,可以在用例步骤中进行参数替换,如果未替换则使用模板中的默认值

4、测试计划
快速查询测试计划,可以查询项目中已经在计划以及没有在计划中的测试用例,并且可以看到当前计划中存在用例的数量。

支持在线快速编辑测试计划。

备注:调度任务中选择的测试计划,就是此处的测试计划以及计划中对应的测试用例

计划用例

选择对应的测试计划,再点击【计划用例】,可以对计划中的用例进行添加/删除,选择对应的测试用例到计划中。

支持测试计划中用例执行的优先级设置

5、公共参数

在此创建的参数,在参数所属的项目中里面任何一条用例皆可引用。

当然如果你想定义所有项目的都可以使用的参数,那么你只需要把参数项目选择【所有项目】即可。

用例步骤中引用方式: @参数名

5. 测试执行

测试执行菜单包含了【任务调度】【任务执行】【用例明细】三个模块,其中用例明细里面既有用例执行的基本情况,在用例界面展开后也有执行过程的详细日志
1、任务调度
任务调度主要是为测试计划配置一个定时任务,按Cron表达式来定时执行测试计划。

测试驱动路径,指的是客户端对应配置的驱动路径,用来存放指定的外部测试驱动API,当有多个驱动路径时,会有下拉选项。

点击【查看日志】按钮,以文本文件的形式展示,建议使用360浏览器,此时你查看日志不需要下载,直接在页面可以直接查看。

此处的查看日志,展示的是客户端上log4j的日志,非数据库日志,相对用例中的步骤日志,此处的日志更加详细,能更方便的分析问题。

点击【上传驱动包】按钮,主要是指把测试驱动打包成 jar 的形式后,上传到指定的客户端使用。

选择客户端,上传项目的客户端应该与【客户端配置】中配置的客户端一致。

上传的驱动路径,就是客户端执行时,加载jar的路径。

2、任务执行
主要查询所有测试任务的执行概要情况以及当前任务的测试进展。

点击任务名称或是用例的概要数据,可以跳转到【用例明细】模块中,查询对应的用例状态以及执行日志

3、用例明细
主要用于查询用例的执行情况以及执行过程中的业务日志,方便快速定位自动化过程中出现的问题。

点开【+】号即可查看当前用例的执行日志。

失败状态的用例,左侧复选框可选,选中后点击【执行所选用例】会开始执行指定选择的用例。 点击【执行全部非成功状用例】,点击后会重新执行当前任务下所有非成功状态的用例。

针对Web UI或是移动端类型的用例,如果失败,在日志明细中一般会产生错误截图链接,点击可以查看。

针对失败用例,如果当前测试结果已经发生变更,可直接同步测试结果到用例步骤中

语法手册

1. 测试驱动(接口)自动化语法说明

Web服务端中的系统管理模块里面,有一个客户端管理功能,其中有一个配置驱动目录的选项,会默认有一个驱动目录为/TestDriver,如果你有几个项目在同一个客户端运行,为了避免包冲突的情况,建议您一个项目配置一个驱动目录。
将您打包好的测试驱动JAR包,放置在客户端编译好的项目根目录中的驱动目录下即可。
注意:是在编译好的项目根目录下的驱动目录中,不是直接放在项目代码目录下的驱动目录
1:普通的方法调用
包|定位路径:Package名.类名

方法|操作:方法名

参数:参数1|参数2|……|参数n

示例:

2:参数引用以及传递
将用例里面前面步骤的执行结果,传递至后续步骤的包路径、方法、参数、预期结果中当成参数;

赋值局部变量:$=value

引用:@value 用例里面前面步骤的执行结果,传递至后续步骤的包路径、方法、参数、预期结果中当成参数; 当您需要引用项目中定义的公共参数时,直接使用 @变量名 引用即可。

赋值全局变量: $A=value

赋值局部变量 $=value,作用域只在单条用例内的步骤间进行传递,而关键字 $A=value 支持作用域扩展到整个任务执行的生命周期内。只要是同一个调度任务内,都可以对此变量进行引用以及传递。

注意:

当遇到参数值里面本身带了字符@的,请使用@@来转义。比如参数值是一个邮箱地址XX@qq.com,那么这时候你应该写成XX@@qq.com.
当遇到参数值里面本身带了字符 | 的,请使用 \| 来转义。比如有一个参加值是:tfwfsf|ysggfw|ggsvs ,那么这时候你应该把这个参数写成这样:tfwfsf\|ysggfw\|ggsvs
示例:


3:预期结果精确匹配
将用例里面【方法|操作】执行的结果,与【期望的结果】字段里面的字符串进行精确匹配;

直接在预期结果里面填写需要匹配的字符串即可。

4:预期结果模糊匹配
将用例里面【方法|操作】执行的结果,与【期望的结果】字段里面的字符串进行模糊匹配;

模糊匹配: %=value

示例:

5:正则方式结果模糊匹配
将用例里面【方法|操作】执行的结果,与【期望的结果】字段里面的字符串通过正则表达式进行匹配;

模糊匹配: ~=value

正则表达式写法,请自行百度,不再累述。针对多个结果模糊匹配,非包含字符匹配都可以用此种方式,非常灵活。

6:步骤间添加休眠时间
步骤执行完成后,等待 N 秒,在【步骤动作】中加上“10#Wait” 10 表示 10 秒;

更多【步骤动作】说明,请参考3.2.5章节

示例:

2. Web UI自动化语法说明

1:关键字语法结构
包|定位路径:语法结构 属性=对应值 示例:xpath=.//*[@id=‘username’] 元素在页面中的定位路径,定位属性支持请参考下面内容,如果操作不涉及页面元素,此栏为空

方法|操作:自动联想出Web UI封装好的操作语法

预期结果:语法结构 check(属性=对应值) 示例:check(xpath=.//*[@id=‘username’]) 此方法用来检查步骤动作执行完成后,检查对应的元素是否存在。

示例:

2:其他关键字语法结构
支持与接口自动化相同关键字语法,写法一样,如:参数传递、模糊匹配预期结果步骤间休眠等,请参考接口自动化的章节,此处不再赘述

3:web用例调用接口用例
当你的WEB UI用例需要调用另外一条接口用例或是WEB UI用例的时候,提供一种runcase的方式,在【方法|操作】列选择runcase,在【参数】列输入接口用例的编号就可以了。此操作变量不共享。

同时在WEB UI用例也支持插入接口类型的步骤(此操作变量共享)

类似在接口用例中填写步骤的用法,“包 | 定位路径”列填包路径,“方法 | 操作”列填方法名,“参数”列填传给该方法的入参,“预期结果”列可以选填根据方法返回值的断言,“类型”列选接口

示例:

4:元素操作语法
语法结构:动作(方法|操作) 操作值(参数)

示例:sendKeys(方法|操作) username(参数)

关键字 解释
selectbyvisibletext 通过下拉框的文本
selectbyvisibletext 通过下拉框的文本
selectbyvalue 通过下拉框的 VALUE 属
selectbyindex 通过下拉框的 index 属性,从 0 开始计数
isselect 判断是否已经被选择,同用于单选、复选框

获取对象属性值类

关键字 解释
gettext 获取文本属性
gettagname 获取标签类型
getattribute 获取指定属性值
getcssvalue 获取cssvalue值
getcaptcha 获取验证码

对象动作类

关键字 解释
lick 点击
sendkeys 输入
clear 清除输入框
gotoframe 跳转框架(iframe)
isenabled 是否可用
isdisplayed 是否可见
exjsob 针对对象执行JS脚本,返回值非空,则使用该返回值返回,可用于用例步骤的预期结果判断;如:通过js获取只读输入框中的内容,然后跟目标值做判断。
scrollto 滚动到目标对象
scrollintoview 将目标对象滚动到可视

主对象类(无定位属性)

关键字 解释
open 打开页面
exjs 执行js脚本,返回值非空,则使用该返回值返回,可用于用例步骤的预期结果判断;如:通过js获取只读输入框中的内容,然后跟目标值做判断。
gotodefaultcontent 跳转回到默认 frame(用于跳转到另一个 iframe 后,跳回
gettitle 获取窗口标题
getwindowhandle 参数可以是目标窗口句柄的下标或标题。下标:从1开始,小于等于0则返回当前窗口的句柄值;标题:非空则返回第一个匹配的窗口的句柄值,为空则返回当前窗口的句柄值;
gotowindow 参数可以是窗口句柄、名称、标题、下标(注:下标从0开始),先使用句柄和名称查找目标窗口句柄,没有找到再使用标题查找,最后用下标去尝试查找。
runcase 调用指定用例编号的接口
gotoparentframe 跳转回到上一级iframe
wait 等待
closewindow 关闭当前浏览器窗口
addcookie 添加浏览器cookie

弹出框类

关键字 解释
alertaccept 点击 OK
alertdismiss 点击取消
alertgettext 获取弹出框 TEXT

模拟鼠标键盘类

关键字 解释
mouselkclick 模拟鼠标左键单击(可带页面对象)
mouserkclick 模拟鼠标右键单击(可带页面对象)
mousedclick 模拟鼠标双击(可带页面对象)
mouseclickhold 模拟鼠标左键单击后不释放(可带页面对象)
mousedrag 模拟鼠标拖拽(可带页面对象)
mouseto 模拟鼠标移动到指定坐标(可带页面对象)
mouserelease 模拟鼠标释放(可带页面对象)
mousekey(tab) 模拟键盘Tab键
mousekey(space) 模拟键盘Space键
mousekey(ctrl) 模拟键盘Ctrl键
mousekey(shift) 模拟键盘Shift键
mousekey(enter) 模拟键盘Enter键

3. 移动端自动化语法说明

简介:介绍移动端自动化相关的语法说明,目前仅支持在Windows环境下的安卓自动化。IOS的自动化,由于必须运行在MAC环境中,所以客户端中Windows批处理相关的命令需要重新改造,目前这一块暂时不支持,但是封装的框架代码已经集成了IOS相关的自动化。有兴趣的同学可以改造后分享出来
1:客户配置移动端自动化
在客户端项目的根目录下,有一个appium_config.properties的配置文件,在其中对客户端即将运行的移动端自动化相关配置项进行修改。

另:因为平台集成的是APPIUM自动化框架,所以必须在客户端的环境自己先行搭建环境,搭建步骤可以参考文章: 《APPIUM自动化测试环境搭建实践》

2:关键字语法结构
包|定位路径: 语法结构 属性=对应值 示例:xpath=.//*[@id=‘username’] 元素在页面中的定位路径,定位属性支持请参考下面内容,如果操作不涉及页面元素,此栏为空

方法|操作:自动联想出Appium封装好的操作语法

预期结果:语法结构 check(属性=对应值) 示例:check(xpath=.//*[@id=‘username’]) 此方法用来检查步骤动作执行完成后,检查对应的元素是否存在。

示例:

3:其他关键字语法结构
支持与接口自动化相同关键字语法,写法一样,如:参数传递、模糊匹配预期结果步骤间休眠等,请参考接口自动化的章节,此处不再赘述。

4:移动端用例调用接口用例
当你的移动端用例需要调用接口用例的时候,提供一种runcase的方式,在【方法|操作】列选择runcase,在【参数】列输入接口用例的编号就可以了。

5:元素操作语法
语法结构:动作(方法|操作) 操作值(参数)

示例:sendKeys(方法|操作) username(参数)
下拉框类

关键字 解释
selectbyvisibletext 通过下拉框的文本
selectbyvalue 通过下拉框的 VALUE 属
selectbyindex 通过下拉框的 index 属性,从 0 开始计数
isselect 判断是否已经被选择,同用于单选、复选框

获取对象属性值类

关键字 解释
gettext 获取文本属性
gettagname 获取标签类型
getattribute 获取指定属性值
getcssvalue 获取CSS属性值

对象动作类

关键字 解释
click 点击
sendkeys 输入
clear 清除输入框
longpresselement 长按页面指定元素,带参,单位:秒
isenabled 是否可用
isdisplayed 是否可见
exjsob 针对对象执行JS脚本

主对象类(无定位属性)

关键字 解释
getcontexthandles 获取指定context的handle,带参,指定第几个窗口
exjs 执行js脚本
keycode 安卓模拟手机键盘发送,带参,按键代码
hidekeyboard 安卓隐藏手机键盘
gotocontext 跳转窗口(句柄),使用getcontexthandles传参值
getcontext 获取当前页面context
gettitle 获取当前页面title
swipeup 手指向上滑动 参数格式: 持续时间(秒)
swipedown 手指向下滑动 参数格式:
swipeleft 手指向左滑动 参数格式: 持续时间(秒)
swiperight 手指向右滑动 参数格式: 持续时间(秒)
swipepageup 拖动页面向上滑动 参数格式: 持续时间(秒)
swipe pagedown 拖动页面向下滑动 参数格式: 持续时间(秒)
swipe pageleft 拖动页面向左滑动 参数格式: 持续时间(秒)
swipe pageright 拖动页面向右滑动 参数格式: 持续时间(秒)
longpressxy 长按指定坐标参数格式: X坐标
pressxy 点击指定坐标参数格式: X坐标
Tapxy 轻击指定坐标参数格式: X坐标
jspressxy JS实现方式点击指定坐标参数格式: X坐标
moveto 在屏幕指定坐标之间滑动参数格式: X1,Y1
timeout 设置全局页面加载&元素出现最大等待时间 参数单位:秒
screenshot 对当前屏幕进行截图
exAdbShell 执行安卓adb命令弹出框类
alertaccept 点击 OK
alertdismiss 点击取消
alertgettext 获取弹出框 TEXT

4. HTTP&Socket模板自动化语法说明

简介:介绍HTTP&Socket的模板使用以及语法说明,包括HTTP中的json如何应用
首先,HTTP&Socket的自动化测试,每个步骤都必须要关联协议模板,去构造消息头以及消息体。

其次,在步骤动作栏中,点击输入框会自动联想当前项目下所有的协议模板,选择对应的模板即可。

再次,请求的参数都必须在模板里面先构造,不能直接在用例步骤的参数列里面去构造,步骤的参数列只能去替换模板里面的默认参数值。也就是说必须得在模板里面有的参数,步骤参数才能生效去替换默认值。

1:关键字语法结构
参数栏可以修改模板中的默认值,如果参数为空,则默认使用模板中定义好的默认参数。

参数栏填写示例:参数名#参数值|参数名#参数值|参数名#参数值|……|

示例:

支持头域参数化:协议模板的请求头域可修改

需要自己设置的常见头域就是登录鉴权了,比如有用Cookie的,那么你必须把token放到Cookie中去,Cookie是放在HTTP消息的头域来发送的。

a.模板中头域为空,可设置头域,但不能设值

例:headmsg(Content-Length)| headmsg(Connection)……

b.模板中设值了请求头域,可修改头域的值headmsg(header)#值

例:headmsg(Content-Length)#500| headmsg(From)#user@@email.com……

头域的值也可传递参数 例:headmsg(Content-Type)#@type

c.模板头域中的参数设置,以;分隔参数,当本身参数值中有;号时,注意使用;进行转义设置。

d.如果构造JSON格式模板,请参考协议模板内容页面中【参数示例】,点击打开后,有详细示例。

2:关于HTTPS的测试
HTTPS的请求测试分为两种,一种是单向认证,一种是双向认证(需要证书),以下分别介绍这两种方式如果去构造请求。

如果是HTTPS单向认证,那么跟普通的HTTP请求差不多,你只需要把【包|定位路径】列中的URL,把http换成https即可,如:https://www.baidu.com/ ,另外在选择请求方法的时候,请注意,必须选择 httpclient 类别的请求,此类请求才支持https。

如果是HTTPS双向认证,那么你需要比单向认证多一个步骤,就是在创建协议模板的时候,要按格式(https证书路径;证书密钥)填写https证书在客户端的路径以及证书的密钥。

注意:如果客户端在运行HTTPS的时候报下面的异常:
javax.net.ssl.SSLKeyException: RSA premaster secret error
是因为缺少JRE中的jar包,把JRE安装目录中的JAR包(sunjce_provider.jar),复制到客户端项目的LIB目录或是对应的驱动目录即可解决。见下图:

3:HTTP&Socket支持的方法

关键字 解释
HttpURLPost 使用HttpURLConnection发送post请求
URLPost 使用URLConnection发送post请求
GetAndSaveFile 发送get请求保存下载文件到客户端
HttpURLGet 使用HttpURLConnection发送get请求
URLGet 使用URLConnection发送get请求
HTTPClientPost 使用HTTPClient发送post请求
HTTPClientGet 使用HTTPClient发送get请求
HttpClientPostJSON 使用HTTPClient发送JSON格式的post请求
HttpURLDelete 使用HttpURLDelete发送delete请求
httpClientPut 使用httpClientPut发送put请求
httpClientPutJson 使用httpClientPutJson发送put请求

5. 步骤动作关键字

3#Wait 当前步骤暂停3秒,以前写法是3Wait 现在间隔符由号变成#,以便后续统一规划。 历史关键字处理,在版本升级的数据库脚本中已经提供相关SQLupdate project_casesteps set action=REPLACE(action,’*’,’#’) where action like “%*wait” or action like “%*Wait”

key[序号]#getJV 获取测试结果中JSON对象中,指定KEY的值,比如测试结果返回:{[“name”:“张三”,“age”:“18”][“name”:“李四”,“age”:“17”]} ,如果想获取李四的年纪 在步骤动作中需要这样写 age[2]#getJV 获取到以后,会拿到17这个值,给预期结果中的关键字进行判断,是匹配,还是赋值都可以。

[startstr][endstr]#subCentreStr 截取测试结果中指定开始字符以及结束字符的中间字符串,比如测试结果返回:{[“name”:“张三”,“age”:“18”][“name”:“李四”,“age”:“17”]} ,如果想获取李四的年纪 在步骤动作中需要这样写 [age":"]["]}]#subCentreStr 获取到以后,会拿到17这个值,给预期结果中的关键字进行判断,是匹配,还是赋值都可以。

[startnum][endnum]#subCentreNum 截取测试结果中指定开始位置以及结束位置的中间字符串,比如测试结果返回:{[“name”:“张三”,“age”:“18”][“name”:“李四”,“age”:“17”]} ,如果想获取李四的年纪 在步骤动作中需要这样写 [45][46]#subCentreNum 获取到以后,会拿到17这个值,给预期结果中的关键字进行判断,是匹配,还是赋值都可以。

[rgex][index]#subStrRgex 通过正则截取测试结果中的字符串,[rgex]在[]中填写正则表达式,[index]在[]中填写匹配到字符串的序号,拿到截取的值以后,给预期结果中的关键字进行判断,是匹配,还是赋值都可以。

示例手册

1. API接口自动化示例

本章节内容:应用LUCKYFRAME来编写API测试用例的过程
1 、添加项目名称和归属部门
进入系统管理—>项目管理—>点击添加,填写“项目名称”、“归属部门”、“项目标识”,点击“确定”,如图下图。备注:归属部门在系统管理—>部门管理模块设置

2、添加协议模板
说明:协议模板是什么?是构造接口请求必须遵守的基础约定;不理解先放一边,重点是要知道一个接口对应一个协议模板。

进入测试管理—>协议模板—>点击添加,选择项目名称,模板名称填写接口名称,消息头域(一般访问接口的时候需要先登录,那么此处就需要填写,格式看示例要求)。其他选项可以先默认,点确定,完成一个协议模板的添加。如下图。

勾选模板类型,点击“模板参数”,如下图。

RAW标签页面,填写格式遵循JSON格式请求,如下图。(此处不懂JSON格式需要去百度一下)

FORM标签页面,各种参数类型填写格式,如下图

String:字符串

Json对象:{ “endDate”: “string”, “startDate”: “string” }

JsonNARR:[{ “endDate”: “string”, “startDate”: “string” }]

File对象:D:\F盘\01tlw\04接口测试\1.jpg (即LuckyFrameClient本地磁盘上传文件的路径)

Number对象:1.2.3……

Boolean对象:true or false

注意:填写RAW标签和FROM标签,只填写其中一种

3、添加用例模块
进入测试管理—>用例模块—>选中项目名称,点击新增,填写父模块、模块名字、显示顺序、备注。点击“确定”,完成模块的添加,如下图:

4、用例管理
进入测试管理—>用例管理—>点击添加,如下图:

选择项目名称、用例模块,填写用例名称、用例类型选择“HTTP接口”,点击“确定”如下图:

勾选用例名称,点击“用例步骤”,如下图:

用例步骤页面,如下图:

4.1步骤编辑页面基本使用方法

4.1.1包|定位路径

填写接口的地址,如:http://10.0.7.105/validation/rest/quality

4.1.2方法|操作
此处单击可以选择系统内置的一种方法名,如:HttpClientGet

4.1.3参数
填写接口参数,传入多个参数用|分隔,参数名称和参数值用#分隔,如:id#1|name#test

4.1.4步骤动作
填写该行用例步骤执行后的等待时间;等待1秒格式,如:1#wait

4.1.5预期结果
此处填写接口预期的返回值;模糊匹配返回值中是否有200,如:%=200

4.1.6类型
默认http接口

4.1.7扩展字段
此处单击可以选择已添加过的协议模板,如:新增质检模型接口

4.1.8 示例

4.1.9调试
点击调试按钮,进入用例调试页面,如下图

注意调试时要先进入系统管理—>客户端管理—>点击添加客户端,且状态正常,如下图:

客户端添加完成后,点击“调试”按钮,进入用例调试页面,如下图:

根据用例调试页面的日志,可以查看用例的执行结果是否正常,到此完成接口用例编写的介绍。

4.2步骤编辑页面进阶使用方法

4.2.1 参数引用以及传递
将用例里面前面步骤的执行结果,传递至后续步骤的包路径、方法、参数、预期结果中当成参数;

赋值局部变量:$=value

引用:@value 用例里面前面步骤的执行结果,传递至后续步骤的包路径、方法、参数、预期结果中当成参数; 当您需要引用项目中定义的公共参数时,直接使用 @变量名 引用即可。

赋值全局变量: $A= value

赋值局部变量 $=value,作用域只在单条用例内的步骤间进行传递,而关键字 $A=value 支持作用域扩展到整个任务执行的生命周期内。只要是同一个调度任务内,都可以对此变量进行引用以及传递。

注意:

当遇到参数值里面本身带了字符@的,请使用@@来转义。比如参数值是一个邮箱地址XX@qq.com,那么这时候你应该写成XX@@qq.com.
当遇到参数值里面本身带了字符 | 的,请使用 \| 来转义。比如有一个参加值是:tfwfsf|ysggfw|ggsvs ,那么这时候你应该把这个参数写成这样: tfwfsf\|ysggfw\|ggsvs
示例:

4.2.2 预期结果精确匹配
将用例里面 【方法|操作】执行的结果,与 【期望的结果】字段里面的字符串进行精确匹配;

直接在预期结果里面填写需要匹配的字符串即可。

4.2.3 预期结果模糊匹配
将用例里面 【方法|操作】执行的结果,与 【期望的结果】字段里面的字符串进行模糊匹配;

模糊匹配: %=value

示例:

4.2.4 正则方式结果模糊匹配
将用例里面 【方法|操作】执行的结果,与 【期望的结果】字段里面的字符串通过正则表达式进行匹配;

模糊匹配: ~=value

正则表达式写法,请自行百度,不再累述。针对多个结果模糊匹配,非包含字符匹配都可以用此种方式,非常灵活。

4.2.5 步骤间添加休眠时间
步骤执行完成后,等待 N 秒,在 【步骤动作】中加上“10#Wait” 10 表示 10 秒;

示例:

4.2.6随机参数值引用
目前支持两种模式,一种是随机数字,一种是获取当前时间的指定格式

随机数字引用关键字参数:@{random[开始数字][结束数字]}比如你想随机一个指定区间的手机号码,如:137XXXX8888 可以在引用参数的时候这样写:137@{random[1000][9999]}8888

获取当前时间指定格式引用关键字参数:@{timenow[日期时间格式]}比如:想生成这样一个字符串 现在时间是:2019-01-25 11:13:36可以在引用参数的时候这样写:现在时间是:@{timenow[yyyy-MM-dd HH:mm:ss]}其中[yyyy-MM-dd HH:mm:ss]中的参数与JAVA类SimpleDateFormat的格式用法是一致的,里面的间隔符( 比如 - ,: )可以删除或是用其他任意字符替换。如果格式不正确的话,会使用默认格式进行引用。

下面做下简单的说明:

yyyy 代表年份

MM 代表月份

dd 代表日期

HH 代表24小时制

hh代表12小时制

mm 代表分钟

ss 代表秒

4.2.7接获取JSON串中KEY值的方法
4.2.7.1 客户端中内置驱动增加直接获取JSON串中KEY值的方法
包路径:luckyclient.driven.SubString

方法名:getJsonValue

参数:@loginrespone|accessToken|1

备注:

@loginrespone:JSON字符串

accessToken:JSON字符串中需要获取值的key

1:key值索引(序号)

4.2.7.2 步骤动作新支持的关键字。

key[序号]#getJV 获取测试结果中JSON对象中,指定KEY的值,比如测试结果返回:{[“name”:“张三”,“age”:“18”][“name”:“李四”,“age”:“17”]} ,如果想获取李四的年纪 在步骤动作中需要这样写 age[2]#getJV 获取到以后,会拿到17这个值,给预期结果中的关键字进行判断,是匹配,还是赋值都可以。
[startstr][endstr]#subCentreStr 截取测试结果中指定开始字符以及结束字符的中间字符串,比如测试结果返回:{[“name”:“张三”,“age”:“18”][“name”:“李四”,“age”:“17”]} ,如果想获取李四的年纪 在步骤动作中需要这样写 [age":"]["]}]#subCentreStr 获取到以后,会拿到17这个值,给预期结果中的关键字进行判断,是匹配,还是赋值都可以。
[startnum][endnum]#subCentreNum 截取测试结果中指定开始位置以及结束位置的中间字符串,比如测试结果返回:{[“name”:“张三”,“age”:“18”][“name”:“李四”,“age”:“17”]} ,如果想获取李四的年纪 在步骤动作中需要这样写 [45][46]#subCentreNum 获取到以后,会拿到17这个值,给预期结果中的关键字进行判断,是匹配,还是赋值都可以。
[rgex][index]#subStrRgex 通过正则截取测试结果中的字符串,[rgex]在[]中填写正则表达式,[index]在[]中填写匹配到字符串的序号,拿到截取的值以后,给预期结果中的关键字进行判断,是匹配,还是赋值都可以。

2. APP自动化示例

本章节内容:应用LUCKYFRAME来实现APP(安卓)自动化测试的过程。

实现原理:调用appium实现APP自动化,LuckyFrame测试平台将自动化用例进行管理、调度任务执行并将结果发送邮件
1 搭建APPIUM环境
1.1 安装node.js
Appium是使用nodejs实现的,所以node是解释器,需要第一步安装好

node.js的安装包下载地址: https://nodejs.org/en/download/

注意:node.js的安装包的下载在官网有两种版本,建议大家下载LTS版本,按照官方的意思,这个版本应该算是稳定版本。页面会根据你的OS有推荐版本,选择版本LTS 12.13.1(已经包含npm 6.12.1的版本,npm是node.js的包管理工具)

安装完成后检查一下版本有没有问题,如下图:

1.2 安装安卓的SDK
安卓SDK下载地址: http://tools.android-studio.org/index.php/sdk

第一步:安装

在安装目录下有一个SDK Manager.exe的文件,双击打开,可以下载你想要的SDK。

主要安装工具Platform-tools、build-tools、Android API(选择最新版本即可),还有扩展插件Google USB Driver,其他根据实际情况自行选择。


第二步:配置环境变量

  1. 新建一个环境变量

变量名:ANDROID_HOME,

变量值:C:\Users\xujp\AppData\Local\Android\android-sdk (以你安装目录为准,确认里面有tools和add-ons等多个文件夹),点击确认

  1. 在用户变量PATH后面加上变量值;%ANDROID_HOME%\platform-tools;

  2. 在系统变量path中添加; C:\Users\xujp\AppData\Local\Android\android-sdk\tools

  3. Android SDK配置完成,接下来验证配置是否成功

  4. 点击运行——输入cmd回车——输入adb回车,如显示ADB版本号,如下图所示,即表示配置成功,在输入Android,启动Android SDK Manager

    1.3 安卓模拟器
    个人觉得安卓SDK自带的模拟器不是太好,建议可以使用Genymotion这个模拟器

先注册一个账号,注册完就能下载了。

Genymotion下载链接在此: https://www.genymotion.com/download/

最好直接下载第一个,直接内置了VirtualBox,否则还得另外安装。

第一步:登录后选择一个机型,如:三星Galaxy S10,将设备名称设置为TestApp

第二步:启动设备,status为On

1.4 安装appium
推荐npm的安装方式,简单方便,它是可以直接取到最新的版本安装的。

因为前面安装node.js的时候,已经安装了npm,所以这里我们不再需要单独安装npm,直接使用此命令就可以了。

你如果要安装最新的版本可以直接使用以下命令
npm install -g appium

如果你要安装指定的版本可以全用以下命令,appium的版本必须在1.8.1-1.7之间,否则与luckyframe3.1存在兼容问题
npm install -g appium@1.8.0

注意: 自动安装完后,机器会自动重启,我的win10就在我猝不及防的情况重启了,提醒大家提前保存好重要的东西。

重启完成后,就可以检查一下appium版本了。

1.5 启动APPIUM服务
注意:直接使用appium启动服务,这里监听的IP跟端口都是默认的,也就是0.0.0.0:4723,启动完成APPIUM环境搭建完成

如果你要指定IP跟端口,可以采取以下方式

2 配置
2.1 appium_config配置
2.1.1 配置说明
Ø 配置文件位置:E:\LuckyFrame\LuckyFrameClient\appium_config

Ø appPackage、appActivity获取方法直接百度,我使用的是aapt dump badging app-release.apk


package:name 就是appPackage

launchable-activity: name 就是appActivity

Ø 将待测APK包放置LuckyFrameClient目录下(appname=app-release.apk)


Ø 模拟器运行的设备名称,status为On

#设备名称 备注:如果您使用的模拟器,就是模拟器中虚拟机的名称

deviceName=TestApp

2.1.2 检查LF是否能调用appium成功
注:执行调度任务前需启动客户端、appium及模拟器

  1. WEB端创建测试计划(可不添加用例)–创建调度任务(APP测试)确定
  2. 手动执行调度任务,若模拟器中自动安装APK包成功,则表示LF成功调用APPIUM

3 APP自动化测试执行
3.1 添加用例
创建项目、用例模块此处不再说明,添加用例:


3.2 用例步骤


包|定位路径语法结构:属性=对应值

示例:xpath=.//*[@id=‘username’]

元素在页面中的定位路径,定位属性支持(id、name、xpath、linktext、tagname、cssselector、androiduiautomator、classname、partiallinktext、accessibilityid、iosclasschain、iosnspredicate、iosuiautomation),如果操作不涉及页面元素,此栏为空

方法|操作:自动联想出Appium封装好的操作语法

预期结果:语法结构 check(属性=对应值) 示例:check(xpath=.//*[@id=‘username’]) 此方法用来检查步骤动作执行完成后,检查对应的元素是否存在。

3.3 例子:登录用例
登录用例分为7个步骤,如下图:

Ø 步骤一、二:安装完进入引导页,左滑动两次引导页,进入主页

包|定位路径:空
方法|操作:moveto
参数:x1,y1|x2,y1

步骤动作:空、5#wait(等待5秒)

预期结果:空

类型:移动端

说明:参数表示坐标,从x1,y1的位置移动到x2,y1位置

Ø 步骤三、四:进入我的页面–登录页面

通过uiautomatorviewer获取xpath,注意如果有@,需要加一个@进行转义

包|定位路径:xpath=//android.widget.LinearLayout[@@resource-id=‘com.hhsurong.app:id/bottom_navigation_bar_item_container’]/android.widget.FrameLayout[4]/android.widget.FrameLayout[1]/android.widget.FrameLayout[1]/android.widget.ImageView[1]
方法|操作:click
参数:空

步骤动作:空

预期结果:空

类型:移动端

Ø 步骤五、六:输入用户名、密码

包|定位路径:xpath=//android.widget.EditText[@@text=‘请输入手机号码’]
方法|操作:sendkeys
参数:用户名/密码

步骤动作:空

预期结果:空

类型:移动端

Ø 步骤七:点击登录,进入登录页面

包|定位路径:xpath=//android.widget.Button[@@text=‘登录’]
方法|操作:click
参数:空

步骤动作:2#wait

预期结果:check(xpath=//android.widget.RelativeLayout/android.widget.ImageView[1])

类型:移动端

说明:预期结果通过check(属性=对应值)来检查元素是否存在,以此判断登录是否成功

3.4 任务调度执行
执行原理:先初始化–安装APK(每次任务调度都会覆盖安装),再执行测试计划中的用例

3.4.1 添加测试计划

3.4.2 计划用例

选定用例保存用例到计划

3.4.3 添加调度任务

3.4.4 执行调度任务
点击执行即开始进行自动化测试执行,可打开模拟器查看执行情况

3.4.5 查看执行结果
1.点击任务执行,查看执行结果

2.点击任务名称,可以看到详细的用例执行情况

4 用例–方法|操作说明
语法结构:动作(方法|操作) 操作值(参数)

示例:sendKeys(方法|操作) username(参数)

4.1下拉框类

关键字 解释
selectbyvisibletext 通过下拉框的文本
selectbyvalue 通过下拉框的 VALUE 属
selectbyindex 通过下拉框的 index 属性,从 0 开始计数
isselect 判断是否已经被选择,同用于单选、复选框

4.2 获取对象属性值类

关键字 解释
gettext 获取文本属性
gettagname 获取标签类型
getattribute 获取指定属性值
getcssvalue 获取CSS属性值

4.3 对象动作类

关键字 解释

click点击
sendkeys| 输入
clear| 清除输入框
longpresselement| 长按页面指定元素,带参,单位:秒
isenabled| 是否可用
isdisplayed| 是否可见
exjsob| 针对对象执行JS脚本

4.4 主对象类(无定位属性)

关键字 解释
getcontexthandles 获取指定context的handle,带参,指定第几个窗口
exjs 执行js脚本
keycode 安卓模拟手机键盘发送,带参,按键代码
hidekeyboard 安卓隐藏手机键盘
gotocontext 跳转窗口(句柄),使用getcontexthandles传参值
getcontext 获取当前页面context
gettitle 获取当前页面title
swipeup 拖动页面向上滑动 参数格式: 持续时间(秒)
swipedown 拖动页面向下滑动 参数格式: 持续时间(秒)
swipleft 拖动页面向左滑动 参数格式: 持续时间(秒)
swipright 拖动页面向右滑动 参数格式: 持续时间(秒)
longpressxy 长按指定坐标参数格式: X坐标
pressxy 点击指定坐标参数格式: X坐标
Tapxy 轻击指定坐标参数格式: X坐标
jspressxyJS 实现方式点击指定坐标参数格式: X坐标
moveto 在屏幕指定坐标之间滑动参数格式: X1,Y1
timeout 设置全局页面加载&元素出现最大等待时间 参数单位:秒
screenshot 对当前屏幕进行截图
exAdbShell 执行安卓adb命令

4.5 弹出框类

关键字 解释
alertaccept 点击 OK
alertdismiss 点击取消
alertgettext 获取弹出框 TEXT

5 FAQ
5.1 uiautomatorviewer获取元素
问题1:

uiautomatorviewer打开报错

解决方案:手动导入页面获取元素

1.在D盘根目录下创建app.png文本文件

2.在D盘根目录下创建app.uix文本文件

3.执行以下adb命名:

              adb shell uiautomator dump /sdcard/app.uixadb pull /sdcard/app.uix D:/app.uixadb shell screencap -p /sdcard/app.pngadb pull /sdcard/app.png D:/app.png

4.运行uiautomatorviewer.bat,导入文件

API驱动关键字

1:数据库操作

说明 定位路径 方法 参数 返回
执行sq l luckyclient.driven.DbDriven executeSql dbUrl|dbUserName|dbPassword|sql
(数据库URL地址|数据库账号|数据库密码|sql语句)
有更新返回: 成功执行SQL,更新数据 xx 行。
无更新返回:成功执行SQL,没有更新到数据!
执行sql查询 luckyclient.driven.DbDriven executeQuery dbUrl|dbUserName|dbPassword|sqll
(数据库URL地址|数据库账号|数据库密码|sql语句)
返回查询结果字符串,行用#间隔,字段用%间隔

2:redis操作

说明 定位路径 方法 参数 返回
打开redis链接 luckyclient.driven.RedisDriver openRedis redisName|host|port|authorl
(redis名称|Redis地址|端口|密码)
返回true或flase
关闭redis链接 luckyclient.driven.RedisDriver closeRedis redisNamel
(redis名称)
返回true或flase
查询key值 luckyclient.driven.RedisDriver getValue redisName|key
(redis名称|redis键值)
返回key值

注意事项:打开redis,操作完redis后,必须关闭redis

3:字符串操作

说明 定位路径 方法 参数 返回
截取指定字符串的中间字段 luckyclient.driven.SubString subCentreStr str|startstr|endstr 返回结果字符串
截取字符串从指定字符开始 luckyclient.driven.SubString subStartStr str|startstr 返回结果字符串
截取字符串到指定字符结束 luckyclient.driven.SubString subEndStr str|endstr 返回结果字符串
通过位置截取指定字符串的中间字段 luckyclient.driven.SubString subCentreNum str|startnum|endnum 返回结果字符串
通过位置截取字符串从指定字符开始 luckyclient.driven.SubString subStartNum str|startnum 返回结果字符串
截取字符串到指定字符结束 luckyclient.driven.SubString subEndNum str|endnum 返回结果字符串
正则匹配字符串 luckyclient.driven.SubString subStrRgex str|rgex|num 返回结果字符串
判断是否是整型数字 luckyclient.driven.SubString isInteger str 返回true或false
判断是否是整型数字 luckyclient.driven.SubString isInteger str 返回true或false
获取JSON或是JSONArray对象指定序号Key中的Value luckyclient.driven.SubString getJsonValue json|key|indexstr 返回指定key的value字符

4:其它通用操作

说明 定位路径 方法 参数 返回
获取当前系统时间 luckyclient.driven.CommonDriven getCurrenSystemTime Dateformat 返回结果字符串
修改时间戳 luckyclient.driven.CommonDriven timestampPlus DateTime|Dateformat|field|step 返回结果字符串

通用操作举例说明:

说明 定位路径 方法 参数 返回
获取当前系统时间 luckyclient.driven.CommonDriven getCurrenSystemTime yyyy-MM-dd HH:mm:ss 返回结果字符串
修改时间戳 luckyclient.driven.CommonDriven timestampPlus 2020-08-19 00:00:00|yyyy-MM-dd HH:mm:ss|分|11(说明:field参数可填:年,月,星期,小时,分,秒) 返回结果字符串(该例子返回的结果为:2020-08-19 00:11:00)

常见问题

1:使用“获取JSON或是JSONArray对象指定序号Key中的Value”关键字 截取JSON格式的对象出现以下错误日志:【获取JSON KEY中的Value异常】格式化成JSON或是JSONArray时出现异常,请检查参数

错误原因可能是:检查返回此报文接口的参数协议模板,查看状态码返回,选择响应不返回
原因是如果选择了响应返回,则接口调用后返回的字符串中会有状态码相关的字符串:RESPONSE_CODE:【200】,则此字符串不是标准的json格式字符串,在使用json截取关键字时,如果传入的不是标准的json格式字符串,则会报错

2:接口地址和参数与postman中一致,但返回的报文结果不一致,可能有如下原因:
参数协议模板中,如果在接口调用中,需要某参数的值为空值,则应该在参数模板的参数默认值中敲一个空格,如果没有该操作,则该参数在接口传参中会被丢弃,即不会传入该参数

3: JSON格式参数中有同名参数,模板替换时,通过添加参数序列号的方式替换指定的参数
例如:
JSON参数报文如下
{“categoryId”:345,“name”:"",“skuList”:[{“name”:"",“ladderPriceList”:[{“key”:1611381175074,“rangeStart”:1,“rangeEnd”:3,“price”:“16”,“priceType”:10}],“specifications”:""}],“specTemplate”:""}
参数中替换第1个name方式为:name#name[1]
参数中替换第2个name方式为:name#name[2]

LuckyFrame使用手册相关推荐

  1. 分布式训练使用手册-paddle 数据并行

    分布式训练使用手册¶ 分布式训练基本思想¶ 分布式深度学习训练通常分为两种并行化方法:数据并行,模型并行,参考下图: 在模型并行方式下,模型的层和参数将被分布在多个节点上,模型在一个mini-batc ...

  2. 正则语法完全正则表达式手册_语法格式重点

    20211202 https://blog.csdn.net/lc11535/article/details/103266263 该表达式打开re.U(re.UNICODE)标志. python –& ...

  3. CUDA C++编程手册(总论)

    CUDA C++编程手册(总论) CUDA C++ Programming Guide The programming guide to the CUDA model and interface. C ...

  4. html iso标准文档,HTML ISO-8859-1 参考手册

    # HTML ISO-8859-1 参考手册 HTML 4.01 支持 ISO 8859-1 (Latin-1) 字符集. ISO-8859-1 的较低部分(从 1 到 127 之间的代码)是最初的 ...

  5. 最好的程序界面就是用户无需去阅读操作手册就知道该如何使用的界面

    最好的程序界面就是用户无需去阅读操作手册就知道该如何使用的界面. 原则 1.一致性  如果你可以在一个列表的项目上双击后能 够弹出对话框,那么应该在任何列表中双击都能弹出对话框.要有统一的字体写号.统 ...

  6. ffmpeg linux安装_ffmpeg命令中文手册

    功能 视频转换和编辑工具 示例 1.从mp4视频文件中提取音频并保存为mp3音频格式 [root@node_116 video]# ffmpeg -i video.mp4 -vn sound.mp3f ...

  7. java修炼手册3.8_Java修炼手册

    <Java修炼手册免费版>是一款专为想要自学JAVA的用户打造的全方位掌上学习软件,拥有各阶段的科学课程模块,从视频,资料,图片,演示等多种方面全面引导用户科学而快速的融入JAVA的世界中 ...

  8. android 设置setmultichoiceitems设置初始化勾选_阿里巴巴Java开发手册建议创建HashMap时设置初始化容量,但是多少合适呢?...

    集合是Java开发日常开发中经常会使用到的,而作为一种典型的K-V结构的数据结构,HashMap对于Java开发者一定不陌生. 关于HashMap,很多人都对他有一些基本的了解,比如他和hashtab ...

  9. 【radar】毫米波雷达相关资料(文献综述列表、顶会研讨会资料列表、顶会workshops资料列表、工具书、使用手册)(2)

    [radar]毫米波雷达相关资料(毫米波雷达文献综述列表.毫米波雷达顶会研讨会资料列表.毫米波雷达顶会workshops资料列表.毫米波雷达工具书.毫米波雷达使用手册)(2) Review Paper ...

最新文章

  1. 数据库原理 - 序列5 - 事务是如何实现的? - Undo Log解析
  2. arduino Pro Mini和nano​替代芯片LGT8F328P,上传报错Cannot run program解决方法
  3. PDF页眉页脚怎么设置
  4. 腾讯数据库内核团队资深架构师:TXSQL Internals @2018
  5. 剑指 Offer 34. 二叉树中和为某一值的路径【附完整可运行代码】
  6. arraylist转int数组_LeetCode 1389. 按既定顺序创建目标数组
  7. python isalpha函数用法_python中string模块各属性以及函数的用法
  8. linux用户权限简介,Linux用户及权限管理
  9. 动态规划 —— 背包问题 P07 —— 有依赖背包
  10. php curl 发送post请求带参数
  11. python list排序方法_python中List的sort方法指南
  12. 团队项目第一阶段冲刺站立会议05
  13. vue前端项目的结构以及组成部分
  14. Unity 制作艺术字 BMFont
  15. 清华大学c语言程序设计课件,c语言清华大学课件
  16. 手机html图片自适应屏幕大小,手机端 图片自适应屏幕尺寸
  17. 最大似然估计和最小二乘法 含代码
  18. Java ques: java.sql.SQLException: Can not issue data manipulation statements with executeQuery().
  19. Linux可以打开cdr文件吗,CDR是什么格式
  20. 如何用列表解析式生成 2个小数位 的 python 列表

热门文章

  1. http响应最大时长 nginx_请问一下该如何用nginx 设置响应时间?
  2. LFS(the Log-structured File System)系统详解
  3. 在编写了一个c语言源程序c001.c,C习题及答案
  4. 阿里----OSS对象存储服务
  5. Chatbot-1-笔记
  6. php internetshortcut,shortcut功能
  7. 记录一次H3C交换机的配置
  8. 招行股东会通过收购永隆银行议案
  9. P2P之UDP穿透NAT的原理与实现(附源代码)
  10. 设计思维——科学提升创造力的方法