精华内容
下载资源
问答
  • 叉叉助手小精灵版

    2019-04-05 14:04:24
    叉叉小精灵是叉叉脚本为开发者提供的独立应用加密打包服务,自定义icon和应用名称,制作专属开发者自己的脚本应用APP
  • 之前一直有朋友在咨询我,学习按键精灵需要多久,需要一个什么样子的基础,其实按键精灵安卓写法并不难,只要死记硬背一些相关命令词汇,和逻辑关系,差不多就可以自己动手写引流脚本了!网络上面有不少此类相关的...

    a34ef2b3345f22fc48fd7679652026a9.png

    之前一直有朋友在咨询我,学习按键精灵需要多久,需要一个什么样子的基础,其实按键精灵安卓写法并不难,只要死记硬背一些相关命令词汇,和逻辑关系,差不多就可以自己动手写引流脚本了!

    网络上面有不少此类相关的课程,有几十个G的,有一小时学会按键精灵安卓写法的,我在录制课程之前,都已经购买观看了,说真的,如果你只是单纯的想学习怎么写引流脚本,和基本的模拟手工操作,如果看哪些课程的话,我估计你会晕,我个人看起来都有点晕,逻辑并不是很清晰,课程当中用到的也只是最基础的几个按键精灵命令! 

    不懂英语,不懂Andrid基础,不懂java基础,怎么才能快速学习安卓按键精灵去编写出适用与自己的脚本昵?不用担心,这些都交给我们来! 只要你跟着练习我们保证让你学会,终身受益!相信这将会对你的工作、生活和学习带来极大的帮助。学得会,能上手!零基础课程。

    这是一堂让大家更好的去了解,什么的按键精灵引流脚本,什么的按键精灵,包括我们在写按键精灵引流脚本过程中需要用到的辅助功能和环境配置,了解基础环境配置,是我们学习过程当中不可缺少的课程!好了,今天就跟着二狗我一起来学习本期的这堂课吧!

    本期高清教程视频我会放到下面两个QQ群文件里面。

    感谢大家关注蜗牛云课堂公众号~

    飞鸟社群①群:931526284(付费QQ群)

    已经开通付费入群模式,自动扣费无需联系群主,群费29.8元

    付费群内有高清视频教程下载,还有一些教程源码

    群主和管理会帮您解答按键精灵安卓版相关问题和其他网赚项目问题,并支持项目对接等等!

    飞鸟社区1群:931526284(付费QQ群)

    飞鸟社群2群:801478590(免费群)

    01.             按键精灵助手

    02.             http://m.anjian.com/

    03.             按键精灵环境配置

    04.             雷电模拟器

    05.             http://www.ldmnq.com/ldy/baidu.html

    06.             雷电模拟器环境配置

    展开全文
  • 可以一次编辑多个精灵。 准备使用调色板,或制作自己的调色板。 精灵由图层和框架组成。 平铺绘图模式,可用于绘制图案和纹理。 像素精确工具,例如填充轮廓,多边形,阴影模式等。 精灵和动画支持几种文件...
  • 叉叉开发文档

    千次阅读 2019-11-02 12:58:00
    叉叉脚本开发手册 叉叉脚本 引擎版本:1.9.314 叉叉脚本开发手册 前言 开发文件夹路径 本地脚本存放路径 公共文件夹路径 截图存放路径 日志文件路径 脚本开发实用技巧(持续更新) 叉叉...

    @xxzhushou 2019-04-03 14:50 字数 66259 阅读 400563

    叉叉脚本开发手册

    叉叉脚本

    引擎版本:1.9.314

     

     

    前言

      叉叉脚本使用 Lua 语言进行编写,支持Lua的所有语法与基本函数,配合叉叉脚本特有的函数命令,实现找图、找色、触摸等高级功能。
      编写脚本前请先学习 lua 的基本语法。
      Lua官方手册:http://www.lua.org/manual/5.1/
      Lua中文开发手册:http://book.luaer.cn/
      叉叉开发者平台:http://dev.xxzhushou.cn/
    特别注意:

    1.由于安全性方面的考虑,以下函数在叉叉脚本中不予以支持:
    debub库所有函数、io.tmpfile、io.popen、os.execute、os.exit、os.remove、os.rename、os.tmpname
    2.io.open的用法比较特殊,参数中不能填写具体路径,只能是文件名,比如:
    io.open('aa.txt') 是正确的,io.open('../../../aa.txt')则运行会报错。
    另外,io库支持公共文件夹,比如io.input('[public]xx.txt'),就会在[tengine]/public下读取xx.txt这个文件。

    脚本文件格式支持说明:

     叉叉助手/IPA精灵开发助手说明生成方式
    xsp0不支持支持主要用于开发调试,没有加密处理IDE生成或者打包工具
    xsp1支持支持主要用于不开源的脚本免费分享,有加密处理上传后台直接加密
    xsp2支持不支持在国内开发者平台上架后,下载到叉叉助手,动态加密在用户下载时生成
    • xsp0 文件包复制到移动设备对应开发助手脚本存放目录中,进入开发助手客户端“本地脚本”列表即可运行保存好的脚本
    • xsp1 文件包复制到移动设备对应叉叉助手存放目录中,进入叉叉客户端“我的”tab启动应用,打开悬浮窗即可运行保存好的脚本

     *iOS可使用ifunbox等工具将脚本文件复制到设备

    开发文件夹路径

    本地脚本存放路径

    • 开发助手
      Android:/sdcard/xsp/
      iOS(开发助手版本>= 1.0.10):/var/mobile/Library/XXIDEHelper/xsp/
      iOS(开发助手版本<1.0.10):/Library/ApplicationSupport/XXIDEHelper/xsp/

    • 叉叉助手
      Android:/sdcard/com.xxAssistant/script/
      iOS(叉叉版本>=2.5.0): /var/mobile/Library/XXAssistant/Lua/LocalLuas/
      iOS(叉叉版本<2.5.0): /Library/ApplicationSupport/XXAssistant/Lua/LocalLuas/

    • IPA精灵
      IPA精灵:应用文件夹/Documents/Lua/LocalLuas

    公共文件夹路径

    • 开发助手
      Android(引擎版本>=1.7.2):/data/data/com.xxscript.idehelper/tengine/public
      Android(引擎版本<1.7.2):/data/data/com.xxscript.idehelper/cache/tengine/public
      iOS(开发助手版本>=1.0.10):/var/mobile/Library/XXIDEHelper/xsp/Temp/public
      iOS(开发助手版本<1.0.10) :/Library/ApplicationSupport/XXIDEHelper/xsp/Temp/public

    • 叉叉助手
      Android(引擎版本>=1.7.2):/data/data/com.xxAssistant/tengine/public
      Android(引擎版本<1.7.2):/data/data/com.xxAssistant/cache/tengine/public
      iOS(叉叉版本>=2.5.0): /var/mobile/Library/XXAssistant/Lua/Luas/Temp/public
      iOS(叉叉版本<2.5.0): /Library/ApplicationSupport/XXAssistant/Lua/Luas/Temp/public

    • IPA精灵
      IPA精灵:应用文件夹/Documents/Lua/Luas/Temp/public

    截图存放路径

    • 开发助手
      Android(引擎版本>=1.7.2):/data/data/com.xxscript.idehelper/tengine/public
      Android(引擎版本<1.7.2):/data/data/com.xxscript.idehelper/cache/tengine/public
      iOS(开发助手版本>=1.0.10):/var/mobile/Library/XXIDEHelper/xsp/Temp
      iOS(开发助手<1.0.10) :/Library/ApplicationSupport/XXIDEHelper/xsp/Temp

    • 叉叉助手
      Android(引擎版本>=1.7.2):/data/data/com.xxAssistant/tengine/public
      Android(引擎版本<1.7.2):/data/data/com.xxAssistant/cache/tengine/public
      iOS(叉叉版本>=2.5.0):/var/mobile/Library/XXAssistant/Lua/Luas/Temp
      iOS(叉叉版本<2.5.0):/Library/Application Support/XXAssistant/Lua/Luas/Temp

    • IPA精灵
      IPA精灵:应用文件夹/Documents/Lua/Luas/Temp/

    日志文件路径

    • 开发助手
      Android:/sdcard/com.xxscript.idehelper/tengine/log/user/脚本名.log
      iOS:/tmp/user/脚本名.log

    • 叉叉助手
      Android:/sdcard/com.xxAssistant/tengine/log/user/脚本id.log
      Android免Root:/sdcard/com.noroot/tengine/log/user/脚本id.log
      iOS:/tmp/user/脚本id.log

    • 叉叉小精灵
      Android:/sdcard/小精灵包名/tengine/log/user/脚本id.log

    • IPA精灵
      IPA精灵:应用文件夹/Document/Temp/脚本id.log
      IPA精灵(开发版):应用文件夹/Document/Temp/脚本名.log

    脚本开发实用技巧(持续更新)

    戳这里:https://www.zybuluo.com/xxzhushou/note/726742

    叉叉脚本定制版发布指引

    戳这里:https://www.zybuluo.com/xxzhushou/note/755911

    iOS免越狱接口说明:适配免越狱引擎必读

    API接口支持状态说明
    isPrivateMode新增返回值1、0;1-越狱/root环境;0-免越狱/免root环境;
    runApp 运行应用不支持无效,返回非0
    closeApp 关闭应用不支持无效,无返回值
    setWifiEnable 设置无线局域网开关不支持无效,返回false
    setAirplaneMode 设置飞行模式开关不支持无效,返回false
    setBTEnable 设置蓝牙开关不支持无效,返回false
    lockDevice 锁定设备不支持无效,无返回值
    unlockDevice 解锁设备不支持无效,无返回值
    deviceIsLock 设备锁定状态不支持无效,返回0-回未锁定
    pressHomeKey 模拟主屏幕按键不支持无效,无返回值
    doublePressHomeKey 双击HOME键不支持无效,无返回值
    appIsRunning 检测应用是否运行支持,有修改参数包名是该游戏返回1-目标应用运行中,否则返回0-目标应用未运行
    isFrontApp 判断是否为前台应用支持,有修改参数包名是该游戏返回1-在前台,否则返回0-不在前台
    frontAppName 获取前台应用识别ID支持,有修改只能返回重打包游戏的包名
    其他接口支持 

    函数:init 初始化

    函数功能:脚本使用触摸函数前必须调用,以指定应用程序以及坐标系
    函数语法:
      init(appid, rotate)

    参数说明:

    参数类型说明
    appid文本型目标程序的应用ID,当填写"0"时,自动使用当前运行的应用
    rotate整数型屏幕方向,0 - 竖屏, 1 - Home键在右边, 2 - Home键在左边

    返回值:无

    脚本实例:

     
    1. init("com.apple.Music", 0); --以应用 "com.apple.Music" 竖屏初始化
    2. init("0", 1); --以当前应用 Home 键在右初始化

    函数:touchDown 触摸按下

    函数功能:发送触摸事件
    函数语法:
      touchDown(index, x, y)

    参数说明:

    参数类型说明
    index整数型手指序号,用于多点触控中标记多只手指,分别控制它们的移动
    x,y整数型屏幕坐标

    返回值:无

    脚本实例:

    • 点击和抬起
     
    1. touchDown(1, 150, 150) --ID为1的手指在坐标(150,150)处按下
    2. mSleep(200) --延时200毫秒
    3. touchUp(1, 150, 150) --ID为1的手指抬起
    • 封装点击函数
     
    1. function tap(x, y)
    2. touchDown(0, x, y);
    3. mSleep(200);
    4. touchUp(0, x, y);
    5. end
    6. tap(100,100); --调用:点击坐标为100,100的点

    注意事项:

    需要注意的是在使用 touchDown、touchUp 函数时,中间一定要插入一定的延时,建议大于 20毫秒,否则可能会出现点击无效等异常情况。

    函数:touchMove 移动

    函数功能:发送触摸事件
    函数语法:
      touchMove(index, x, y)

    参数说明:

    参数类型说明
    index整数型手指序号,用于多点触控中标记多只手指,分别控制它们的移动
    x,y整数型屏幕坐标

    返回值:无

    脚本实例:

    • 连续划动
     
    1. touchDown(1, 150, 550); --在 (150, 550) 按下
    2. for i = 0, 200, 10 do --使用for循环连续滑动
    3. touchMove(1, 150 + i, 550);
    4. mSleep(150); --延迟
    5. end
    6. touchUp(1, 150 + 200, 550); --在 (350, 550) 抬起
    • 多点触控
     
    1. touchDown(1, 100, 100); --ID为1的手指在 (100, 100) 按下
    2. touchDown(2, 300, 500); --ID为2的手指在 (300, 500) 按下
    3. mSleep(50);
    4. for i = 1, 100, 1 do --使用 for 循环使两只手指向不同方向分离
    5. touchMove(1, 200 - i, 400 - i);
    6. touchMove(2, 300 + i, 500 + i);
    7. mSleep(50);
    8. end
    9. touchUp(1, 200 - 100, 400 - 100);
    10. touchUp(2, 300 + 100, 500 + 100); --分别抬起2只手指

    注意事项:

    需要注意的是在使用 touchDown、touchUp 函数时,中间一定要插入一定的延时,建议大于 20毫秒,否则可能会出现点击无效等异常情况。

    函数:touchUp 触摸抬起

    函数功能:发送触摸事件
    函数语法:
      touchUp(index, x, y)

    参数说明:

    参数类型说明
    index整数型手指序号,用于多点触控中标记多只手指,分别控制它们的移动
    x,y整数型屏幕坐标

    返回值:无

    脚本实例:

    • 连续划动
     
    1. touchDown(1, 150, 550); --在 (150, 550) 按下
    2. for i = 0, 200, 10 do --使用for循环连续滑动
    3. touchMove(1, 150 + i, 550);
    4. mSleep(150); --延迟
    5. end
    6. touchUp(1, 150 + 200, 550); --在 (350, 550) 抬起
    • 多点触控
     
    1. touchDown(1, 100, 100); --ID为1的手指在 (100, 100) 按下
    2. touchDown(2, 300, 500); --ID为2的手指在 (300, 500) 按下
    3. mSleep(50);
    4. for i = 1, 100, 1 do --使用 for 循环使两只手指向不同方向分离
    5. touchMove(1, 200 - i, 400 - i);
    6. touchMove(2, 300 + i, 500 + i);
    7. mSleep(50);
    8. end
    9. touchUp(1, 200 - 100, 400 - 100);
    10. touchUp(2, 300 + 100, 500 + 100); --分别抬起2只手指

    注意事项:

    需要注意的是在使用 touchDown、touchUp 函数时,中间一定要插入一定的延时,建议大于 20毫秒,否则可能会出现点击无效等异常情况。

    函数:catchTouchPoint 获取用户点击坐标

    函数功能:调用该函数后,将等待用户完成一次或多次屏幕点击,并返回点击的坐标
    函数语法:
      results = catchTouchPoint(touchCount)
      x,y = catchTouchPoint()

    参数说明:

    参数类型说明
    touchCount整数型所需获取的 点/坐标 个数
    返回值类型说明
    x,y整数型单次点击时,返回该点击对应的屏幕坐标
    resultstable型当touchCount参数有效时,将返回一个包含所有点击坐标的table

    脚本实例:

    • 获取单个点击坐标
     
    1. dialog("请点击屏幕一次", 0);
    2. x,y = catchTouchPoint();
    3. mSleep(1000);
    4. dialog("x:"..x.." y:"..y, 0);
    • 获取多个点击坐标
     
    1. local results = catchTouchPoint(3);
    2. for i = 1, #results do
    3. sysLog("第"..i.."个坐标为:"..i..",x="..results[i].x..",y="..results[i].y);
    4. end

    注意事项:

    1.此函数触发后将一直等待用户完成屏幕点击,并阻止脚本继续运行。
    2.此函数获取到的坐标为竖屏坐标,横屏情况需要自行转换。
    3.此函数有较小的延迟,连续点击时,请勿点击过快。

    函数:findColor 区域多点找色(推荐使用)5-120601152328.png-0.2kB

    函数功能:在指定区域,根据颜色以及其周边点的颜色,寻找符合条件的点的坐标,支持模糊查找
    函数语法:
        x, y = findColor(
         {left, top, right, bottom},
         color0,
         degree,
         hdir,
         vdir,
         priority
        )
        
        x, y = findColor(
         {left, top, right, bottom},
         "x0|y0|color0,x1|y1|color1(|degree1),x2|y2|color2(-offset2),...",
         degree,
         hdir,
         vdir,
         priority
        )
        
        x, y = findColor(
         {left, top, right, bottom},
         {
          {x = x0, y = y0, color = color0},
          {x = x1, y = y1, color = color1, (degree = degree1)},
          {x = x2, y = y2, color = color2, (offset = offset2)},
          ...
         },
         degree,
         hdir,
         vdir,
         priority
        )

    参数说明:

    参数类型说明
    left, top整数型[必填]寻找区域左上角顶点屏幕坐标
    right, bottom整数型[必填]寻找区域右下角顶点屏幕坐标
    x0,y0整数型[必填]起始点坐标值,填写0,0时使用相对坐标体系,填写非0坐标则根据所填绝对坐标换算
    color0整数型[必填]起始点颜色的十六进制颜色值
    x1,y1整数型[选填]偏移位置的坐标值
    color1整数型[选填]偏移位置需要匹配颜色的十六进制颜色值
    degree1整数型[选填]偏移位置找色精度,范围:1 ~ 100,当是100时为完全匹配
    offset1整数型[选填]偏移位置找色偏色值,十六进制颜色值,当是000000时为完全匹配
    degree整数型[必填]全局找色精度,范围:1 ~ 100,当是100时为完全匹配
    hdir整数型[选填]水平搜索方向,0表示从左到右,1表示从右到左,默认为0
    vdir整数型[选填]垂直搜索方向,0表示从上到下,1表示从下到上,默认为0
    priority整数型[选填]搜索优先级,0表示水平优先,1表示垂直优先,默认为0

    说明:
    1.起始点坐标值填写0,0时,偏移位置坐标值使用相对坐标;填写为非0,0的坐标时,则认为偏移位置坐标为绝对坐标,找色时,将根据填写的绝对坐标换算出的相对坐标进行寻找。
    2.偏移位置颜色的偏色值或精度可任意选用,同时填写了偏色值和精度时,将以偏色为准,忽略精度值。
    3.个别偏移位置颜色偏色值或精度优先于全局找色精度,全局找色精度对未指定偏色或精度的颜色有效。

    返回值类型说明
    x,y整数型找到的点坐标,如未找到则返回 -1,-1

    脚本实例:

    • 精确寻找指定单色的坐标
     
    1. x, y = findColor({50, 50, 300, 300},0x112233)
    2. if x ~= -1 and y ~= -1 then --如指定区域找到符合条件的某点
    3. touchDown(1, x, y); --点击该点
    4. mSleep(50)
    5. touchUp(1, x, y);
    6. else --如找不到符合条件的点
    7. dialog("没找到你要的坐标呢",0);
    8. end

    使用以上方法找色时,常常会因为屏幕上有大量符合指定颜色的点而不能找到需要的坐标。该函数通过在寻找到一个符合指定颜色color的坐标后,进一步确认其周边点坐标的方式,来确定准确目标。例如,现在我们在图像上找到了我们需要的一个按钮,这个按钮的样式是不变的,但是它的整体位置却会在整个屏幕上变化,现在我们想要在脚本运行时得到其坐标。

    首先确定一个参照点:
    颜色为 0x181F85,坐标为 (268, 802),下表序号1。
    记录下来,继续寻找周边的几个参照点,以及与第一个参照点的相对坐标,分别为下表序号2~4:

    现在我们找到了需要的所有参照点:

    序号颜色坐标相对坐标
    10x181F85(268, 802)(0, 0)
    20x00BBFE(297, 803)(29, 1)
    30x0B6BBE(371, 798)(103, -4)
    40x150972(333, 811)(65, 9)

    应用上述坐标写成多点找色脚本(以下4种任选1种):

    • 相对坐标的写法:
     
    1. x, y = findColor(
    2. {0, 0, 639, 959},
    3. "0|0|0x181F85,29|1|0x00BBFE|90,103|-4|0x0B6BBE-0x050505,65|9|0x150972")
    4.  
    5. x, y = findColor(
    6. {0, 0, 639, 959},
    7. {
    8. {x = 0, y = 0, color = 0x181F85},
    9. {x = 29, y = 1, color = 0x00BBFE, degree = 90},
    10. {x = 103, y = -4, color = 0x0B6BBE, offset = 0x050505},
    11. {x = 65, y = 9, color = 0x150972}
    12. })
    • 绝对坐标的写法:
     
    1. x, y = findColor(
    2. {0, 0, 639, 959},
    3. "268|802|0x181F85,297|803|0x00BBFE|90,371|798|0x0B6BBE-050505,333|811|0x150972")
    4.  
    5. x, y = findColor(
    6. {0, 0, 639, 959},
    7. {
    8. {x = 268, y = 802, color = 0x181F85},
    9. {x = 297, y = 803 color = 0x00BBFE, degree = 90},
    10. {x = 371, y = 798 color = 0x0B6BBE, offset = 0x050505},
    11. {x = 333, y = 811 color = 0x150972}
    12. })

    新旧多点找色API对比:

     
    1. findColorInRegionFuzzy = function(tcolor, degree, x1, y1, x2, y2, hdir, vdir)
    2. return findColor(
    3. {x1, y1, x2, y2},
    4. tcolor,
    5. degree,
    6. hdir or 0,
    7. vdir or 0
    8. )
    9. end
    10.  
    11. findMultiColorInRegionFuzzy = function(tcolor, posandcolors, degree, x1, y1, x2, y2, hdir, vdir)
    12. posandcolors = string.format("0|0|0x%x,%s", tcolor, posandcolors)
    13. return findColor(
    14. {x1, y1, x2, y2},
    15. posandcolors,
    16. degree,
    17. hdir or 0,
    18. vdir or 0
    19. )
    20. end
    21.  
    22. findMultiColorInRegionFuzzy2 = function(tcolor, posandcolors, degree, x1, y1, x2, y2, hdir, vdir)
    23. table.insert(posandcolors, 1, {x = 0, y = 0, color = tcolor})
    24. return findColor(
    25. {x1, y1, x2, y2},
    26. posandcolors,
    27. degree,
    28. hdir or 0,
    29. vdir or 0
    30. )
    31. end

    关于搜索方向:

    hdirvdirpriority区域搜索路径
    000左上角  右上角  左下角  右下角
    001左上角  左下角  右上角  右下角
    010左下角  右下角  左上角  右上角
    011左下角  左上角  右下角  右上角
    100右上角  左上角  右下角  左下角
    101右上角  右下角  左上角  左下角
    110右下角  左下角  右上角  左上角
    111右下角  右上角  左下角  左上角

    注意事项:

    1.未找到则返回 (-1, -1) ,所以找到时 x, y 均不等于 -1,~= 为不等于操作符,是 Lua 基本语法, 属于逻辑控制。
    2.该代码应用过程中,建议使用"保持屏幕"优化找色速度。
    3.颜色值的十六进制文本中,其顺序为RGB。
    4.相对坐标为偏移位置坐标相对于第一个点的坐标,即用这个点的横坐标、纵坐标分别减去第一个点的横坐标、纵坐标,可以为负数。
    5.使用此函数时精度参数设置过低或允许的偏色多大,会导致性能大幅下降。
    6.支持引擎版本:1.8.30或更新

    函数:findColors 高级区域多点找色(推荐使用)5-120601152328.png-0.2kB

    函数功能:在指定区域,根据颜色以及其周边点的颜色,寻找所有符合条件的点的坐标,支持模糊查找
    函数语法:
      point = findColors(
       {left, top, right, bottom},
       color0,
       degree,
       hdir,
       vdir,
       priority,
      )
      
      point = findColors(
       {left, top, right, bottom},
       "x0|y0|color0,x1|y1|color1(|degree1),x2|y2|color2(-offset2),...",
       degree,
       hdir,
       vdir,
       priority,
      )
      
      point = findColors(
       {left, top, right, bottom},
       {
       {x = x0, y = y0, color = color0},
       {x = x1, y = y1 color = color1, (degree = degree1)},
       {x = x2, y = y2 color = color2, (offset = offset2)},
       ...
       },
       degree,
       hdir,
       vdir,
       priority,
      )

    参数说明:

    参数类型说明
    left, top整数型[必填]寻找区域左上角顶点屏幕坐标
    right, bottom整数型[必填]寻找区域右下角顶点屏幕坐标
    x0,y0整数型[必填]起始点坐标值,填写0,0时使用相对坐标体系,填写非0坐标则根据所填绝对坐标换算
    color0整数型[必填]起始点颜色的十六进制颜色值
    x1,y1整数型[选填]偏移位置的坐标值
    color1整数型[选填]偏移位置需要匹配颜色的十六进制颜色值
    degree1整数型[选填]偏移位置找色精度,范围:1 ~ 100,当是100时为完全匹配
    offset1整数型[选填]偏移位置找色偏色值,十六进制颜色值,当是000000时为完全匹配
    degree整数型[必填]全局找色精度,范围:1 ~ 100,当是100时为完全匹配
    hdir整数型[选填]水平搜索方向,0表示从左到右,1表示从右到左,默认为0
    vdir整数型[选填]垂直搜索方向,0表示从上到下,1表示从下到上,默认为0
    priority整数型[选填]搜索优先级,0表示水平优先,1表示垂直优先,默认为0

    说明:
    1.起始点坐标值填写0,0时,偏移位置坐标值使用相对坐标;填写为非0,0的坐标时,则认为偏移位置坐标为绝对坐标,找色时,将根据填写的绝对坐标换算出的相对坐标进行寻找。
    2.偏移位置颜色的偏色值或精度可任意选用,同时填写了偏色值和精度时,将以偏色为准,忽略精度值。
    3.个别偏移位置颜色偏色值或精度优先于全局找色精度,全局找色精度对未指定偏色或精度的颜色有效。

    返回值类型说明
    pointtable类型以 table 形式返回所有符合条件的参照点的坐标,如未找到则返回的table为空

    返回的 table 为key-value的形式,如下:
    point = {
     {x = 100,y = 110},
     {x = 200,y = 210},
     {x = 300,y = 310},
     ...
    }

    脚本实例:

     
    1. point = findColors(
    2. {0, 0, 639, 959},
    3. 0x181F85)
    4. if #point ~= 0 then --如果找到符合条件的点
    5. for var = 1, #point do
    6. sysLog(point[var].x..":"..point[var].y)
    7. end
    8. end
    9.  
    10. point = findColors(
    11. {0, 0, 639, 959},
    12. "0|0|0x181F85,29|1|0x00BBFE|90,103|-4|0x0B6BBE-050505,65|9|0x150972")
    13. if #point ~= 0 then --如果找到符合条件的点
    14. for var = 1, #point do
    15. sysLog(point[var].x..":"..point[var].y)
    16. end
    17. end
    • 相对坐标的写法:
     
    1. point = findColors(
    2. {0, 0, 639, 959},
    3. {
    4. {x = 0, y = 0, color = 0x181F85},
    5. {x = 29, y = 1, color = 0x00BBFE, degree = 90},
    6. {x = 103, y = -4, color = 0x0B6BBE, offset = 0x050505},
    7. {x = 65, y = 9, color = 0x150972}
    8. })
    • 绝对坐标的写法:
     
    1. point = findColors(
    2. {0, 0, 639, 959},
    3. "268|802|0x181F85,297|803|0x00BBFE|90,371|798|0x0B6BBE-050505,333|811|0x150972")
    4.  
    5. point = findColors(
    6. {0, 0, 639, 959},
    7. {
    8. {x = 268, y = 802, color = 0x181F85},
    9. {x = 297, y = 803, color = 0x00BBFE, degree = 90},
    10. {x = 371, y = 798, color = 0x0B6BBE, offset = 0x050505},
    11. {x = 333, y = 811, color = 0x150972}
    12. })

    新旧高级多点区域找色API对比:

     
    1. findMultiColorInRegionFuzzyExt = function(tcolor, posandcolors, degree, x1, y1, x2, y2, hdir, vdir)
    2. posandcolors = string.format("0|0|0x%x,%s", tcolor, posandcolors)
    3. return findColors(
    4. {x1, y1, x2, y2},
    5. posandcolors,
    6. degree,
    7. hdir or 0,
    8. vdir or 0
    9. )
    10. end
    11.  
    12. findMultiColorInRegionFuzzyExt2 = function(tcolor, posandcolors, degree, x1, y1, x2, y2, hdir, vdir)
    13. table.insert(posandcolors, 1, {x = 0, y = 0, color = tcolor})
    14. return findColors(
    15. {x1, y1, x2, y2},
    16. posandcolors,
    17. degree,
    18. hdir or 0,
    19. vdir or 0
    20. )
    21. end

    注意事项:

    1.高级区域多点找色函数目前最多支持返回99个。
    2.支持引擎版本:1.8.30或更新

    函数:findColorInRegionFuzzy 模糊区域找色(推荐使用findColor代替)

    函数功能:在指定区域中,寻找符合指定颜色的坐标,模糊查找。(请使用findColor函数代替)
    函数语法:
      x, y = findColorInRegionFuzzy(color, degree, x1, y1, x2, y2,hdir,vdir)

    参数说明:

    参数类型说明
    color整数型将要找的十六进制颜色值
    degree整数型寻找精度,范围:1 ~ 100,当是100时为完全匹配
    x1,y1整数型欲寻找的区域左上角顶点屏幕坐标
    x2,y2整数型欲寻找的区域右下角顶点屏幕坐标
    hdir整数型水平搜索方向,0表示从左到右,1表示从右到左,默认为0
    vdir整数型垂直搜索方向,0表示从上到下,1表示从下到上,默认为0
    返回值类型说明
    x,y整数型找到的点坐标,如未找到则返回 -1,-1

    脚本实例:

    • 精确寻找指定颜色的坐标
     
    1. x, y = findColorInRegionFuzzy(0x112233, 100, 50, 50, 300, 300);
    2. if x ~= -1 and y ~= -1 then --如指定区域找到符合条件的某点
    3. touchDown(1, x, y); --点击该点
    4. mSleep(50)
    5. touchUp(1, x, y);
    6. else --如找不到符合条件的点
    7. dialog("没找到你要的坐标呢",0);
    8. end
    • 模糊查找接近指定颜色的坐标
     
    1. for deg = 100, 70, -1 do --使用 for 循环不断降低精确度
    2. x, y = findColorInRegionFuzzy(0xffffff, deg, 50, 50, 300, 300);
    3. if x ~= -1 and y ~= -1 then --如指定区域找到符合条件的某点
    4. touchDown(1, x, y); --点击该点
    5. mSleep(50)
    6. touchUp(1, x, y);
    7. break; --跳出循环
    8. end
    9. end
    10. dialog("噢天哪!还是没找到",0);

    注意事项:

    1.未找到则返回 (-1, -1) ,所以找到时 x, y 均不等于 -1,~= 为不等于操作符,是 Lua 基本语法, 属于逻辑控制。
    2.该代码应用过程中,建议使用"保持屏幕"优化找色速度。

    函数:findMultiColorInRegionFuzzy 区域多点找色(推荐使用findColor代替)

    函数功能:在指定区域,根据颜色以及其周边点的颜色,寻找符合条件的点的坐标,支持模糊查找。(请使用findColor函数代替)
    函数语法:
      x, y = findMultiColorInRegionFuzzy(color, posandcolor, degree, x1, y1, x2, y2,hdir,vdir)

    参数说明:

    参数类型说明
    color整型欲寻找的参照点颜色
    posandcolor文本型周边点颜色参数
    degree整数型寻找精度,范围:1 ~ 100,当是100时为完全匹配
    x1, y1整数型欲寻找的区域左上角顶点屏幕坐标
    x2,y2整数型欲寻找的区域右下角顶点屏幕坐标
    hdir整数型水平搜索方向,0表示从左到右,1表示从右到左,默认为0
    vdir整数型垂直搜索方向,0表示从上到下,1表示从下到上,默认为0
    返回值类型说明
    x, y整数型返回符合条件的参照点的坐标,如未找到则返回 -1,-1

    脚本实例:
    使用“区域模糊找色”函数时,常常会因为屏幕上有大量符合指定颜色的点而不能找到需要的坐标。该函数通过在寻找到一个符合指定颜色color的坐标后,进一步确认其周边点坐标的方式,来确定准确目标。例如,现在我们在图像上找到了我们需要的一个按钮,这个按钮的样式是不变的,但是它的整体位置却会在整个屏幕上变化,现在我们想要在脚本运行时得到其坐标。

    首先确定一个参照点:
    颜色为 0x181F85,坐标为 (268, 802),下表序号1。
    记录下来,继续寻找周边的几个参照点,以及与第一个参照点的相对坐标,分别为下表序号2~4:

    现在我们找到了需要的所有参照点:

    序号颜色坐标相对坐标
    10x181F85(268, 802)(0, 0)
    20x00BBFE(297, 803)(29, 1)
    30x0B6BBE(371, 798)(103, -4)
    40x150972(333, 811)(65, 9)

    应用上述坐标写成多点找色脚本:

    • 多点找色
     
    1. x, y = findMultiColorInRegionFuzzy(0x181F85, "29|1|0x00BBFE,103|-4|0x0B6BBE,65|9|0x150972", 100, 0, 0, 639, 959);

    注意事项:

    1.posandcolor 参数中的坐标为相对坐标。
    2.颜色值的十六进制文本中,其顺序为RGB。
    3.相对于第一个点的坐标,即用这个点的横坐标、纵坐标分别减去第一个点的横坐标、纵坐标,可以为负数。
    4.使用此函数时精度参数设置过低,会导致性能大幅下降。

    函数:findMultiColorInRegionFuzzy2 区域多点找色(推荐使用findColor代替)

    函数功能:在指定区域,根据颜色以及其周边点的颜色,寻找符合条件的点的坐标,支持模糊查找。(请使用findColor函数代替)
    函数语法:
      x, y = findMultiColorInRegionFuzzy2(color, {{posandcolor}}, degree, x1, y1, x2, y2,hdir,vdir)

    参数说明:

    参数类型说明
    color整型欲寻找的参照点颜色
    posandcolortable型周边点颜色参数
    degree整数型寻找精度,范围:1 ~ 100,当是100时为完全匹配
    x1, y1整数型欲寻找的区域左上角顶点屏幕坐标
    x2,y2整数型欲寻找的区域右下角顶点屏幕坐标
    hdir整数型水平搜索方向,0表示从左到右,1表示从右到左,默认为0
    vdir整数型垂直搜索方向,0表示从上到下,1表示从下到上,默认为0
    返回值类型说明
    x, y整数型返回符合条件的参照点的坐标,如未找到则返回 -1,-1

    脚本实例:
    该函数是区域多点找色函数findMultiColorInRegionFuzzy的增强版,将周边参照点的颜色及相对坐标写成table的形式,更方便动态调整。

     
    1. x, y = findMultiColorInRegionFuzzy2(0x181F85, {{x=29, y=1, color=0x00BBFE},{x=103,y=- 4,color=0x0B6BBE},{x=65,y=9,color=0x150972}}, 100, 0, 0, 639, 959)

    函数:findMultiColorInRegionFuzzyExt 高级区域多点找色(推荐使用findColors代替)

    函数功能:在指定区域,根据颜色以及其周边点的颜色,寻找所有符合条件的点的坐标,支持模糊查找
    函数语法:
      point = findMultiColorInRegionFuzzyExt(color, posandcolor, degree, x1, y1, x2, y2,hdir,vdir)

    参数说明:

    参数类型说明
    color整型欲寻找的参照点颜色
    posandcolor文本型周边点颜色参数
    degree整数型寻找精度,范围:1 ~ 100,当是100时为完全匹配
    x1, y1整数型欲寻找的区域左上角顶点屏幕坐标
    x2,y2整数型欲寻找的区域右下角顶点屏幕坐标
    hdir整数型水平搜索方向,0表示从左到右,1表示从右到左,默认为0
    vdir整数型垂直搜索方向,0表示从上到下,1表示从下到上,默认为0
    返回值类型说明
    pointtable类型以 table 形式返回所有符合条件的参照点的坐标,如未找到则返回的table为空

    返回的 table 为key-value的形式,如下:
    table = {
    {x = 100,y = 110},
    {x = 200,y = 210},
    {x = 300,y = 310},
    ...
    }

    脚本实例:

     
    1. point = findMultiColorInRegionFuzzyExt(0xcf0000,"-37|3|0x942814,-38|20|0xeba62d,1|54|0xf2b054,28|22|0x8a5707", 90, 97, 220, 903, 701)
    2. if #point ~= 0 then --如果找到符合条件的点
    3. for var = 1,#point do
    4. sysLog(point[var].x..":"..point[var].y)
    5. end
    6. end

    注意事项:

    1.高级区域多点找色函数目前最多支持返回99个点。

    函数:findMultiColorInRegionFuzzyExt2 高级区域多点找色(推荐使用findColors代替)

    函数功能:在指定区域,根据颜色以及其周边点的颜色,寻找所有符合条件的点的坐标,支持模糊查找
    函数语法:
      point = findMultiColorInRegionFuzzyExt2(color, {{posandcolor}}, degree, x1, y1, x2, y2,hdir,vdir)

    参数说明:

    参数类型说明
    color整型欲寻找的参照点颜色
    posandcolortable型周边点颜色参数
    degree整数型寻找精度,范围:1 ~ 100,当是100时为完全匹配
    x1, y1整数型欲寻找的区域左上角顶点屏幕坐标
    x2,y2整数型欲寻找的区域右下角顶点屏幕坐标
    hdir整数型水平搜索方向,0表示从左到右,1表示从右到左,默认为0
    vdir整数型垂直搜索方向,0表示从上到下,1表示从下到上,默认为0
    返回值类型说明
    pointtable类型以 table 形式返回所有符合条件的参照点的坐标,如未找到则返回的table为空

    返回的 table 为为key-value的形式,如下:
    table = {
    {x = 100,y = 110},
    {x = 200,y = 210},
    {x = 300,y = 310},
    ...
    }

    脚本实例:
    该函数是高级区域多点找色函数findMultiColorInRegionFuzzyExt的增强版,将周边参照点的颜色及相对坐标写成table的形式,更方便动态调整。

     
    1. point = findMultiColorInRegionFuzzyExt2(0xcf0000, {{x=-37,y=3,color=0x942814},{x=-38,y=20,color=0xeba62d},{x=1,y=54,color=0xf2b054},{x=28,y=22,color=0x8a5707}}, 90, 97, 220, 903, 701)
    2. if #point ~= 0 then
    3. for var = 1,#point do
    4. sysLog(point[var].x..":"..point[var].y)
    5. end
    6. end

    注意事项:

    1.高级区域多点找色函数目前最多支持返回99个点。

    函数:getColor 获取屏幕某点颜色值

    函数功能:获取屏幕某点颜色值
    函数语法:
      color = getColor(x, y)

    参数说明:

    参数类型说明
    x,y整数型将获取颜色值的屏幕坐标
    返回值类型说明
    color整数型该点的十进制颜色值RGB

    脚本实例:

    • 如果某点符合某颜色则点击
     
    1. if getColor(100, 100) == 0xffffff then
    2. touchDown(1, 100, 100);
    3. touchUp(1, 100, 100);
    4. end

    注意事项:

    getColor函数获得的颜色值十六进制文本中,实际顺序为RGB

    函数:getColorRGB 获取颜色RGB值

    函数功能:获取屏幕某点颜色值R,G,B 值。
    函数语法:
      color_r, color_g, color_b = getColorRGB(x, y)

    参数说明:

    参数类型说明
    x,y整数型将获取颜色值的屏幕坐标
    返回值类型说明
    color_r, color_g, color_b整数型该点颜色的RGB值

    脚本实例:

    • 判断某点的颜色与某颜色相似
     
    1. r,g,b = getColorRGB(100,100); --获取该点的R,G,B值
    2. if r > 200 and b < 150 then --判断颜色强度
    3. touchDown(1,100,100);
    4. touchUp(1,100,100);
    5. end
    • 封装一个单点模糊比色函数
     
    1. function isColor(x,y,c,s) --x,y为坐标值,c为颜色值,s为相似度,范围0~100。
    2. local fl,abs = math.floor,math.abs
    3. s = fl(0xff*(100-s)*0.01)
    4. local r,g,b = fl(c/0x10000),fl(c%0x10000/0x100),fl(c%0x100)
    5. local rr,gg,bb = getColorRGB(x,y)
    6. if abs(r-rr)<s and abs(g-gg)<s and abs(b-bb)<s then
    7. return true
    8. end
    9. return false
    10. end
    11.  
    12. if isColor(963, 961, 0x7b593f,90) then touchDown(963, 961)
    13. mSleep(50)
    14. touchUp(963, 961)
    15. end

    函数:findImageInRegionFuzzy 模糊区域找图

    函数功能:在指定区域中,寻找指定的图案,返回其左上角顶点坐标,支持模糊查找。
    函数语法:
      x, y = findImageInRegionFuzzy(picpath, degree, x1, y1, x2, y2, alpha)

    参数说明:

    参数类型说明
    picpath文本型将要寻找的图片文件名(需要预先存放于脚本中res文件夹)
    degree整数型寻找精度,范围:1 ~ 100,当是100时为完全匹配
    x1,y1整数型欲寻找的区域左上角顶点屏幕坐标
    x2,y2整数型欲寻找的区域右下角顶点屏幕坐标
    alpha整数型忽略的颜色值(透明色) 若无请填 0
    返回值类型说明
    x,y整数型找到的图片的左上角顶点坐标,如未找到则返回 -1,-1

    脚本实例:

    • 寻找符合条件的图片
     
    1. x, y = findImageInRegionFuzzy("test_alpha.png", 100, 0, 0, 320, 480, 0xffffff);
    2. if x ~= -1 and y ~= -1 then --忽略背景色白色的情况下找到符合条件的图片则点击
    3. touchDown(1, x, y);
    4. mSleep(50)
    5. touchUp(1, x, y);
    6. else --如果没找到符合条件的
    7. dialog("没找到 ╮(╯▽╰)╭",0);
    8. end

    函数:snapshot 截图

    函数功能:截取屏幕中指定区域的图像并生成指定格式的图片文件
    函数语法:
      snapshot(picname, x1, y1, x2, y2, quality)

    参数说明:

    参数类型说明
    picname文本型截图保存的文件名
    x1,y1整数型欲截取的区域左上角顶点屏幕坐标
    x2,y2整数型欲截取的区域右下角顶点屏幕坐标
    quality数字型当截图格式选为jpg时,可用此参数控制图片质量,此参数值为大于0且小于等于1的值

    返回值:无

    脚本实例:

    • 全屏截图(分辨率1080*1920),并以当前日期为文件名保存
     
    1. current_time = os.date("%Y-%m-%d", os.time());
    2. snapshot(current_time..".png", 0, 0, 1079, 1919); --截图并以当前时间戳命名
    3. snapshot('[public]'..i..".jpg", 0, 0, 1079, 1919, 0.9); --使用jpg格式截图,质量为0.9

    注意事项:

    1.保存图片的格式可为 bmp, jpg, png,推荐选择 png。
    2.截图时,如使用全屏截图,右下角顶点坐标最大为当前分辨率最大值,否则会出现越界错误。
    3.默认图片路径为脚本私有文件夹,文件相同将会被覆盖
    4.本文实例中 os.date 与 os.time 为 Lua 基本库函数,请查阅附录 Lua 操作系统函数库。
    5.".." 为字符串连接操作符,可以将字符串变量、常量连接在一起。
    6.截图保存路径:
    - 开发助手
    Android:/data/data/com.xxscript.idehelper/tengine/public
    iOS(开发助手版本>=1.0.10):/var/mobile/Library/XXIDEHelper/xsp/Temp
    iOS(开发助手<1.0.10) :/Library/ApplicationSupport/XXIDEHelper/xsp/Temp
    - 叉叉助手
    android: /data/data/com.xxAssistant/tengine/public
    iOS(叉叉版本>=2.5.0):/var/mobile/Library/XXAssistant/Lua/Luas/Temp
    iOS(叉叉版本<2.5.0):/Library/Application Support/XXAssistant/Lua/Luas/Temp
    - IPA精灵
    IPA精灵:应用文件夹/Documents/Lua/Luas/Temp/
    7.公共目录路径:
    - 开发助手
    Android:/data/data/com.xxscript.idehelper/tengine/public
    iOS(开发助手版本>=1.0.10):/var/mobile/Library/XXIDEHelper/xsp/Temp/public
    iOS(开发助手版本<1.0.10) :/Library/ApplicationSupport/XXIDEHelper/xsp/Temp/public
    - 叉叉助手
    Android: /sdcard/com.xxAssistant/tengine/public
    iOS(叉叉版本>=2.5.0): /var/mobile/Library/XXAssistant/Lua/Luas/Temp/public
    iOS(叉叉版本<2.5.0): /Library/ApplicationSupport/XXAssistant/Lua/Luas/Temp/public
    - IPA精灵
    IPA精灵:应用文件夹/Documents/Lua/Luas/Temp/public
    8.引擎1.3.0版本增加对公共目录[public]访问支持,截图方向跟随init

    函数:keepScreen 保持屏幕

    函数功能:函数功能:在脚本中保持当前屏幕内容不变,多次调用取色、找色、截图、找图等函数时,直接调用保持的屏幕内容。该函数主要用于优化找图找色函数的效率。
    函数语法:
      keepScreen(flag)

    参数说明:

    参数类型说明
    flag逻辑型保持开关

    返回值:无

    脚本实例:

    • 遍历屏幕区块
     
    1. keepScreen(true);
    2. for k = 1, 640, 10 do
    3. for j = 1, 960, 10 do
    4. --格式化颜色为十六进制文本
    5. color = string.format("%X", getColor(k, j));
    6. --输出系统日志
    7. sysLog("("..k..", "..j..") Color: "..color..".");
    8. end
    9. end
    10. keepScreen(false);

    函数:inputText 输入字符串

    函数功能:向输入框中输入文本
    函数语法:
      inputText(string)

    参数说明:

    参数类型说明
    string文本型将输入的文本以及控制字符

    返回值:无

    脚本实例:

    • 输入文本
     
    1. touchDown(1,150,150); --点击输入框获取焦点(假设已知输入框坐标150,150)
    2. mSleep(50)
    3. touchUp(1,150,150);
    4. mSleep(1000);
    5. inputText("#CLEAR#") --删除输入框中的文字(假设输入框中已存在文字)
    6. mSleep(1000);
    7. inputText("Welcome.#ENTER#"); --在输入框中输入字符串"Welcome."并回车

    注意事项:

    1.使用该函数前,必须先点击输入框获取焦点(指使当前的输入光标停留在某一输入框中)。
    2.iOS系统上,该函数不支持第三方输入法(指百度输入法、搜狗输入法等),请切换到系统内置输入法方可使用,对于弹出的窗口,需要先初始化再使用该函数,例如 App Store登录窗口(该窗口识别ID 为"com.apple.springboard"),安卓则无此限制。
    3.可使用控制字符,包括 \n、\r、#ENTER#、#CLEAR#;#CLEAR#表示清空,需要注意的是,#ENTER#并非支持在所有应用中使用。

    函数:createOcrDict 加载自定义的点阵字库

    函数功能:加载自定义的点阵字库
    函数语法:
      index = createOcrDict(dict)

    参数说明:

    参数类型说明
    dict文本型/table型字库名,如:dict.txt,需放置于脚本内 res 目录;或table型字库编码
    返回值类型说明
    index整数型字库标识,由 createOcrDict 函数返回值生成,ocrText第一个参数需要用到此值

    脚本实例:

     
    1. lines = {}
    2. lines[1] = 'FFFFFC000000000000000000000001FFF$u$0.0.56$15'
    3. lines[2] = 'FFFFFC$l$0.0.42$21'
    4. lines[3] = '10EE1B06608811062084108218C1FF8FF$a$0.1.77$15'
    5. lines[4] = 'FFFFFC03008030040080100200600F00F$h$0.0.71$21'
    6. lines[5] = '0040080100200400801002FFFFFC010020040080100200400800400$王$4.2.83$21'
    7. lines[6] = '1FE200400801002007F8000000000080601804030300E002002001001001001001$哈$0.1.118$26'
    8.  
    9. local dict = createOcrDict(lines)
    10. --或者可以写成这样的形式 local dict = createOcrDict("dict.txt")
    11. result = ocrText(dict, 0, 0, 1135, 639, {"0x613d3b-0x202020","0x797979-0x202020"}, 100, 0, 0) -- 表示范围内全部搜索,以字符串形式返回识别结果
    12. sysLog('result: ' .. result)
    13. results = ocrText(dict, 0, 0, 1135, 639, {"0x613d3b-0x202020"}, 100, 1, 1) -- 表示范围内横向搜索,以table形式返回识别到的所有结果及其坐标
    14. for k,v in pairs(results) do
    15. sysLog(string.format('{x=%d, y=%d, text=%s}', v.x, v.y, v.text))
    16. end

    注意事项:

    1.ocr函数不支持多分辨率,不受setScreenScale影响
    2.字库文件“dict.txt”需注意文本编码必须使用 UTF-8 格式,并放置于脚本内 res 目录
    3.搜索方向横向或竖向时的检索规则为:从识别到第一个匹配结果开始给予该位置横向或竖向搜索,忽略选定区域内其他范围;合理使用搜索方向参数可有效提高ocr函数性能。

    函数:ocrText 文字点阵化识别

    函数功能:识别屏幕上的文字。
    函数语法:
      result = ocrText(index, x1, y1, x2, y2, {"c0-c1"} , sim, flag, dir)

    参数说明:

    参数类型说明
    index整数型字库标识,由 createOcrDict 函数返回值生成
    x1, y1整数型识别区域左上角顶点屏幕坐标
    x2, y2整数型识别区域右下角顶点屏幕坐标
    c0, c1文本型偏色范围,由字库制作中获取,需要与制作字库时所设值保持一致,多组偏色用,分割
    sim整数型精确度,范围 0 - 100
    flag整数型表示选择返回结果的类型, 0 == 字符串形式返回识别结果,1 == table形式返回识别到的结果及其坐标
    dir整数型选填项,表示识别方向,0 == 区域内全部搜索,1 == 横向搜索, 2 ==竖向搜索, 忽略此项则默认为0
    返回值类型说明
    result文本型/table型返回识别结果/返回识别到的结果及其坐标

    脚本实例:

     
    1. lines = {}
    2. lines[1] = 'FFFFFC000000000000000000000001FFF$u$0.0.56$15'
    3. lines[2] = 'FFFFFC$l$0.0.42$21'
    4. lines[3] = '10EE1B06608811062084108218C1FF8FF$a$0.1.77$15'
    5. lines[4] = 'FFFFFC03008030040080100200600F00F$h$0.0.71$21'
    6. lines[5] = '0040080100200400801002FFFFFC010020040080100200400800400$王$4.2.83$21'
    7. lines[6] = '1FE200400801002007F8000000000080601804030300E002002001001001001001$哈$0.1.118$26'
    8.  
    9. local dict = createOcrDict(lines)
    10. --或者可以写成这样的形式 local dict = createOcrDict("dict.txt")
    11. result = ocrText(dict, 0, 0, 1135, 639, {"0x613d3b-0x202020","0x797979-0x202020"}, 100, 0, 0) -- 表示范围内全部搜索,以字符串形式返回识别结果
    12. sysLog('result: ' .. result)
    13. results = ocrText(dict, 0, 0, 1135, 639, {"0x613d3b-0x202020"}, 100, 1, 1) -- 表示范围内横向搜索,以table形式返回识别到的所有结果及其坐标
    14. for k,v in pairs(results) do
    15. sysLog(string.format('{x=%d, y=%d, text=%s}', v.x, v.y, v.text))
    16. end

    注意事项:

    1.ocr函数不支持多分辨率,不受setScreenScale影响
    2.字库文件“dict.txt”需注意文本编码必须使用 UTF-8 格式,并放置于脚本内 res 目录
    3.搜索方向横向或竖向时的检索规则为:从识别到第一个匹配结果开始给予该位置横向或竖向搜索,忽略选定区域内其他范围;合理使用搜索方向参数可有效提高ocr函数性能。

    函数:createOCR 载入高级文字识别字库(集成tesserOCR)

    函数功能:载入高级文字识别字库,并指定检测方式
    函数语法:
      ocr, msg = createOCR({
      type = "tesseract",
      mode = mode,
      path = path,
      lang = lang
      })

    参数说明:

    参数类型说明
    type文本型[必填]文字识别类型,暂只支持tesseract,更多ocr引擎逐步支持中
    mode整数型[选填]引擎识别模式(参见下表),默认3
    path文本型[选填]字库路径,不填默认使用eng字库路径;官方字库扩展路径、自定义路径见下方说明
    lang文本型[选填]字库语言文件名称,不填则默认eng(只支持一般的中英+数字+标点符号)

    path 自定义字库,有两种路径选择:
    对于自定义字库,有以下几种路径选择:
    1. 内置到xsp的res目录下,直接指定res路径:"res/"
    2. 下载到public目录下,指定[public]和子路径:"[public]downloads/tessdata/"
    3. 使用开发助手/叉叉助手的字库扩展,指定[external]即可:"[external]"
    特别注意:下载到public目录的字库路径,traineddata的上层目录必须命名为tessdata

    lang 字库语言文件:
    1. lang 为.traineddata字库文件名,叉叉助手、开发助手中可下载的字库语言文件有:
    chi_sim 简体中文字库
    chi_tra 繁体中文字库
    eng_ext 英文增强版字库
    eng 内置默认精简版中英数字标点字库,免下载可用
    2. 识别要求不高或识别数据比较标准,也可以path和lang都不填,使用默认字库eng,只支持一般的中英+数字+标点符号。

    字库与语言配置样例:
    1. path & lang均不填: 使用内置eng字库
    2. path = [external] & lang = eng_ext/chi_sim/chi_tra:叉叉提供的字库扩展(需下载)
    3. path = "res/" & lang = dictname(dictname:xsp打包中res目录字库文件名)

    引擎识别模式说明
    0仅执行Tesseract,速度最快
    1仅进行Cube处理,较慢但准确
    2结合Tesseract和Cube处理,最准确
    3根据字库配置自动选择
    返回值类型说明
    ocr文本型ocr实例,创建失败时ocr为nil
    msg文本型创建成功返回版本号,创建失败返回错误信息

    脚本实例:

     
    1. local ocr, msg = createOCR({
    2. type = "tesseract", -- 指定tesseract引擎
    3. path = "[external]", -- 使用开发助手/叉叉助手的扩展字库,不填默认使用eng字库路径
    4. lang = "eng_ext" -- 使用英文增强字库(注意需要提前下载好)
    5. })
    6.  
    7. if ocr ~= nil then
    8. -- ocr 创建成功,使用该实例进行后续识别操作(参见下面函数文档)
    9. sysLog("createOCR succeed: Tesseract-OCR v" .. msg)
    10. else
    11. -- ocr 创建失败,根据msg提示调整
    12. sysLog("createOCR failed: " .. tostring(msg))
    13. end

    训练字库:
    请参阅:【如何使用Tesseract-OCR(v3.02.02)训练字库】

    注意事项:

    支持引擎版本:1.8.10或更新
    引擎内置Tesseract-OCR版本:3.02.02

    函数:ocr:getText 高级文字识别

    函数功能:使用已载入的高级文字识别字库进行识别
    函数语法:
      local code, text = ocr:getText({
      psm = psm,
      rect = {x1, y1, x2, y2},
      diff = {diff},
      data = data,
      whitelist = whitelist,
      blacklist = blacklist
      })

    参数说明:

    参数类型说明
    psm整数型[选填]int: page segmentation mode(参见下表),默认6
    recttable[必填]{x1, y1, x2, y2} 屏幕的识别范围,越准确越好
    difftable[必填]{"颜色1-误差1", "颜色2-误差2", ...} 色值范围,可以提供多个,供二值化使用
    datatable[选填]二值化二维数组,1代表有效数据,其余代表无效数据)
    whitelist文本型[选填]仅识别为白名单中的字符
    blacklist文本型[选填]识别时需排除的字符(对识别时易相互混淆的字符进行排除)
    psm选项说明
    0仅检测方向和文本
    1自动检测方向和文本(OSD)
    2自动检测,但不进行OSD或OCR处理
    3自动PSM模式(但不含OSD)
    4所识别图片的字体大小不一
    5所识别图片当作整块竖向文字区域
    6所识别图片当作整块横向文字区域 (默认值)
    7所识别图片当作一行文字
    8所识别图片当作单个词语
    9所识别图片当作单个圆型围绕的词语
    10所识别图片当作单个英文/数字字符
    11尽可能识别更多的字符(无顺序要求)
    12分散稀疏的OSD检测
    返回值类型说明
    code整数型code = 0: 识别成功;code < 0: 识别失败
    text文本型识别出的字符串(末尾可能有多余的换行或空格),识别失败时,text为对应的错误提示

    脚本实例:

     
    1. local ocr, msg = createOCR({
    2. type = "tesseract", -- 指定tesseract引擎
    3. path = "[external]", -- 使用开发助手/叉叉助手的扩展字库
    4. lang = "eng_ext" -- 使用英文增强字库(注意需要提前下载好)
    5. })
    6.  
    7. if ocr ~= nil then
    8. string.trim = function(s)
    9. return s:match'^%s*(.*%S)' or ''
    10. end
    11.  
    12. local code, text = 0, ""
    13. mSleep(1000)
    14. -- 识别屏幕图像内容(例如5/5s设备的当前时间显示)
    15. code, text = ocr:getText({
    16. rect = {249, 6, 249 + 144, 6 + 29},
    17. diff = {"0x000000-0x101010"}, -- 时间颜色为纯黑
    18. whitelist = "0123456789APM:" -- 添加所有可能出现的字符作为白名单
    19. })
    20. -- 输出示例:"code = 0, text = 5:24 PM" (末尾可能有多余换行符,为正常结果,可以参考trim处理)
    21. sysLog("code = " .. tostring(code) .. ", text = " .. text:trim())
    22.  
    23. mSleep(1000)
    24. -- 识别二值化二维数组(单个字符)
    25. code, text = ocr:getText({
    26. psm = 10, -- 所识别图片当作单个英文/数字字符
    27. data = {
    28. {0,0,0,0,1,0,0,0,0,0,0,0,0,0},
    29. {0,0,0,1,0,1,0,0,0,0,0,0,0,0},
    30. {0,0,0,0,1,0,0,0,0,0,0,0,0,0},
    31. {0,0,0,1,0,0,0,0,0,0,0,0,0,0},
    32. {0,0,0,1,0,0,0,0,0,0,0,0,0,0},
    33. {0,0,1,1,0,0,0,0,0,0,0,0,0,0},
    34. {0,1,0,1,0,0,0,0,0,0,0,0,0,0},
    35. {0,1,1,1,1,1,0,1,1,0,0,0,0,0},
    36. {1,0,1,1,0,0,0,0,1,1,1,0,0,0},
    37. {0,1,0,1,0,0,0,0,0,0,1,1,0,0},
    38. {1,1,1,0,0,0,0,0,0,0,1,1,0,0},
    39. {1,0,0,0,0,0,0,0,0,0,1,0,1,0},
    40. {1,0,0,0,0,0,0,0,0,0,0,1,1,0},
    41. {1,0,0,0,0,0,0,0,0,0,0,1,0,1},
    42. {1,0,0,0,0,0,0,0,0,0,0,0,1,0},
    43. {1,0,0,0,0,0,0,0,0,0,0,1,1,1},
    44. {1,0,0,0,0,0,0,0,0,0,0,1,0,1},
    45. {1,1,0,0,0,0,0,0,0,0,0,1,1,0},
    46. {1,0,1,0,0,0,0,0,0,0,1,0,0,0},
    47. {0,1,1,1,0,1,0,0,1,1,1,0,0,0},
    48. {0,0,0,1,1,1,0,1,1,0,0,0,0,0},
    49. {0,0,0,0,0,0,1,0,1,0,0,0,0,0}
    50. },
    51. whitelist = "0123456789" -- 添加白名单为数字类型
    52. })
    53. -- 输出示例:"code = 0, text = 6"
    54. sysLog("code = " .. tostring(code) .. ", text = " .. text:trim())
    55.  
    56. mSleep(1000)
    57. -- 识别二值化二维数组(多个字符)
    58. code, text = ocr:getText({
    59. psm = 7, -- 所识别图片当作一行文字
    60. data = {
    61. {1,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0},
    62. {1,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,0},
    63. {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1},
    64. {1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1},
    65. {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
    66. {1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0},
    67. {1,1,1,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1,0,0},
    68. {1,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0},
    69. {0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1},
    70. {0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1},
    71. {0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1},
    72. {0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1},
    73. {1,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1},
    74. {0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0},
    75. {0,0,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0}
    76. },
    77. whitelist = "0123456789"
    78. })
    79. -- 输出示例:"code = 0, text = 53"
    80. sysLog("code = " .. tostring(code) .. ", text = " .. text:trim())
    81. else
    82. sysLog("createOCR failed: " .. tostring(msg))
    83. end

    特别说明

    diff = {"C1-D1", "C2-D2", …} 设置的意义是,当区域内任意一个颜色值Cxy,满足条件 min(Ci - Di, 0x000000) ≤ Cxy ≤ max(Ci + Di, 0xffffff),i = 1, 2, … 的时候,这个位置的颜色就是有效颜色(0xffffff),否则,都是无效颜色(0x000000)。这个处理过程称为二值化,经过这样处理后的二值化数据,提交给OCR识别会更加精确。

    注意事项:

    支持引擎版本:1.8.10或更新

    函数:ocr:release 释放字库

    函数功能:主动释放OCR字库,避免内存峰值过高导致被系统强杀
    函数语法:
      ocr:release()

    参数说明:
    使用到字库较大的情况下,为避免内存峰值过高导致被系统强杀,请在OCR使用完毕时调用API释放ocr,否则只能依赖lua的gc自动清理。

    脚本实例:

     
    1. local ocr, msg = createOCR({
    2. type = "tesseract", -- 指定tesseract引擎
    3. path = "[external]", -- 使用开发助手/叉叉助手的扩展字库
    4. lang = "eng_ext" -- 使用英文增强字库(注意需要提前下载好)
    5. })
    6.  
    7. local code, text = ocr:getText({
    8. rect = {249, 6, 249 + 144, 6 + 29},
    9. diff = {"0x000000-0x101010"},
    10. whitelist = "0123456789APM:"
    11. })
    12.  
    13. -- ocr使用完毕,为避免内存峰值过高导致被系统强杀(主要是使用到字库较大的情况下)
    14. -- 建议及时手动释放ocr
    15. ocr:release()

    注意事项:

    支持引擎版本:1.8.11或更新

    函数:binarizeImage 二值化图片转换为table 5-120601152328.png-0.2kB

    函数功能:对当前屏幕指定范围的图像二值化,并转换为table,得到的结果通过去噪或者矩阵运算后,可以提供给ocr:getText()识别成文字
    函数语法:
      colorTbl = binarizeImage({
       rect = {x1, y1, x2, y2},
       diff = {diff}
      })

    参数说明:

    参数类型说明
    recttable[必填]{x1, y1, x2, y2} 屏幕二值化的识别范围,越准确越好
    difftable[必填]{"颜色1-误差1", "颜色2-误差2", ...} 色值范围,可以提供多个,供二值化使用
    返回值类型说明
    colorTbl文本型图像二值化后的table

    脚本实例:

     
    1. colorTbl = binarizeImage({
    2. rect = {30, 80, 53, 101},
    3. diff = {"0xf7d363-0x1f1f1f", "0xefaa29-0x1f1f1f"}
    4. })
    5.  
    6. -- 输出colorTbl每一行测试转换结果
    7. for _, row in pairs(colorTbl) do
    8. sysLog(table.concat(row, ','))
    9. end
    10.  
    11. --[[
    12. colorTbl格式类似这样:
    13. {
    14. {0,0,0,0,1,0,0,0,0,0,0,0,0,0},
    15. {0,0,0,1,0,1,0,0,0,0,0,0,0,0},
    16. {0,0,0,0,1,0,0,0,0,0,0,0,0,0},
    17. {0,0,0,1,0,0,0,0,0,0,0,0,0,0},
    18. {0,0,0,1,0,0,0,0,0,0,0,0,0,0},
    19. {0,0,1,1,0,0,0,0,0,0,0,0,0,0},
    20. {0,1,0,1,0,0,0,0,0,0,0,0,0,0},
    21. {0,1,1,1,1,1,0,1,1,0,0,0,0,0},
    22. {1,0,1,1,0,0,0,0,1,1,1,0,0,0},
    23. {0,1,0,1,0,0,0,0,0,0,1,1,0,0},
    24. {1,1,1,0,0,0,0,0,0,0,1,1,0,0},
    25. {1,0,0,0,0,0,0,0,0,0,1,0,1,0},
    26. {1,0,0,0,0,0,0,0,0,0,0,1,1,0},
    27. {1,0,0,0,0,0,0,0,0,0,0,1,0,1},
    28. {1,0,0,0,0,0,0,0,0,0,0,0,1,0},
    29. {1,0,0,0,0,0,0,0,0,0,0,1,1,1},
    30. {1,0,0,0,0,0,0,0,0,0,0,1,0,1},
    31. {1,1,0,0,0,0,0,0,0,0,0,1,1,0},
    32. {1,0,1,0,0,0,0,0,0,0,1,0,0,0},
    33. {0,1,1,1,0,1,0,0,1,1,1,0,0,0},
    34. {0,0,0,1,1,1,0,1,1,0,0,0,0,0},
    35. {0,0,0,0,0,0,1,0,1,0,0,0,0,0}
    36. }
    37. ]]--
    38.  
    39. -- 对colorTbl结果进行可选的去噪或者矩阵运算纠正等处理
    40. -- (假设处理函数是denoising)
    41. colorTbl = denoising(colorTbl)
    42.  
    43. local ocr, msg = createOCR({
    44. type = "tesseract"
    45. })
    46.  
    47. -- 使用ocr识别新的colorTbl
    48. local code, text = ocr:getText({
    49. data = colorTbl,
    50. psm = 10 -- 单个字符模式识别
    51. })
    52.  
    53. sysLog("code = " .. tostring(code) .. ", text = " .. text)
    54. -- 输出结果:code = 0, text = 6

    注意事项:

    支持引擎版本:1.8.30或更新

    函数:runApp 运行应用

    函数功能:打开一个应用程序。
    函数语法:
      flag = runApp(appid)

    参数说明:

    参数类型说明
    appid文本型应用程序的应用ID
    返回值类型说明
    flag整数型0 == 应用启动成功;非0 == 应用启动失败

    脚本实例:

    • 打开内置音乐应用,然后关闭
     
    1. r = runApp("com.apple.Music");
    2. mSleep(10 * 1000); --等待程序响应
    3. if r == 0 then
    4. closeApp("com.apple.Music");
    5. else
    6. toast("启动应用失败");
    7. end

    注意事项:

    1.runApp函数需要系统响应时间,响应时间根据机型有所不同,调用此函数需做好延迟或判断。

    函数:closeApp 关闭应用

    函数功能:关闭一个应用程序。
    函数语法:
      closeApp(appid)

    参数说明:

    参数类型说明
    appid文本型应用程序的应用ID

    返回值:无

    脚本实例:

    • 打开内置音乐应用,然后关闭
     
    1. r = runApp("com.apple.Music");
    2. mSleep(10 * 1000); --等待程序响应
    3. if r == 0 then
    4. closeApp("com.apple.Music");
    5. else
    6. toast("启动应用失败");
    7. end

    函数:appIsRunning 检测应用是否运行

    函数功能:检测应用是否运行
    函数语法:
      flag = appIsRunning(appid)

    参数说明:

    参数类型说明
    appid文本型目标应用程序的应用ID
    返回值类型说明
    flag整数型0 - 目标应用未运行;1 - 目标应用运行中

    脚本实例:

     
    1. flag = appIsRunning("com.xxAssistant"); --检测叉叉助手是否在运行
    2. if flag == 0 then
    3. runApp("com.xxAssistant") --运行叉叉助手
    4. end

    注意事项:

    此函数将判断目标应用的运行状态,目标应用前台运行或者后台运行返回值都为 1。

    函数:isFrontApp 判断是否为前台应用

    函数功能:根据应用ID判断应用是否处于前台。
    函数语法:
      flag = isFrontApp(appid)

    参数说明:

    参数类型说明
    appid文本型待检测的应用程序的应用ID
    返回值类型说明
    flag整数型0 == 不在前台运行;1 == 在前台运行

    脚本实例:

    • 监听应用状态
     
    1. while true do
    2. isfront = isFrontApp("com.xxAssistant"); --前台状态
    3. if isfront == 1 then
    4. break
    5. end
    6. toast("请打开叉叉助手");
    7. mSleep(3000)
    8. end

    函数:frontAppName 获取前台应用识别ID

    函数功能:获取前台应用程序的应用ID。
    函数语法:
      appid = frontAppName()

    参数说明:

    返回值类型说明
    appid文本型返回前台应用程序的应用ID,若无应用处于前台,则返回空字符串

    脚本实例:

    • 检查指定应用是否开启
     
    1. appid = frontAppName();
    2. if appid ~= "com.apple.mobilesafari" then
    3. dialog("请打开 Safari 再运行该脚本!", 5);
    4. mSleep(3000);
    5. lua_exit();
    6. end

    函数:showUI 自定义脚本界面

    函数功能:显示一个自定义的界面,用来接收用户相关的自定义配置。
    函数语法:
      ret,results = showUI(ui_json)

    参数说明:

    参数类型说明
    ui_json文本型自定义界面json格式字符串,或UI目录下的json文件名称
    返回值类型说明
    ret整数型返回用户按下的按钮 0 - 取消;1 - 确定
    resultstable类型返回用户输入的多项数据

    脚本界面说明

    脚本界面通过json格式存储 ,以下是一个包含所有控件及其属性的例子:

     
    1. {
    2. "style" : "default",
    3. "config" : "save_111.dat",
    4. "width" : 700,
    5. "height" : 1080,
    6. "cancelname" : "Cancel",
    7. "okname" : "Let's Rock",
    8. "cancelscroll" : true,
    9. "countdown":10,
    10. "views" : [
    11. {
    12. "text" : "基本设置",
    13. "type" : "Page",
    14. "views" : [
    15. {
    16. "align" : "center",
    17. "color" : "0,0,225",
    18. "size" : 30,
    19. "bg" : "0,0,0", //RGB格式规定标签的背景色,不指定为透明
    20. "text" : "设置:这是一行文本",
    21. "type" : "Label"
    22. },
    23. {
    24. "id" : "RadioGroup1",
    25. "list" : "选项1,选项2,选项3,选项4,选项5,选项6,选项7",
    26. "select" : "0",
    27. "size" : 30,
    28. "type" : "RadioGroup",
    29. "orientation" : "vertical" //选项排布方式为竖排
    30. },
    31. {
    32. "align" : "left",
    33. "color" : "0,100,0",
    34. "id" : "Edit1",
    35. "kbtype" : "number",
    36. "prompt" : "这是提示文本",
    37. "size" : 25,
    38. "text" : "这是预输入文本",
    39. "type" : "Edit"
    40. },
    41. {
    42. "id" : "CheckBoxGroup1",
    43. "list" : "选项1,选项2,选项3,选项4,选项5,选项6,选项7",
    44. "select" : "3@5",
    45. "size" : 30,
    46. "type" : "CheckBoxGroup",
    47. "orientation" : "horizontal" //选项排布方式为智能横排
    48. },
    49. {
    50. "id" : "ComboBox1",
    51. "list" : "选项1,选项2,选项3,选项4,选项5,选项6,选项7",
    52. "select" : "1",
    53. "size" : 30,
    54. "type" : "ComboBox"
    55. },
    56. {
    57. "src" : "b.png", //这是来源为本地文件的图片
    58. "type" : "Image"
    59. },
    60. {
    61. "src" : "http://www.baidu.com/img/bdlogo.png", //这是来源为网络地址的图片
    62. "type" : "Image"
    63. }
    64. ]
    65. },
    66. {
    67. "text" : "水平布局",
    68. "type" : "Page",
    69. "views" : [
    70. {
    71. "color" : "100,100,100",
    72. "size" : 30,
    73. "text" : "以下是水平布局排列的三个控件",
    74. "type" : "Label"
    75. },
    76. {
    77. "height" : 300,
    78. "width" : 700,
    79. "id" : "group1",
    80. "type" : "LinearLayout", //这是LinearLayout控件
    81. "valign" : "top",
    82. "views" : [
    83. //从这里开始是LinearLayout控件内部的子控件,不可嵌套LinearLayout控件,可添加LinearLayout、Page以外的所有控件
    84. {
    85. "color" : "100,100,100",
    86. "size" : 30,
    87. "text" : "选择",
    88. "type" : "Label",
    89. "width" : 100
    90. //LinearLayout控件内部的子控件均需要指定一个width属性,不指定则无法显示
    91. },
    92. {
    93. "id" : "checkboxgroup2",
    94. "list" : "选项1,选项2,选项3",
    95. "select" : "2@3@",
    96. "type" : "CheckBoxGroup",
    97. "width" : 180
    98. },
    99. {
    100. "id" : "4",
    101. "list" : "选项1,选项2,选项3,选项4,选项5",
    102. "select" : "1",
    103. "size" : 20,
    104. "type" : "ComboBox",
    105. "width" : 250
    106. }
    107. ]
    108. },
    109. {
    110. "color" : "100,100,100",
    111. "size" : 30,
    112. "text" : "以下是一张默认布局方式的图片,水平布局可与普通布局样式联合使用",
    113. //这里是一个Label,跟上面的LinearLayout同层级
    114. "type" : "Label",
    115. "width" : 100
    116. },
    117. {
    118. "src" : "b.png",
    119. "type" : "Image"
    120. },
    121. {
    122. "color" : "100,100,100",
    123. "size" : 30,
    124. "text" : "以下又是一个水平布局区域",
    125. //这里也是一个Label,跟上面的LinearLayout同层级
    126. "type" : "Label"
    127. },
    128. {
    129. //在同层级的情况下,可以多个LinearLayout联合使用,以下是第二个LinearLayout控件中的内容
    130. "height" : 400,
    131. "width" : 700,
    132. "id" : "group1",
    133. "type" : "LinearLayout",
    134.  
    135. "valign" : "top",
    136. "views" : [
    137. {
    138. "color" : "100,100,100",
    139. "size" : 30,
    140. "text" : "右边是一张图片",
    141. "type" : "Label",
    142. "width" : 150
    143. },
    144. {
    145. "src" : "b.png",
    146. "type" : "Image",
    147. "width" : "400"
    148. }
    149. ]
    150. }
    151. ]
    152. },
    153. {
    154. "text" : "跳转示例",
    155. "type" : "Page",
    156. "views" : [
    157. {
    158. "color" : "100,110,200",
    159. "extra" : [ //附加属性指定
    160. {
    161. "goto" : "http://www.baidu.com", //跳转到网址
    162. "text" : "阅读原文"
    163. },
    164. {
    165. "goto" : "qq", //跳转到QQ咨询
    166. "text" : "1602127440"
    167. }
    168. ],
    169. "size" : 30,
    170. "text" : "阅读原文 QQ:1602127440",
    171. "type" : "Label"
    172. }
    173. ]
    174. },
    175. {
    176. "text" : "V1.6.7更新",
    177. "type" : "Page",
    178. "views" : [
    179. {
    180. "align" : "left",
    181. "color" : "0,0,0",
    182. "size" : 40,
    183. "text" : "标签",
    184. "type" : "Label",
    185. "bg" : "100,100,100"
    186. },
    187. {
    188. "id" : "web",
    189. "url" : "http://www.baidu.com",
    190. "type" : "WebView",
    191. "height" : 500,
    192. "width" : 800
    193. },
    194. {
    195. "id" : "line",
    196. "type" : "Line",
    197. "color" : "0,0,255",
    198. "height" : 7,
    199. "width" : 800
    200. }
    201. ]
    202. }
    203. ]
    204. }
    205.  

    创建一个界面,需要包含style和views两个参数。

    • style表示界面样式,目前支持两种:
      1.default 控件垂直排列
      2.custom 界面中所有控件都必须设置大小和位置,后面有补充说明
    • views数组则是界面上的全部控件,要根据views数组的长度来生成若干个可切换的tab;width与height分别指定了界面的宽和高(单位是像素);
      bg 指定界面的背景图片;
      text 指定页面的名称,当存在Page控件时,Tab上会显示该名称;
      okname,cancelname 分别为底部的确定和取消按钮显示的文字;
      config表示自动配置文件名,界面打开的时候,如果存在此配置文件,UI会自动读取该配置文件中的参数,用户点击确定按钮时,也会去更新该配置文件
      cancelscroll 用于控制当设定控件超出UI宽度时是否支持滑动,默认true
      false - UI界面支持滑动
      true - UI界面不支持滑动
      countdown 此属性会在生成UI上进行倒计时,自动确认UI输入。

    界面控件:
    界面包含有8种控件:标签 Label,单选框 RadioGroup,编辑框 Edit,多选框CheckBoxGroup,下拉框 ComboBox,图片 Image,页面Page,水平布局LinearLayout。
    例如一个标签控件的例子:

     
    1. {
    2. "type": "Label",
    3. "text": "设置",
    4. "size": 25,
    5. "align": "center",
    6. "color": "0,0,255"
    7. }
    • 标签 Label 一共有六种属性:
      文本/标题/text
      必填,一般来用显示说明文字或者标题,该控件没有任何返回值,只用作显示。此类型可支持多行显示,在字符串中插入 \n 可以进行换行,例如:\"测试\n测试 1\n测试2\"
      数值/字体大小/size
      如果不指定该属性,则默认值为 15。
      文本/对齐方式/align
      对齐方式 align 可取值为:左对齐 left,右对齐 right,居中 center。
      文本/字体颜色/color
      字体颜色 color 使用RGB十进制数值,以英文半角逗号分割。
      文本/背景颜色/bg
      背景颜色 bg 使用RGB十进制数值,以英文半角逗号分割;或输入图片文件名以使用图片文件。
      附加属性/extra,指定了该标签内部分文本的属性。
      支持多种类型的跳转 goto,对应跳转类型的属性类别为url、qq;跳转网址 url:属性类别中直接输入该url; 跳转QQ:属性类别填写"qq"。

    • 单选框 RadioGroup 一共有四种属性:
      文本/ID/id
      必填,全局唯一,用来标示控件
      文本/可选项目标题 /list
      可选项目标题 list 用英文半角逗号分割。
      文本/字体颜色/color
      字体颜色 color 使用RGB十进制数值,以英文半角逗号分割。
      文本/默认选中项编号/select
      默认选中项编号 select 只允许填写一个,序号从 0 开始,与可选项目标题中的顺序保持一致。
      文本/分行显示控制/orientation
      用于控制多个选项的排布方式,填写horizontal为水平方向智能排版,填写vertical为全部选项竖排,不水平排版,不填写则默认为水平方向智能排版
      数值/字体大小/size
      如果不指定该属性,则默认值为 30。

    • 编辑框 Edit 一共有七种属性:
      文本/ID/id
      必填,全局唯一,用来标示控件
      文本/编辑框提示文本/prompt
      编辑框提示文本prompt为编辑框中无任何内容时显示的底色文本。
      文本/编辑框默认内容/text
      界面载入时已经存在于编辑框中的文本。
      文本/对齐方式/align
      文本/字体颜色/color
      文本/键盘类型/kbtype
      设置获取焦点时弹出的键盘类型,number ascii default
      数值/字体大小/size
      如果不指定该属性,则默认值为15

    • 多选框 CheckBoxGroup,又称作检查框,一共有三种属性:
      文本/ID/id
      必填,全局唯一,用来标示控件
      文本/可选项目标题/list
      文本/默认选中项编号/select
      默认选中项编号 select 允许填写一个或多个,填写多个时以 @ 分割编号。
      文本/字体颜色/color
      字体颜色 color 使用RGB十进制数值,以英文半角逗号分割。
      文本/分行显示控制/orientation
      用于控制多个选项的排布方式,填写horizontal为水平方向智能排版,填写vertical为全部选项竖排,不水平排版,不填写则默认为水平方向智能排版
      数值/字体大小/size
      如果不指定该属性,则默认值为 30。

    • 下拉框 ComboBox,一共有四种属性:
      文本/ID/id
      必填,全局唯一,用来标示控件
      文本/可选项目标题/list 多个项目标题之间以” ,”分割
      数值/字体大小/size
      如果不指定该属性,则默认值为 30。
      文本/默认选中项编号/select
      默认选中项编号 select 只允许填写一个,序号从 0 开始

    • 图片 Image,放置一个图片到 UI 上,属性:
      路径/插入图片的路径/src 可以是本地路径或者网络路径
      例如:"type":"Image","src":"http://www.baidu.com" 或者"src":"1.png"

    • 页面 Page,生成一个独立页面到UI上,该页面可自由添加若干个控件,在上一级页面有Tab的页面索引,可点击切换页面,一共有两个属性:
      文本/Tab标题/text
      数组/控件容器/views
      (要特别注意的是,如果存在Page控件,那么别的同级控件都就只能是Page控件,否则会导致UI解析出错,返回长度为0的字符串作为结果。)

    • WebView页面 WebView,在UI上规定一个范围,作为webview展示区域,可显示任意url网页内容,共有四种种属性:
      文本/ID/id
      必填,全局唯一,用来标示控件
      文本/地址/url
      指定该webview区域展示的目标地址
      数字/宽度/width
      指定展示区域的宽度
      数字/高度/height
      指定展示区域的高度

    • 直线 line,在UI上放置一条直线,共有四种种属性:
      文本/ID/id
      必填,全局唯一,用来标示控件
      文本/颜色/color
      使用RGB十进制数值,以英文半角逗号分割。
      数字/宽度/width
      指定线条长度
      数字/高度/height
      指定线条粗细

    以上九种控件均可重复使用,这个界面的样式 style 为 default,即默认样式,这个样式下的控件将会自动排列,不需要指定其坐标。部分控件带有id参数,id不可重复,需要注意的是,涉及到用户操作的控件,其id参数为必填项。

    • 水平布局 LinearLayout,指定一个区域,区域内的子控件按照水平布局显示,控件内可添加page、LinearLayout以外的控件作为子控件,该控件一共有三个属性:
      文本/控件宽度/width
      必填,标示水平布局控件宽度
      文本/控件高度/height
      必填,标示水平布局控件高度
      文本/垂直对齐属性/valign
      指定水平布局控件内子控件之间的垂直对齐属性,有top, center, bottom三个值,省略不填则默认为top
      注意: LinearLayout 控件内的所有子控件都需要加入width属性指定宽度,不指定width属性的控件不予显示
      以下是一个关于LinearLayout控件的示例
     
    1. {
    2. "id" : "group1",
    3. "width" : 1780,
    4. "height" : 600,
    5. "type" : "LinearLayout",
    6. "views" : [
    7. {
    8. "color" : "100,110,200",
    9. "size" : 30,
    10. "text" : "标题栏",
    11. "type" : "Label",
    12. "width" : 100
    13. },
    14. {
    15. "id" : "checkboxgroup2",
    16. "list" : "选项1,选项2,选项3",
    17. "select" : "2@3@",
    18. "type" : "CheckBoxGroup",
    19. "width" : 250
    20. },
    21. {
    22. "id" : "4",
    23. "list" : "选项1,选项2,选项3,选项4,选项5",
    24. "select" : "1",
    25. "size" : 20,
    26. "type" : "ComboBox",
    27. "width" : 210
    28. }
    29. ]
    30. }

    另一种界面style样式为 custom,当界面样式被指定为这种,则必须指定每个控件的 rect 属性以调整控件的尺寸以及位置,例如:

     
    1. {
    2. "type": "Edit", "size": 15, "align": "left",
    3. "prompt": "提示文字",
    4. "text": "默认文字",
    5. "color": "255,0,0",
    6. "rect": "0,0,100,40"
    7. }
    • 文本/尺寸与位置/rect
      该属性适用于除页面page外的全部六种控件,将控件的左上角顶点横坐标、纵坐标,控件宽度、高度分别以英文半角逗号分割。
    • 返回值
      除了标签 Label,页面Page 其余四种控件均存在文本型返回值,按照定义时的id,会返回以id为key的Map类型数据。单选框返回当前选中项的编号;编辑框返回其中的内容;多选框返回 当前选中项的编号(从 0 开始),多个选项以 @ 分割。如:3@5 表示多选框组编号为 3 和 5 的两个选项已被选中。
      解析函数的第1个返回值为整数型,用户单击右下角的“确认”时返回 1,单击左下角的“取消”时返回 0。

    函数:getUIContent 获取UI文件信息

    函数功能:获取json文件中的内容
    函数语法:
      content = getUIContent(string)

    参数说明:

    参数、返回值类型说明
    string文本型脚本UI目录下json文件名称
    content文本型所获取的json文件内容

    脚本实例:

    • 一个简单的动态UI例子
     
    1. --ui.json文件内具体内容如下
    2. {
    3. "style": "default",
    4. "config": "save.dat",
    5. "width": 400,
    6. "height": 300,
    7. "cancelname": "Quit",
    8. "okname": "Let's Rock!",
    9. "views": [
    10. {
    11. "type": "Page",
    12. "text": "settings",
    13. "views": [
    14. {
    15. "type": "Label",
    16. "text": "Settings",
    17. "size": 25,
    18. "align": "center",
    19. "color": "0,0,255",
    20. }
    21. ]
    22. }
    23. ]
    24. }
    • 更改ui窗口的宽、高的实例
     
    1. --lua文件中示例如下
    2. local bb = require("badboy")
    3. local json = bb.getJSON()
    4.  
    5. ret,results=showUI("ui.json"); --显示未更改的UI界面
    6.  
    7. content = getUIContent("ui.json") --获得文件ui.json的内容
    8. lua_value = json.decode(content) --对获取到的json字符串解码
    9. lua_value.width = 500 --将ui窗口宽度赋值为500
    10. lua_value.height = 400 --将ui窗口宽度赋值为450
    11. showUI(json.encode(lua_value)) --重新编码json字符串,窗口将按照新设定的尺寸显示

    注意事项:

    1.badboy是专为叉叉脚本开发的开源工具库,具体使用方法参照对应章节

    函数:resetUIConfig 重置UI默认选项

    函数功能:重置UI默认选项
    函数语法:
      resetUIConfig(file)

    参数说明:

    参数类型说明
    file文本型需要重置的UI配置文件,例"save.dat"

    返回值:无

    脚本实例:

     
    1. ret,results = showUI("ui.json")
    2. mSleep(500)
    3. resetUIConfig("save_111.dat")
    4. mSleep(500)
    5. toast("UI默认选项已重置")
    6. mSleep(2500)
    7. ret,results = showUI("ui.json")

    注意事项:

    支持引擎版本:1.7.4或更新

    函数:getScreenSize 获取屏幕分辨率

    函数功能:获取设备屏幕的分辨率,用来判断坐标系的使用。
    函数语法:
      width,height = getScreenSize()

    参数说明:

    返回值类型说明
    width整数型获取到的屏幕宽度
    height整数型获取到的屏幕高度

    注意事项:

    统一为竖直(Home 键在下方时)屏幕的宽度和高度。

    函数:setScreenScale 设置屏幕缩放

    函数功能:设置当前脚本开发环境的屏幕分辩率,使脚本适配不同分辩率的设备。
    函数语法:
      setScreenScale(width, height, scale)

    参数说明:

    参数类型说明
    width整数型脚本开发时使用的设备宽度
    height整数型脚本开发时使用的设备高度
    scale整数型返回坐标缩放参数, 默认为0; 0 - 返回的坐标进行反向缩放,1 - 返回的坐标不缩放

      该函数使脚本根据开发环境的屏幕分辩率和当前使用环境分辨率自动将脚本里XY坐标进行等比换算
      受影响命令包括:

    • touchDown、touchUp、touchMove
    • findColor、findColors
    • findColorInRegionFuzzy、findMultiColorInRegionFuzzy、findMultiColorInRegionFuzzy2
    • findMultiColorInRegionFuzzyExt、findMultiColorInRegionFuzzyExt2
    • getColor、getColorRGB
    • showHUD
    • ocr:getText
    • binarizeImage

    脚本实例:
    假设一名作者在540*960分辨率的手机中开发了脚本,要在720*1280的设备中运行

     
    1. setScreenScale(540,960) --或者setScreenScale(540,960,0)效果相同
    2.  
    3. touchDown(0, 100, 200) --此处实际点击坐标为:100*(720/540),200*(1280/960)
    4. mSleep(50)
    5. touchMove(0, 100, 200) --此处实际移动坐标为:100*(720/540),200*(1280/960)
    6. mSleep(50)
    7. touchUp(0, 100, 200)
    8.  
    9. x, y = findMultiColorInRegionFuzzy(0x181F85, "29|1|0x00BBFE", 100, 0, 0, 400, 600)
    10.  
    11. --此处实际查找范围为坐标(0,0)到(400*720/540,600*1280/960),同时坐标偏移也进行换算,即匹配首点x,y坐标后,再比对(x+29*720/540,y+1*1280/960)这个坐标是否为"0x00BBFE"
    12.  
    13. if x~=-1 then
    14. touchDown(0, x, y) --第三参数为0或省略情况下返回的坐标为经过反向缩放的坐标,
    15. mSleep(100)
    16. touchUp(0, x, y)
    17. end
    18.  

    注意事项:

    1.通分辨率取色要点:取色点周边颜色相近为佳,由于字体或图形边缘线的点就很可能由于缩放而消失,导致找色失败。
    2.只适用等比例分辨率:例如540*960,720*1280都是9:16就可通用,而540*960与400*800的一般不通用。
    3.在最小分辨率开发,同比例的大分辨可用。例如:540*960下开发的脚本,在720*1280可用,反过来,一般不能通用。

    函数:mTime 获取Unix时间戳

    函数功能:显示从1970年到现在经过的毫秒数
    函数语法:
      t = mTime()

    参数说明:

    返回值类型说明
    t整数型表示从1970年到现在经过的毫秒数

    脚本实例:

     
    1. sysLog('mTime:' .. mTime())

    函数:getNetTime 获取网络时间

    函数功能:获取GMT时区从1970年到现在经过的秒数
    函数语法:
      t = getNetTime()

    参数说明:

    返回值类型说明
    t整数型表示网络时间GMT时区从1970年到现在经过的秒数,无网络情况下返回值为0

    脚本实例:

     
    1. sysLog("NetTime:" .. getNetTime())

    函数:pressHomeKey 模拟主屏幕按键

    函数功能:模拟用户点击主屏幕按键的操作。
    函数语法:
      pressHomeKey()

    参数说明:
    返回值:无

    函数:doublePressHomeKey 双击HOME键

    函数功能:模拟用户双击HOME键的操作,用于打开后台。
    函数语法:
      doublePressHomeKey()

    参数说明:
    返回值:无

    脚本实例:

    • 双击HOME键打开后台
     
    1. doublePressHomeKey();

    函数:pressKey 导航栏按键

    函数功能:模拟用户点击导航栏按键的操作,仅安卓适用
    函数语法:
      ret = pressKey(keyname,mode)

    参数说明:

    参数/返回值类型说明
    keyname文本型必填参数,为'BACK','MENU'和'HOME'三项之一
    mode逻辑型可选参数,控制是否长按,true表示长按,false表示不长按
    ret文本型返回值为0时表示成功

    脚本实例:
    ret = pressKey('BACK',false)

    函数:setWifiEnable 设置无线局域网开关

    函数功能:设置无线局域网开关
    函数语法:
      setWifiEnable(flag)

    参数说明:

    参数类型说明
    flag逻辑型打开WIFI - true; 关闭WIFI - false
    返回值类型说明
    ret逻辑型开关设置变更前的状态 false - 关闭;true - 开启

    脚本实例:

     
    1. setWifiEnable(true); --打开 Wifi
    2. setWifiEnable(false); --关闭 Wifi

    函数:setAirplaneMode 设置飞行模式开关

    函数功能:设置飞行模式开关
    函数语法:
      setAirplaneMode(flag)

    参数说明:

    参数类型说明
    flag逻辑型打开飞行模式 - true;关闭飞行模式 - false
    返回值类型说明
    ret逻辑型开关设置变更前的状态 false - 关闭;true - 开启

    脚本实例:

     
    1. setAirplaneMode(true); --打开 飞行模式
    2. setAirplaneMode(false); --关闭 飞行模式

    函数:setBTEnable 设置蓝牙开关

    函数功能:设置蓝牙开关
    函数语法:
      setBTEnable(flag)

    参数说明:

    参数类型说明
    flag逻辑型打开蓝牙 - true;关闭蓝牙 - false
    返回值类型说明
    ret逻辑型开关设置变更前的状态 false - 关闭;true - 开启

    脚本实例:

     
    1. setBTEnable(true); --打开 蓝牙
    2. setBTEnable(false); --关闭 蓝牙

    函数:lockDevice 锁定设备

    函数功能:锁定设备并关闭屏幕,仅支持iOS。
    函数语法:
      lockDevice()

    参数说明:
    返回值:无

    脚本实例:

     
    1. lockDevice();
    2. lua_exit();

    函数:unlockDevice 解锁设备

    函数功能:解除屏幕锁定状态,仅支持iOS。
    函数语法:
      unlockDevice()

    参数说明:
    返回值:无

    脚本实例:

    • 解锁设备
     
    1. flag = deviceIsLock(); --判断屏幕锁定状态
    2. if flag == 0 then
    3. dialog("未锁定",3);
    4. else
    5. unlockDevice(); --解锁
    6. end

    注意事项:

    1.如果设备设置了锁屏密码,则此函数只能唤醒屏幕。

    函数:deviceIsLock 设备锁定状态

    函数功能:判断当前设备的屏幕锁定状态
    函数语法:
      flag = deviceIsLock()

    参数说明:

    返回值类型说明
    flag整数型0 == 表示设备未锁定;非0 == 表示设备已锁定

    脚本实例:

    • 判断设备是否锁定
     
    1. flag = deviceIsLock(); --判断屏幕锁定状态
    2. if flag == 0 then
    3. dialog("未锁定",3);
    4. else
    5. unlockDevice(); --解锁
    6. end

    函数:vibrator 手机振动

    函数功能:使手机振动一次。
    函数语法:
      vibrator()

    参数说明:
    返回值:无

    脚本实例:

     
    1. for var = 1,5 do
    2. vibrator(); --振动
    3. mSleep(1000); --持续 1 秒
    4. end

    注意事项:

    1.使用此函数需在移动设备设置里打开震动选项。

    函数:resetIDLETimer 重置锁屏时间

    函数功能:重置系统空闲时间,阻止自动锁屏,保持屏幕常亮。
    函数语法:
      resetIDLETimer()

    参数说明:
    返回值:无

    脚本实例:

    • 保持屏幕常亮
     
    1. while true do
    2. mSleep(30 * 1000); --等待 30 秒
    3. resetIDLETimer(); --重置锁屏计时
    4. end

    注意事项:

    安卓暂不支持此功能。

    函数:resetScreenScale 取消屏幕缩放

    函数功能:取消屏幕比例缩放设置,一般与setScreenScale配套使用。
    函数语法:
      resetScreenScale()

    参数说明:
    返回值:无

    脚本实例:

     
    1. setScreenScale(540,960) --或者setScreenScale(540,960,0)效果相同
    2. resetScreenScale() --取消缩放

    函数:playAudio 播放音频

    函数功能:在后台播放指定的声音文件
    函数语法:
      playAudio(file)

    参数说明:

    参数类型说明
    file文本型音频文件名,支持mp3

    返回值:无

    脚本实例:

     
    1. playAudio("music.mp3") -- 播放音乐文件music.mp3
    2. mSleep(5000)
    3. stopAudio() --停止播放音频文件

    注意事项:

    1.如果播放一个音频文件后,使用此函数播放另一音频文件,将会先停止正在播放的音频,再播放第二段音频文件。
    2.用于播放的音乐文件需置于脚本对应的res文件夹内。

    函数:stopAudio 停止播放音频

    函数功能:停止正在播放的音频
    函数语法:
      stopAudio()

    参数说明:
    返回值:无

    脚本实例:

     
    1. playAudio("music.mp3") -- 播放音乐文件music.mp3
    2. mSleep(5000)
    3. stopAudio() --停止播放音频文件

    注意事项:

    如果播放一个音频文件后,使用此函数播放另一音频文件,将会先停止正在播放的音频,再播放第二段音频文件。

    函数:setTimer 规定时间之后调用指定函数

    函数功能:规定时间之后,调用指定的函数,同时把参数输入
    函数语法:
      setTimer(time,func,arg1,arg2,...)

    参数说明:

    参数类型说明
    time数字型当前时间到调用函数的时间间隔,毫秒
    func函数需要调用的函数名称
    arg1,arg2,...变量调用指定的函数时需要输入的参数,不定项

    返回值:无

    脚本实例:

     
    1. --每隔2000毫秒toast提示一次a+b+c的结果
    2. function func(a,b,c)
    3. toast(a+b+c)
    4. a=a+1
    5. b=b+1
    6. c=c+1
    7. setTimer(2000,func,a,b,c)
    8. end
    9.  
    10. setTimer(2000,func,0,1,2)
    11.  
    12. --等待运行
    13. mSleep(2000)
    14. mSleep(2000)
    15. mSleep(2000)
    16. mSleep(2000)
    17. mSleep(2000)

    注意事项:

    1.如定义了一段时间运行的函数,需在函数调用之前预留充裕的时间。
    2.支持引擎版本:1.7.4或更新

    函数:setSysConfig 设置系统参数

    函数功能:设置系统参数,脚本API行为受这些参数决定
    函数语法:
      setSysConfig(key,value)

    参数说明:

    参数类型说明
    key文本型要设置的系统参数项目
    value文本型该API行为的控制选项

    返回值:无

    可设置系统参数:

    设置项目(key)控制选项说明(value)
    isLogFile:令系统日志sysLog写入到文件中0 - 关闭,1 - 开启

    脚本实例:

     
    1. --设置开启将API:系统日志sysLog写入到文件。
    2. setSysConfig("isLogFile","1")
    3.  
    4. --设置关闭将API:系统日志sysLog写入到文件。
    5. setSysConfig("isLogFile","0")

    日志文件路径

    • 开发助手
      Android:/sdcard/com.xxscript.idehelper/tengine/log/user/脚本名.log
      iOS:/tmp/user/脚本名.log

    • 叉叉助手
      Android:/sdcard/com.xxAssistant/tengine/log/user/脚本id.log
      Android免Root:/sdcard/com.noroot/tengine/log/user/脚本id.log
      iOS:/tmp/user/脚本id.log

    • 叉叉小精灵
      Android:/sdcard/小精灵包名/tengine/log/user/脚本id.log

    • IPA精灵
      IPA精灵:应用文件夹/Document/Temp/脚本id.log
      IPA精灵(开发版):应用文件夹/Document/Temp/脚本名.log

    注意事项:

    1.支持引擎版本:1.9.00或更新.
    2.安卓叉叉小精灵应用内可直接查看日志,小精灵需更新到1.0.8或以上。

    函数:mSleep 延时

    函数功能:发送系统等待事件。
    函数语法:
      mSleep(interval)

    参数说明:

    参数类型说明
    interval整数型单位为毫秒,脚本暂停执行的时间长度

    脚本实例:

    • 延迟5秒
     
    1. mSleep(5000);
    • 长按 3 秒
     
    1. touchDown(1, 200, 300); --按下
    2. mSleep(3000); --延迟 3 秒
    3. touchUp(1, 200, 300); --抬起

    注意事项:

    1.延迟函数一般是用来模拟人在界面上的操作,因此要考虑人在各种情况下的延迟、界面加载时的响应时间。
    2.延迟间隔不可过短,当 interval <= 50 ms 时,延迟精确度大幅下降,当 interval <= 16 ms 时,实际延迟约在16 ms左右。
    3.请勿将此函数用于长时间的精确计时。
    4.1 秒 (s) = 1000 毫秒 (ms)。

    函数:toast 提示

    函数功能:以HUD方式显示提示信息。
    函数语法:
      toast(text)

    参数说明:

    参数类型说明
    text文本型提示信息,将在设备屏幕上以HUD形式显示,2秒后消失

    返回值:无

    脚本实例:

    • 欢迎使用
     
    1. toast("欢迎使用叉叉脚本!");
    2. mSleep(1000);
    3. toast("本脚本仅供演示toast函数效果。\n提示信息可以换行。");

    注意事项:

    该函数所产生的提示信息将以HUD形式显示在屏幕上,该函数所产生的提示信息可能会影响当前屏幕的找色,请合理使用。

    函数:dialog 提示框

    函数功能:弹出提示信息
    函数语法:
      dialog(text, time)

    参数说明:

    参数类型说明
    text文本型提示信息,将在设备屏幕上以弹窗形式显示
    time整数型提示信息显示的时间,不限时间请填0

    返回值:无

    脚本实例:

    • 欢迎使用
     
    1. dialog("欢迎使用叉叉脚本!", 5);
    2. mSleep(1000);
    3. dialog("本脚本仅供演示对话框的用法。\n提示信息可以换行。",0);

    注意事项:

    1.time 参数时间设置过短有可能因出现时间太短看不清楚。
    2.该函数仅供呈现提示信息给用户,不可接收返回值。
    3.该函数所产生的提示窗口显示的时候会影响当前屏幕取色,请在合理的位置使用该函数。
    4.关于转义字符:\n 为换行,请查阅 Lua 转义字符表。
    5.time 参数可省略,如省略将按 0 处理。

    函数:dialogRet 带按钮的对话框

    函数功能:弹出提示信息,并提供 1 ~ 3 个按钮给用户选择。
    函数语法:
      choice = dialogRet(text, cbtn, btn1, btn2, time)

    参数说明:

    参数类型说明
    Text文本型提示信息
    cbtn文本型默认按钮标题,不需要请填 ""
    btn1文本型可选按钮 1,不需要请填 ""
    btn2文本型可选按钮 2,不需要请填 ""
    time整数型提示信息显示的时间,不限时间请填 0
    返回值类型说明
    choice整数型返回用户按下按钮的序号 cbtn == 0;btn1 == 1;btn2 == 2;如用户在规定显示时间内未进行选择,返回值为 -1

    脚本实例:

    • 选择屏幕方向(二选一)
     
    1. choice = dialogRet("请选择您的屏幕方向:", "横屏", "竖屏", "", 0);
    • 选择屏幕方向(三选一)
     
    1. choice = dialogRet("请选择您的屏幕方向:", "HOME键在下", "HOME键在左", "HOME键在右", 0);
    • 请阅读许可协议
     
    1. dialogRet("请花30秒仔细阅读该许可协议。", "", "", "", 30);

    注意事项:

    1.请勿将三个按钮都设置为空,再将 time 参数设置为 0,这样将造成出现无法消失也没有按钮的 对话框,造成设备无法进行其它操作,只能重启。

    函数:dialogInput 带参数的对话框

    函数功能:弹出提示信息,并提供 1 ~ 2 个编辑框给用户输入。
    函数语法:
      text_a,text_b = dialogInput(title, format, btn)

    参数说明:

    参数类型说明
    title文本型提示标题
    format文本型编辑框中浅色的提示文字
    btn文本型确认按钮标题
    返回值类型说明
    text_a,text_b文本型返回用户输入的文本

    脚本实例:

    • 输入重复打本的次数
     
    1. text_a = dialogInput("请输入循环副本的次数", "在这里输入次数", "确认");
    2. mSleep(1000);
    • 输入打副本的设置和次数
     
    1. text_a, text_b = dialogInput("请输入使用的设置方案","在这里输入方案编号#在这里输入次数","确认");
    2. mSleep(1000);
    3. if text_b ~= "" and text_a ~= "" then --如果均已填写
    4. dialog("打本信息:"..text_b.." 次数 "..text_a.." 。", 5);
    5. mSleep(1000);
    6. else --未填写完整
    7. dialog("请完整填写打本的设置信息", 5);
    8. mSleep(1000);
    9. lua_exit()
    10. end

    注意事项:

    1.使用该函数都要对用户输入的数据进行一定的检查,例如要求非空、长度不得少于。
    2.需要注意使用双编辑框时,函数返回的两个字符串顺序与 format中的顺序相反。
    3.由于对话框事件需要响应时间,所以建议使用对话框时配合设置相应的延迟。

    函数:sysLog 系统日志

    函数功能:输出系统日志 NSLog
    函数语法:
      sysLog(contents)

    参数说明:

    参数类型说明
    content文本型需要显示的日志内容

    返回值:无

    注意事项:

    1.该函数将日志输出到对应平台的开发窗口
    2.该函数可通过setSysConfig设置项"isFileLog"设置为写入日志到文件,详情查看“setSysConfig 设置系统参数”条目(引擎支持:需1.9.00或更新)。

    函数:fileLogWrite 输出日志到文件

    函数功能:输出日志到文件
    函数语法:
      fileLogWrite(file,date,tag,msg)

    参数说明:

    参数类型说明
    file文本型日志名
    date整数型文件名是否添加日期后缀,0-不添加,1-添加。选择1的文件名称-/tmp/Good-20170401.log
    tag文本型标签,便于查看日志
    msg文本型写入日志文件的内容

    返回值:无

    脚本实例:

     
    1. fileLogWrite("Name",1,"INFO","这是写入日志文件的内容")

    注意事项:

    1.该函数目前仅支持开发助手
    2.该函数将日志输出到对应平台日志文件路径:
    android:/sdcard/
    iOS越狱:/tmp/
    3.支持引擎版本:1.7.4或更新

    函数:getCloudContent 获取云端自定义公告

    函数功能:获取开发者平台公告服务模块中表单的内容
    函数语法:
      content, err = getCloudContent(key,token,default_msg)

    参数说明:

    参数类型说明
    key文本型指定需要获取公告服务表中的key值
    token文本型开发助手调试中用于获取公告服务测试环境表单中数据的调试口令,在开发者平台中获取
    default_msg文本型(选填)获取key对应value值失败时,将该默认值作为结果返回
    返回值类型说明
    content文本型从公告服务表单中取得对应的value值,正式环境与测试环境的数据分别配置
    err整数型返回错误的类型:0 - 正常获取,1 - 网络错误,999 - 未知错误

    脚本实例:

    • 从开发者平台中配置的数据表中获取文本作为公告发布
     
    1. content, err = getCloudContent("key", "此处十六位调试口令", "没有正确获取到公告信息")
    2.  
    3. sysLog(string.format("getCloudContent return content = %s, err = %s", tostring(content), tostring(err)));
    4.  
    5. if err == 0 then
    6. dialog(content)
    7. elseif err == 1 then
    8. dialog("网络错误")
    9. elseif err == 999 then
    10. dialog("未知错误")
    11. end
    12.  

    注意事项:

    1.调试口令在开发者平台中生成,用于开发助手测试时获取测试环境的公告服务表单使用,正式环境中该密钥参数不生效。
    2.该API需要保证网络通畅才能获取到对应信息,请勿用于存放重要信息。
    3.支持引擎版本:1.7.5或更新。

    函数:setStringConfig 存字符串

    函数功能:将字符串存入配置文件
    函数语法:
      setStringConfig("key","string")

    参数说明:

    参数类型说明
    key1文本型将要写入的参数名称
    string1文本型将要写入参数的内容

    返回值:无

    脚本实例:

     
    1. sex = getStringConfig("gender","male");
    2. toast(sex) -- 未对“gender”进行新的赋值,toast结果为默认值"male"
    3. setStringConfig("gender","female");
    4. sex = getStringConfig("gender","male");
    5. toast(sex) -- toast结果为新的赋值"female"

    函数:getStringConfig 取字符串

    函数功能:读取配置文件的字符串
    函数语法:
      ret = getStringConfig("key","default_string")

    参数说明:

    参数类型说明
    key1文本型将要读取的参数名称
    default_string文本型参数"key1"所对应的默认值,如果没有对key1进行新的赋值,或无法找到对key1的赋值,将返回默认值“default_string”
    返回值类型说明
    ret文本型获取到名为"key1"的参数当前的值

    脚本实例:

     
    1. sex = getStringConfig("gender","male");
    2. toast(sex) -- 未对“gender”进行新的赋值,toast结果为默认值"male"
    3. setStringConfig("gender","female");
    4. sex = getStringConfig("gender","male");
    5. toast(sex) -- toast结果为新的赋值"female"

    函数:setNumberConfig 存入数值

    函数功能:将数值存入配置文件
    函数语法:
      setNumberConfig("key",num)

    参数说明:

    参数类型说明
    key2文本型将要写入的参数名称
    num1数字型将要写入参数的数值

    返回值:无

    脚本实例:

     
    1. a = getNumberConfig("age",18);
    2. toast(a) -- toast结果"18"
    3. setNumberConfig("age",20);
    4. a = getNumberConfig("age",18);
    5. toast(a) -- toast结果"20"

    函数:getNumberConfig 读取数值

    函数功能:读取配置文件的数值
    函数语法:
      num = getNumberConfig("key",default_num)

    参数说明:

    参数类型说明
    key2文本型将要读取的参数名称
    default_num数字型参数"key2"所对应的默认值,如果没有对key2进行新的赋值,或无法找到对key2的赋值,将返回默认值 default_num
    返回值类型说明
    num数字型获取到名为"key2"的参数当前的值

    脚本实例:

     
    1. a = getNumberConfig("age",18);
    2. toast(a) -- toast结果"18"
    3. setNumberConfig("age",20);
    4. a = getNumberConfig("age",18);
    5. toast(a) -- toast结果"20"

    函数:readPasteboard 读取剪贴板

    函数功能:读写系统剪贴板
    函数语法:
      string = readPasteboard()

    参数说明:

    返回值类型说明
    string文本型写入或读出的剪贴板字符串

    脚本实例:

    • 从剪贴板中写出到编辑框
     
    1. string = readPasteboard(); --读取剪贴板内容
    2. mSleep(1000); --延迟 1 秒等待响应
    3. inputText(string); --输入字符串

    函数:writePasteboard 写入剪贴板

    函数功能:读写系统剪贴板
    函数语法:
      writePasteboard(string)

    参数说明:

    参数类型说明
    string文本型写入的剪贴板字符串

    返回值:无

    脚本实例:

    • 从文件中读入一行并储存到剪贴板
     
    1. file = io.open("test.txt" ,"r"); --以只读方式打开一个文本文件
    2. if file then --如打开成功
    3. writePasteboard(file:read()); --写入到剪贴板
    4. file:close(); --关闭文件
    5. end

    注意事项:

    1.该函数将覆盖系统剪贴板,如有重要数据储存在剪贴板请事先备份。

    函数:lua_exit 退出脚本执行

    函数功能:直接终止脚本。
    函数语法:
      lua_exit()
      

    参数说明:
    返回值:无

    脚本实例:

    • 弹出提示框,确认退出则结束脚本执行
     
    1. ret = dialogRet("该脚本不支持当前手机分辨率", "继续", "退出","",0);
    2. if ret == 0 then --如果按下"继续"按钮
    3. init("0",0); --开始初始化
    4. else
    5. lua_exit(); --否则退出脚本
    6. end

    函数:lua_restart 重载脚本

    函数功能:重新加载运行脚本
    函数语法:
      lua_restart()
      

    参数说明:
    返回值:无

    注意事项:

    此函数作用相当于停止脚本后重新运行脚本。

    函数:onBeforeUserExit 脚本运行终止回调

    函数功能:在用户主动终止脚本运行之前执行的回调函数
    函数语法:
      onBeforeUserExit()

    参数说明:
    返回值:无

    脚本实例:

    • 当用户在脚本运行过程中主动停止脚本,将会触发 onBeforeUserExit 函数并执行函数体内的语句
     
    1. function onBeforeUserExit()
    2. dialog("OK",0)
    3. end
    4. for var = 1,30 do
    5. mSleep(1000)
    6. sysLog("var")
    7. end

    注意事项:

    1.函数名必须为 onBeforeUserExit才能够被识别(旧版本为beforeUserExit,依然兼容),请勿在函数体中使用死循环,否则会造成脚本无法终止或其他不可预料的问题。
    2.此函数可以被 lua_exit()、悬浮窗停止、远程接口停止 触发。

    函数:getEngineVersion 获取脚本引擎的版本号

    函数功能:获取当前应用使用中的脚本引擎的版本号
    函数语法:
      ver = getEngineVersion()

    参数说明:

    返回值类型说明
    ver文本型返回当前引擎的版本号

    脚本实例:

     
    1. ver = getEngineVersion()
    2. sysLog(string.format('当前版本号: %s', ver))

    函数:getOSType 获取系统类型

    函数功能:获取系统类型
    函数语法:
      ver = getOSType()

    参数说明:

    返回值类型说明
    ver文本型返回当前系统的类型;android系统返回“android”,iOS系统返回“iOS”

    脚本实例:

     
    1. ver = getOSType()
    2. if ver == "android" then
    3. sysLog("安卓系统")
    4. elseif ver == "iOS" then
    5. sysLog("苹果系统")
    6. end

    函数:isPrivateMode 获取系统环境类型

    函数功能:获取系统环境类型
    函数语法:
      ver = isPrivateMode()

    参数说明:

    返回值类型说明
    ver文本型返回当前系统的类型:返回值1、0;1-越狱/ROOT环境;0-免越狱/免ROOT环境

    脚本实例:

     
    1. ver = isPrivateMode()
    2. if ver == 0 then
    3. toast("当前为免越狱/免ROOT环境")
    4. elseif ver == 1 then
    5. toast("当前为越狱/root环境")
    6. end

    注意事项:

    1.isPriviateMode支持引擎版本:1.7.4或更新
    2.isPrivateMode支持引擎版本:1.8.30或更新

    函数:getSystemProperty 获取系统常量属性

    函数功能:获取系统常量属性,仅安卓可用
    函数语法:
      value = getSystemProperty('key')

    参数说明:

    参数类型说明
    key文本型CPU构架 - 'ro.arch'; 手机产品号 - 'ro.build.product'
    返回值类型说明
    value文本型返回所获取的系统常量属性结果

    脚本实例:

     
    1. sysLog('CPU构架: ' .. getSystemProperty('ro.arch'))
    2. sysLog('手机产品号:' .. getSystemProperty('ro.build.product'))

    函数:getLocalInfo 获取当前系统语言属性

    函数功能:获取当前系统语言属性
    函数语法:
      ret = getLocalInfo()

    参数说明:

    返回值类型说明
    ret文本型获取到的当前系统语言,格式:语言-国家,例如:zh-CN, es-US,用于支持多语言脚本适配

    脚本实例:

     
    1. ret = getLocalInfo()
    2. sysLog(string.format('当前系统语言: %s', ret))

    函数:getUserID 获取用户ID

    函数功能:获取用户的识别ID
    函数语法:
      id = getUserID()

    参数说明:

    返回值类型说明
    id文本型表示拿到的用户的ID,没有登录时则返回null

    脚本实例:

     
    1. sysLog("id: "..getUserID())

    函数:getScriptID 获取脚本ID 5-120601152328.png-0.2kB

    函数功能:获取脚本的识别ID
    函数语法:
      id = getScriptID()

    参数说明:

    返回值类型说明
    id文本型表示拿到的脚本上架的ID,否则返回-1

    脚本实例:

     
    1. sysLog("id: "..getScriptID())

    注意事项:

    支持引擎版本:1.8.30或更新

    函数:getScreenDPI 获取当前设备屏幕DPI

    函数功能:获取当前设备屏幕DPI,仅安卓适用
    函数语法:
      ret = getScreenDPI()

    参数说明:

    返回值类型说明
    ret文本型返回的当前设备屏幕DPI

    脚本实例:

     
    1. ret = getScreenDPI()
    2. sysLog(string.format('当前设备屏幕DPI: %s', ret))

    函数:getDeviceIMEI 获取当前设备IMEI码

    函数功能:获取当前设备IMEI码,仅安卓适用
    函数语法:
      ret = getDeviceIMEI()

    参数说明:

    返回值类型说明
    ret文本型返回的当前设备IMEI码

    脚本实例:

     
    1. ret = getDeviceIMEI()
    2. sysLog(string.format('当前设备IMEI码: %s', ret))

    函数:getDeviceIMSI 获取当前设备IMSI码

    函数功能:获取当前设备IMSI码,仅安卓适用
    函数语法:
      ret = getDeviceIMSI()

    参数说明:

    返回值类型说明
    ret文本型返回的当前设备IMSI码

    脚本实例:

     
    1. ret = getDeviceIMSI()
    2. sysLog(string.format('当前设备IMSI码: %s', ret))

    函数:getDeviceUUID 获取当前设备UUID

    函数功能:获取当前设备UUID,仅iOS适用
    函数语法:
      ret = getDeviceUUID()

    参数说明:

    返回值类型说明
    ret文本型返回的当前设备UUID

    脚本实例:

     
    1. ret = getDeviceUUID()
    2. sysLog(string.format('当前设备UUID: %s', ret))

    函数:getBatteryLevel 获取电池状态

    函数功能:获取电池充电状态、电量
    函数语法:
      charge,level = getBatteryLevel()

    参数说明:

    返回值类型说明
    charge整数型0表示没充电,1表示充电 (充电状态未知返回-1,同时剩余电量为-1)
    level整数型表示剩余电量,0-100

    脚本实例:

     
    1. charge,level = getBatteryLevel()
    2. if charge == 0 then
    3. toast("当前电池未充电,电量剩余 "..level)
    4. elseif charge == 1 then
    5. toast("当前电池充电中,电量剩余 "..level)
    6. elseif charge == -1 then
    7. toast("当前电池充电状态未知,电量剩余未知")
    8. end

    注意事项:

    1.支持引擎版本:1.7.4或更新

    函数:getScreenDirection 获取屏幕方向

    函数功能:获取设备当前屏幕方向
    函数语法:
      ret = getScreenDirection()

    参数说明:

    返回值类型说明
    ret整数型Android:0-竖屏, 1-橫屏; iOS:0-竖屏,1-横屏(Home右),2-横屏(Home左), -1(Unknow)

    脚本实例:

     
    1. ret = getScreenDirection()
    2. if ret == 0 then
    3. toast("当前屏幕方向为竖屏")
    4. elseif ret == 1 then
    5. ver = getOSType()
    6. if ver == "iOS" then
    7. toast("当前屏幕方向为横屏,HOME键在右")
    8. elseif ver == "android" then
    9. toast("当前屏幕方向为横屏")
    10. end
    11. elseif ret == 2 then
    12. toast("当前屏幕方向为横屏,HOME键在左")
    13. elseif ret == -1 then
    14. toast("当前屏幕方向Unknow")
    15. end

    注意事项:

    1.iOS版开发助手中该函数返回值跟随init指定的方向,未指定的情况下返回值为-1。
    2.支持引擎版本:1.7.4或更新

    函数:getUserCredit 获取用户付费类型和套餐剩余时间

    函数功能:获取用户付费类型和套餐剩余时间
    函数语法:
      buyState,validTime,res=getUserCredit()

    参数说明:

    返回值类型说明
    buyState整数型用户付费类型,1 - 付费用户,2 - 试用用户,3 - 免费用户,0 - 非购买非试用
    validTime整数型用户当前套餐购买时长,单位为秒,试用用户的情况下会返回0
    res整数型返回错误代码,0 - 正常, 非0 - 出错

    脚本实例:

     
    1. buyState,validTime,res=getUserCredit()
    2. if buyState ~= 0 then
    3. dialog("您是付费用户")
    4. end

    注意事项:

    1.支持引擎版本:1.8.30或更新

    函数:getRuntimeMode 获取脚本运行模式(安卓专用)

    函数功能:获取脚本运行模式,用于区分哪种运行模式跑脚本
    函数语法:
      int = getRuntimeMode()

    参数说明:

    返回值类型说明
    int整数型脚本运行模式,0 - 通用模式(当做“免root免激活”处理),1 - 低版本兼容模式(当做“免root免激活”处理),2 - 极客模式(root或者激活)

    脚本实例:

     
    1. int = getRuntimeMode()
    2. if int == 0 then
    3. dialog("当前模式:通用模式")
    4. end

    注意事项:

    1.支持引擎版本:1.9.312或更新

    函数:getProduct 获取当前运行产品

    函数功能:获取当前运行脚本产品
    函数语法:
      int = getProduct()

    参数说明:

    返回值类型说明
    int整数型1-叉叉/免root叉叉;2-内部使用;3-开发助手;4-内部使用;5-叉叉IPA精灵;6-叉叉小精灵;7-叉叉酷玩;8-叉叉云游

    脚本实例:

     
    1. --打印产品id
    2. product_id = getProduct()
    3. if product_id ~= nil then
    4. sysLog("product_id="..product_id);
    5. end

    注意事项:

    1.支持引擎版本:1.9.23或更新

    函数:createHUD 创建HUD内容

    函数功能:创建、显示、隐藏HUD内容
    函数语法:
      id = createHUD()

    参数说明:

    返回值类型说明
    id整数型用于标示HUD

    脚本实例:

     
    1. init("0",1)
    2. id = createHUD() --创建一个HUD
    3. showHUD(id,"欢迎使用叉叉脚本!",12,"0xffff0000","0xffffffff",0,100,0,228,32) --显示HUD内容
    4. mSleep(2000)
    5. showHUD(id,"HelloWorld!",12,"0xffff0000","msgbox_click.png",0,100,0,228,32) --变更显示的HUD内容
    6. mSleep(5000)
    7. hideHUD(id) --隐藏HUD
    8. mSleep(3000)

    注意事项:

    1.隐藏标示为id的HUD信息后,如需再次显示HUD信息内容,需要使用createHUD函数再次创建。
    2.ARGB---Alpha,Red,Green,Blue;A表示透明度,00代表完全透明,ff代表完全不透明。

    函数:showHUD 显示HUD内容

    函数功能:创建、显示、隐藏HUD内容
    函数语法:
      showHUD(id,text,size,color,bg,pos,x,y,width,height)

    参数说明:

    参数类型说明
    id整数型用于标示HUD
    text文本型提示信息,将在屏幕上以HUD形式显示
    size整数型表示提示信息的字体大小
    color文本型表示提示信息的字体颜色,格式为ARGB
    bg文本型表示提示信息的背景颜色,可以是ARGB,也可以是图片文件名称
    pos整数型表示提示信息的原点位置,0 - 左上角,1 - 居中,2 - 水平居中, 3 - 垂直居中
    x,y整数型表示提示信息相对原点的坐标偏移值
    width,height整数型表示提示信息显示的宽高

    返回值:无

    脚本实例:

     
    1. init("0",1)
    2. id = createHUD() --创建一个HUD
    3. showHUD(id,"欢迎使用叉叉脚本!",12,"0xffff0000","0xffffffff",0,100,0,228,32) --显示HUD内容
    4. mSleep(2000)
    5. showHUD(id,"HelloWorld!",12,"0xffff0000","msgbox_click.png",0,100,0,228,32) --变更显示的HUD内容
    6. mSleep(5000)
    7. hideHUD(id) --隐藏HUD
    8. mSleep(3000)

    注意事项:

    1.隐藏标示为id的HUD信息后,如需再次显示HUD信息内容,需要使用createHUD函数再次创建。
    2.ARGB---Alpha,Red,Green,Blue;A表示透明度,00代表完全透明,ff代表完全不透明。

    函数:hideHUD 隐藏HUD内容

    函数功能:创建、显示、隐藏HUD内容
    函数语法:
      hideHUD(id)

    参数说明:

    参数类型说明
    id整数型用于标示HUD

    返回值:无

    脚本实例:

     
    1. init("0",1)
    2. id = createHUD() --创建一个HUD
    3. showHUD(id,"欢迎使用叉叉脚本!",12,"0xffff0000","0xffffffff",0,100,0,228,32) --显示HUD内容
    4. mSleep(2000)
    5. showHUD(id,"HelloWorld!",12,"0xffff0000","msgbox_click.png",0,100,0,228,32) --变更显示的HUD内容
    6. mSleep(5000)
    7. hideHUD(id) --隐藏HUD
    8. mSleep(3000)

    注意事项:

    1.隐藏标示为id的HUD信息后,如需再次显示HUD信息内容,需要使用createHUD函数再次创建。
    2.ARGB---Alpha,Red,Green,Blue;A表示透明度,00代表完全透明,ff代表完全不透明。

    函数:asyncExec 异步网络请求

    函数功能:asyncExec 异步httpget、httppost请求
    函数语法:
      asyncExec({
       type,
       immediate,
       url,
       headers,
       content,
       callback
      })

    参数说明:

    参数类型说明
    type文本型目前仅支持httpgethttppost
    immediate逻辑型是否独立开启新线程运行(建议使用默认值false)
    url文本型请求地址
    headers文本型网络请求头设置,格式key1:value1#key2:value2#...
    content文本型httppost网络请求的附加数据
    callback函数网络请求结果回调函数,接受参数table = {code[int], data[string]}

    返回值:无

    脚本实例:

     
    1. local function urlencode(w)
    2. pattern = "[^%w%d%?=&:/._%-%* ]"
    3. s = string.gsub(w, pattern, function(c)
    4. local c = string.format("%%%02X", string.byte(c))
    5. return c
    6. end)
    7. s = string.gsub(s, " ", "+")
    8. return s
    9. end
    10.  
    11. -- 异步httpget请求
    12. asyncExec({
    13. type = "httpget", -- [string] 指定httpget类型
    14. immediate = false, -- [bool] 默认false, 设置true会独立开启线程执行任务
    15. url = urlencode("http://httpbin.org/get?x=测试x&y=测试y"), -- [string] 请求的URL地址,出现中文字符时需要使用urlencode进行编码
    16. callback = function (result) -- [function] 请求回调函数
    17. -- 回调结果table
    18. assert(type(result) == "table")
    19. --[[
    20. 返回数据格式: { code = [int]错误码, data = [string]服务器返回数据 }
    21. code -1: 请求出错
    22. -2: 请求超时
    23. -3: 强制关闭
    24. 其他: 同http status code
    25. ]]--
    26. sysLog("httpget callback: code = " .. result.code .. " data = " .. result.data)
    27. -- 注意: 虽然请求会异步执行, 但回调函数依然在lua主线程执行, 不要在回调里执行其他阻塞操作
    28. end
    29. })
    30.  
    31. -- 异步httppost请求
    32. asyncExec({
    33. type = "httppost", -- [string] 指定httppost类型
    34. immediate = true, -- [bool] 默认false, 设置true会独立开启线程执行任务
    35. url = "http:/httpbin.org/post", -- [string] 请求的URL地址
    36. headers = "User-Agent:Test-Agent#Accept-Language:zh-CN", -- [string] 请求头设置
    37. content = "test content 2", -- [string] post请求的数据
    38. callback = function (result) -- [function] 请求回调函数
    39. -- 回调结果table
    40. assert(type(result) == "table")
    41. -- httpget和httppost返回数据格式一致
    42. sysLog("httppost callback: code = " .. result.code .. " data = " .. result.data)
    43. end
    44. })
    45.  
    46. local t = 0
    47. while t < 10 do
    48. mSleep(1000)
    49. t = t + 1
    50. end

    注意事项:

    1.不论immediate为true还是false,asyncExec的网络请求总是会在Lua线程之外的线程运行,区别是immediate设置为false时,使用已有的常驻线程(sentinel thread)运行,多次运行使用同一个线程;而immediate为true是,会即时创建一个新的线程独立运行任务,多次运行创建多个线程
    2.headers设置仅在引擎版本1.8.30及以上生效,所有HTTP headers设置可以参阅 https://en.wikipedia.org/wiki/List_of_HTTP_header_fields

    函数:setUIOrientation 设置UI方向和HUD方向

    函数功能:设置UI方向和HUD方向,仅iOS可用
    函数语法:
      setUIOrientation(mode)

    参数说明:

    参数类型说明
    mode整数型用于设置UI及HUD的全局方向类型,0表示跟随游戏;1表示home在右侧;2表示home在左侧

    返回值:无

    脚本实例:

     
    1. init("",1)
    2. setUIOrientation(0)

    注意事项:

    1.只适用于iOS系统,Andorid系统不可用

    badboy开源工具库

    Badboy是专为叉叉脚本引擎开发的工具类,代码全部以开源的方式提供,目前有以下的模块:

    1. 进入https://github.com/boyliang/lua_badboy,下载项目源码;
    2. 把项目当中内容,复制到src目录下;
    3. 在main.lua中加入你的脚本逻辑;
    4. 使用xsp打包工具即完成out.xsp

    使用方法:
    请在脚本开头插入 local bb = require("badboy") 即可调用扩展库中所有函数。

    JSON模块

    newArray 新建数组对象
    newObject 新建对象
    decode json字符串转成talbe对象
    encode table对象转换成压缩的json字符
    encode_pretty table对象转换成优雅的json字符

    脚本实例:

     
    1. local bb = require("badboy")
    2. local json = bb.getJSON()
    3. local lua_value = json.decode('{"a": 1, "b":"boy", "c":{"d":1}}')
    4. local a_value = lua_value.a -- =1
    5. local b_balue = lua_value.b -- ="boy"
    6. local c_d_balue = lua_value.c.d -- =1
    7.  
    8. local raw_json_text = json.encode(lua_value)
    9. local pretty_json_text = json.encode_pretty(lua_value)
    10.  
    11. sysLog(raw_json_text)
    12. sysLog(pretty_json_text)

    StringUtils模块

    toCharTable 从字符串转字符数组
    fromCharTable 从字符数组转字符串
    toByteTable 从字符串转字节数组
    fromByteTale 从字节数组转字符串
    contains 是否包含子串
    startWith 是否以某个子串开头
    endsWith 是否以某个子中结束
    ...更多API请关注badboy项目源码文件\bblibs\StrUtilsAPI.lua

    脚本实例:

     
    1. local bb = require("badboy")
    2. local strutils = bb.getStrUtils()
    3. local str = 'i am a badboy'
    4.  
    5. --十六进制编码转换、SHA1计算、MD5计算
    6. local hex = str:tohex() -- 等同于 strutils.toHex(str)
    7. local sha1 = str:sha1() -- 等同于 strutils.SHA1(str)
    8. local md5 = str:md5() -- 等同于 strutils.md5(str)
    9.  
    10. sysLog('hex:' .. hex)
    11. sysLog('sha1:' .. sha1)
    12. sysLog('md5:' .. md5)
    13.  
    14. 输出内容:
    15. hex:69:20:61:6D:20:61:20:62:61:64:62:6F:79
    16. sha1:43386755b0ff2899e0a7895c45a0c051468d06cd
    17. md5:0663e75e1087668c30b527f5d9519185

    UI模块

    RootView:create 构造UI根对象
    RootView:addView 添加子view
    RootView:removeView 删除子view
    RootView:removeViewByID 删除子view
    Page:create 构建Page控件
    Page:addView 添加子view
    Page:removeView 删除子view
    Page:removeViewByID 删除子view
    Image:create 构造Image控件
    Edit:create 构造Edit控件
    Label:create 构造Label控件
    ...(所有属性都可以直接通过对象访问)

     
    1. local bb = require("badboy")
    2. bb.loaduilib()
    3. local json = bb.getJSON()
    4. local rootview = RootView:create({style = ViewStyle.CUSTOME})
    5. local page = Page:create("page")
    6. page.text = "Page1"
    7. local page2 = Page:create("page2")
    8. page2.text = "Page2"
    9. local label = Label:create("Label", {color = "255, 255, 0"})
    10. label.text = "I love XX"
    11. local image = Image:create("image")
    12. image.src = "bg.png"
    13. local edit = Edit:create("edit", {prompt = "提示"})
    14. edit.align = TextAlign.LEFT
    15.  
    16. local radiogroup = RadioGroup:create("radiogroup")
    17. radiogroup:setList('男', '女', '嬲', '奻')
    18. radiogroup:setSelect(3)
    19.  
    20. local checkboxgroup = CheckBoxGroup:create('checkboxgroup')
    21. checkboxgroup:setList('XX', 'OO', 'AA', 'BB')
    22. checkboxgroup:setSelects(2, 3)
    23.  
    24. rootview:addView(page) --把page添加到rootview
    25. rootview:addView(page2)
    26.  
    27. page:addView(label) --把label添加到page
    28. -- page:addView(label) --label的id重复,这里会报错
    29. page:addView(image) --把image添加到page
    30. page:addView(checkboxgroup)
    31. page:addView(radiogroup)
    32. page:removeView(label1) --从page中删除label
    33.  
    34. uijson = json.encode(rootview)
    35. showUI(uijson)

    POS模块

    distanceBetween 计算距离
    click 单击
    touchMoveTo 精确滑动
    angleBetween 计算角度
    polarProjection 根据角度和距离找点
    isColorClick 根据颜色进行点击

     
    1. local bb = require("badboy")
    2. local pos = bb.loadpos()
    3. p1 = pos:new(0, 0, 0x123456)
    4. p2 = pos:new(1, 2)
    5. sysLog(p1:distanceBetween(p2))
    6. sysLog(p1:angleBetween(p2))
    7. p2 = p1:polarProjection(4, 30)
    8. sysLogFmt('p2[%d, %d]', p2.x, p2.y)

    utils模块

    sysLogFmt 格式化字符串输出
    sysLogLst 任意内容输出
    tap 模拟一次点击
    swip 模拟一次滑动
    cmpColor 指定颜色对比

     
    1. -- utils test
    2. local bb = require("badboy")
    3. bb.loadutilslib()
    4. i = 3
    5. j = 6.9
    6. s = 'good boy'
    7. sysLogFmt('i=%d, j=%f, s=%s', i, j, s)
    8. sysLogLst(i, j, s)

    LuaSocket模块

    LuaSocket 是 Lua 的网络模块库,它可以很方便地提供 TCP、UDP、DNS、FTP、HTTP、SMTP、MIME 等多种网络协议的访问操作。详细使用说明关注badboy项目源码文件main.lua,API参考见http://w3.impa.br/~diego/software/luasocket/reference.html

    DNS

     
    1. local bb = require("badboy")
    2. bb.loadluasocket()
    3. local socket = bb.socket
    4. local dns = socket.dns
    5. sysLog('localhostIP: ' .. dns.toip('localhost'))
    6. sysLog('result: ' .. (dns.tohostname('59.37.96.63') or 'nil'))
    7. sysLog('hostname: ' .. dns.gethostname())
    8. sysLog('addinfo: ' .. tostring(dns.getaddrinfo('localhost')))

    httpGet请求

     
    1. local bb = require("badboy")
    2. bb.loadluasocket()
    3. local http = bb.http
    4. local ltn12 = bb.ltn12
    5. res, code = http.request('http://www.baidu.com')
    6. -- 等价于
    7. -- local response_body = {}
    8. -- res, code = http.request({
    9. -- url = 'http://www.baidu.com',
    10. -- sink = ltn12.sink.table(response_body)
    11. -- })
    12. if code == 200 then
    13. sysLog(res)
    14. dialog(res, 0)
    15. end
    16.  
    17. --获取外网ip地址
    18. local bb = require("badboy")
    19. bb.loadluasocket()
    20. local http = bb.http
    21. local res, code = http.request('http://www.ip.cn/');
    22. if code == 200 then
    23. local i,j = string.find(res, '%d+%.%d+%.%d+%.%d+')
    24. local ipaddr =string.sub(res,i,j)
    25. dialog(ipaddr, 0)
    26. end

    1.返回的2个参数中,res 是 http body 的内容,也就是请求网页的内容,code 是 http 状态码,返回200的话就表示正常返回。
    2.如果传入的是 table 的话,就需要用一个容器来接收 http body 的内容。

    httpPost请求

     
    1. local bb = require("badboy")
    2. bb.loadluasocket()
    3. local http = bb.http
    4. local response_body = {}
    5. local post_data = 'asd';
    6. res, code = http.request{
    7. url = 'http://127.0.0.1/post.php',
    8. method = "POST",
    9. headers =
    10. {
    11. ['Content-Type'] = 'application/x-www-form-urlencoded',
    12. ['Content-Length'] = #post_data,
    13. },
    14. source = ltn12.source.string('data=' .. post_data),
    15. sink = ltn12.sink.table(response_body)
    16. }

    1.这里注意记得 method 传入 POST, 因为默认是 GET。
    2.headers 参数,由一个 table 组成,key 为 header,value 为 header 内容。
    3.source 参数,这里是填入 POST 的参数,多个数据的情况用 & 隔开,例如 "data1=a&data2=b"。
    4.此代码仅为举例说明,请勿直接复制使用。

    挂载代理

     
    1. local bb = require("badboy")
    2. bb.loadluasocket()
    3. local http = bb.http
    4. http.PROXY = 'http://127.0.0.1:8888' --代理服务器地址
    5. local result, code = http.request('http://www.baidu.com')
    6. dialog(result or tostring(code), 0)

    以socket的方式访问

     
    1. local bb = require("badboy")
    2. bb.loadluasocket()
    3. local http = bb.http
    4. local host = 'www.baidu.com'
    5. local file = "/"
    6. local sock = assert(socket.connect(host, 80)) --创建一个 TCP 连接,连接到 HTTP 连接的标准 80 端口上
    7. sock:send('GET ' .. file .. ' HTTP/1.0\r\n\r\n')
    8. repeat
    9. local chunk, status, partial = sock:receive(1024) --以 1K 的字节块接收数据
    10. until status ~= 'closed'
    11. sock:close() -- 关闭 TCP 连接

    smtp方法发送email

     
    1. local bb = require("badboy")
    2. bb.loadluasocket()
    3. local smtp = bb.smtp
    4. from = '<youmail@126.com>' -- 发件人
    5. --发送列表
    6. rcpt = {
    7. '<youmail@126.com>',
    8. '<youmail@qq.com>',
    9. '<youmail@gmail.com>',
    10. }
    11. mesgt = {
    12. headers = {
    13. to = 'youmail@gmail.com', -- 收件人
    14. cc = '<youmail@gmail.com>', -- 抄送
    15. subject = "This is Mail Title"
    16. },
    17. body = "邮件内容"
    18. }
    19.  
    20. r, e = smtp.send{
    21. server = "smtp.126.com", --smtp服务器地址
    22. user = "youmail@126.com",--smtp验证用户名
    23. password = "******", --smtp验证密码
    24. from = from,
    25. rcpt = rcpt,
    26. source = smtp.message(mesgt)
    27. }
    28.  
    29. if not r then
    30. dialog(e, 0)
    31. else
    32. dialog('发送成功!', 0)
    33. end

    实现获取网络时间

     
    1. local bb = require("badboy")
    2. bb.loadluasocket()
    3. local socket = bb.socket
    4. server_ip = {
    5. "132.163.4.101",
    6. "132.163.4.102",
    7. "132.163.4.103",
    8. "128.138.140.44",
    9. "192.43.244.18",
    10. "131.107.1.10",
    11. "66.243.43.21",
    12. "216.200.93.8",
    13. "208.184.49.9",
    14. "207.126.98.204",
    15. "207.200.81.113",
    16. "205.188.185.33"
    17. }
    18.  
    19. local function nstol(str)
    20. assert(str and #str == 4)
    21. local t = {str:byte(1,-1)}
    22. local n = 0
    23. for k = 1, #t do
    24. n= n*256 + t[k]
    25. end
    26. return n
    27. end
    28.  
    29. local function gettime(ip)
    30. local tcp = socket.tcp()
    31. tcp:settimeout(10)
    32. tcp:connect(ip, 37)
    33. success, time = pcall(nstol, tcp:receive(4))
    34. tcp:close()
    35. return success and time or nil
    36. end
    37.  
    38. local function nettime()
    39. for _, ip in pairs(server_ip) do
    40. time = gettime(ip)
    41. if time then
    42. return time
    43. end
    44. end
    45. end
    46.  
    47. dialog(nettime(),0)

    统计毫秒精度时间

     
    1. local bb = require("badboy")
    2. bb.loadluasocket()
    3. local socket = bb.socket
    4. local function sleep(sec)
    5. socket.select(nil,nil,sec);
    6. end
    7. local t0 = socket.gettime()
    8. sleep(0.4);
    9. local t1 = socket.gettime()
    10. dialog(t1 - t0, 0)

    FTP 测试

     
    1. local bb = require("badboy")
    2. bb.loadluasocket()
    3.  
    4. -- [ftp://][<user>[:<password>]@]<host>[:<port>][/<path>][type=a|i]
    5. -- The following constants in the namespace can be set to control the default behavior of the FTP module:
    6. -- PASSWORD: default anonymous password.
    7. -- PORT: default port used for the control connection;
    8. -- TIMEOUT: sets the timeout for all I/O operations;
    9. -- USER: default anonymous user;
    10.  
    11. local ftp = bb.ftp
    12.  
    13. -- Log as user "anonymous" on server "ftp.tecgraf.puc-rio.br",
    14. -- and get file "lua.tar.gz" from directory "pub/lua" as binary.
    15. f, e = ftp.get("ftp://ftp.tecgraf.puc-rio.br/pub/lua/lua.tar.gz;type=i")
    16.  
    17. -- Log as user "fulano" on server "ftp.example.com",
    18. -- using password "silva", and store a file "README" with contents
    19. -- "wrong password, of course"
    20. f, e = ftp.put("ftp://fulano:silva@ftp.example.com/README", "wrong password, of course")
    21.  
    22. -- Log as user "fulano" on server "ftp.example.com",
    23. -- using password "silva", and append to the remote file "LOG", sending the
    24. -- contents of the local file "LOCAL-LOG"
    25. f, e = ftp.put{
    26. host = "ftp.example.com",
    27. user = "fulano",
    28. password = "silva",
    29. command = "appe",
    30. argument = "LOG",
    31. source = ltn12.source.file(io.open("LOCAL-LOG", "r"))
    32. }

    取色器使用说明

    • 取色器需连接到设备才能使用

    抓图说明:
    截图:于设备截图,会出现精度条圆圈标志,等待时间过长或其他意外情况 点击叉或者按Esc结束.截图后显示图片,右键图片名显示菜单,可关闭图片
    保存:保存当前图片
    载入:载入图片,也可以拖入图片
    左转:左边旋转90度
    右转:右边旋转90度
    放大:快捷键ctrl + 滚轮上, 放大当前图片
    缩小:快捷键ctrl + 滚轮下, 缩小当前图片
    1:1 :快捷键ctrl + o, 100%显示当前图片
    截图旋转方向: 截图默认旋转的方向
    Home键在下相当于init("0", 0)
    Home键在右相当于init("0", 1)
    Home键左相当于init("0", 2)

    尺寸显示:旋转后改变方向
    取色:快捷键 1,2,3,4,5,6,7,8,9,0 或鼠标右键菜单取色
    取色微调:键盘上下左右方向键移动

    取色器快捷键表

    数字键(1 2 3 4 5 6 7 8 9 0)
    分别取色到第1~10个位置

    Ctrl + 数字键(1 2 3 4 5 6 7 8 9 0)
    分别取色到11~20个位置

    A、S
    取 [坐标位 A] 和 [坐标位 S] 作为左上右下坐标到选择范围

    光标(↑ ↓ ← →)
    鼠标指针定位移动 1 个像素

    回车键/Ctrl + 鼠标左键点击
    取色到剪贴板的首个空白位置,已取色的位置不会被覆盖,如果无空白位置则不取色

    Shift + Delete
    清除已勾选的点色信息

    Ctrl + Shift + Delete
    清除所有点色信息

    F5
    刷新所有点色信息为当前图片的值

    Ctrl + L/Ctrl + R
    分别对代码窗口1、2的内容进行代码测试

    Shift + L/Shift + R
    分别复制代码窗口1、2的内容

    -
    缩小视图

    =
    放大视图

    Ctrl + Tab
    切换到下一个文档

    Ctrl + Shift + Tab
    切换到上一个文档

    放大镜功能说明:
    选择范围: A,S快捷键或 按钮点击选择范围.会出现红色线,按Esc键取消选择.注意选取范围时可鼠标滚动滚轮
    颜色数据反选:在复选框上按住鼠标左键往下或者往上拖动,移动范围内反选颜色数据
    可全选全删

    格式:自定义生成代码. 在IDE目录下data.lua可以编辑格式
    在datacolorfg中自己添加格式为:

     
    1. {
    2. title = "",
    3. fScript = function(poslist,area, degree)
    4. end,
    5. sScript = function (poslist,area, degree)
    6. end,
    7. }

    +

    •  
    •  
    •  
    •  
    •  
    •  
    •  
    展开全文
  • 交叉开发环境配置

    2020-07-08 15:59:45
    1、打开设备管理器 如果一切正常应该能看到 端口选项(USB-SERIAL CH340(COMX)) 如果接好线,也没有看到这个选项,看下有没有 《其它设备》这个选项,如果有,那么可能需要安装驱动(推荐使用驱动精灵安装) 如果上面...

    交叉开发

    1、交叉环境

    ​ 编译,就是把一种语言(如C语言) 翻译成 另一种语言(如机器语言)
    ​ 之前我们的编译环境 和 运行环境是相同的。

    交叉编译:
    也是编译,也是把一种语言翻译成另一种语言
    但是,在嵌入领域中, 很多时候程序的运行环境 不适合 去编写和编译程序。
    所以,我们把常规的 编写 编译 执行 的这几个步骤分开:
    在PC机上编写程序
    在PC机上编译程序
    最后通过一些特殊的工具,把生成的目标代码(如可执行文件)传输到目标设备(如GEC6818开发板)上去执行。

    ​ 简单的说,交叉编译 就是在一种环境下 去编译 另一种环境的程序。

    2、交叉编译器

    ​ 一般来说,交叉编译器由开发板厂商提供,也当然也可以自己去网上下载,如:
    ​ http://releases.linaro.org/components/toolchain
    ​ https://www.evryarm.com

    安装交叉编译器:
    *1、下载
    从官网下载
    从云盘下载
    从飞秋下载…
    gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabi.tar.xz
    可以使用指令uname -a查看系统版本:
    结果显示中包含 x86_64,就是64位的系统,简称x64
    结果显示中包含 i686,就是32位的系统,简称x86

    下载完成后,把压缩包放到Ubuntu系统中去(共享目录也行)

    2、解压
    把下载的压缩包解压到一个合适的目录(不能解压到共享目录!),如/usr/local/ 目录
    具体过程:
    1、进入压缩包所在的目录,并能查看到它
    cd /mnt/hgfs/Tools/交叉开发
    ls
    2、解压
    sudo tar xvf gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabi.tar.xz -C /usr/local/
    解压完成后,会在/usr/local目录下生成一个 gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabi 目录
    自动生成的目录略微过长,使用不便,所以,改成一个短一点的名字,如 arm-linux
    改名指令:
    sudo mv gcc-linaro-5.5.0-2017.10-x86_64_arm-linux-gnueabi arm-linux

    ​ 3、给交叉编译器创建软链接
    ​ 进入交叉编译工具链所在目录
    ​ cd /usr/local/arm-linux/bin
    ​ 把创建软链接的脚本拷贝到当前目录
    ​ sudo cp /mnt/hgfs/Tools/交叉开发/myln-x64.sh ./
    ​ 执行脚本
    ​ sudo ./myln-x64.sh
    ​ 4、配置环境变量
    ​ 为了能够在任意目录下都能使用交叉编译器,我们需要把交叉编译器所在的路径添加到环境变量PATH中去
    ​ 临时添加指令:
    ​ PATH=/usr/local/arm-linux/bin:$PATH
    ​ 请确保该指令是正确的!(=两边不能有空格,分配符是英文的冒号,PATH必须大写)

    ​ 如果需要永久生效,需要把上述指令写入系统的启动配置文件中,并把PATH导出为环境变量
    ​ 可以写入这些文件的最后面(已有内容不要修改,只是在后面追加),使得配置永久生效:
    ​ /etc/profile 对所有的普通用户有效,只要登录系统,系统会自动读取该文件中的配置信息
    ​ ~/.bashrc 对当前用户用效,只要登录系统,自动读取。
    ​ 具体指令:
    ​ 打开配置文本:
    ​ sudo vim /etc/profile
    ​ 按快捷键shift+g(把光标定位到文件的最后一行)
    ​ 按i键,进入插入模式,在最后一行的后面,写入配置指令
    ​ 配置指令:
    ​ export PATH=/usr/local/arm-linux/bin:$PATH
    ​ 写入完成后,保存退出(按esc键,再:wq),重启系统。

    ​ 5、测试是否配置成功
    ​ 打开终端,输入指令, 查看交叉编译器的版本信息:
    ​ arm-linux-gcc -v

    3、熟悉使用开发板

    ​ 开发板名称: GEC6818
    ​ 标准配置:
    ​ 底板
    ​ LCD液晶屏
    ​ 电源适配器
    ​ 串口线
    ​ USB-Serial线

    最简单基本的使用:
    接上电源,接好串口线,开机
    开机能看到登录界面 或 能看到粤嵌的LOGO图标

    PC机与开发板的连接,需要一些专门的软件,用于操作开发板上的系统,如:
    SecureCRT (我们选择这个)
    Xshell
    putty

    在第一次使用USB-Serial线连接开发板时,可能需要安装这根线的驱动!
    如何确认呢?
    1、打开设备管理器
    如果一切正常应该能看到 端口选项(USB-SERIAL CH340(COMX))
    如果接好线,也没有看到这个选项,看下有没有 《其它设备》这个选项,如果有,那么可能需要安装驱动(推荐使用驱动精灵安装)
    如果上面两个选项都没,那么请先关闭虚拟机,拔掉USB转串口线,重新接入。
    如果还不行,请检查线是否接好
    如果还不行,换一根确定是好的线再试一试。

    2、打开SecureCRT
    菜单-> 快速连接
    协议:serial
    端口:请查看设备管理器
    波特率:115200
    数据位:8 (默认就是,不要修改)
    奇偶校验: None(默认就是,不要修改)
    停止位:1(默认就是,不要修改)
    流控:都不要(去掉中间的那默认的勾)

    ​ 设置完成后,点击连接按钮即可。

    ​ 如果是先接线,再启动开发板,那么在SecureCRT界面,会看到系统的启动信息,启动时间6秒左右。
    ​ 启动成功后,按下回车,或输入其它的指令,以确认一切正常。

    3、第一次操作开发板
    创建自己的工作目录(类似PC端的家目录)
    mkdir /home/china -p
    以后每次开机,请先进入你的工作目录。
    以后尽量不要去随意修改(如创建/删除)工作目录之外的文件。

    4、通过串口传输文件到开发板
    rx(默认就有)
    常规使用步骤:
    1、rx 文件名
    2、回车
    3、菜单->传输->发送Xmodem
    4、在弹出的文件对话框中选择你需要传送的文件,即可
    5、稍等几秒钟,就能看到数据的传输过程
    6、如果要传输的文件是可执行文件,那么在执行之前需要添加可执行文件权限,指令如下:
    chmod +x 文件名
    7、按常规方式执行程序即可。
    rz(需要自己配置)
    1、进行自己的工作目录
    cd /home/china
    2、rx arm-rz.tar.xz
    3、发送完成后,解压
    tar xvf arm-rz.tar.xz
    4、进入解压生成的arm-rz目录
    5、执行该目录下的脚本
    7、使用rz时,原则上,输入rz后,直接回车就能弹出文件对话框
    如果要发送的文件在开发板上已经存在了,那么
    要么把已存在的文件删除
    要么rz -y
    5、从开发板传输文件到PC
    sz 文件名

    6、使用tftp网络服务把文件从Ubuntu中传输到开发板
    tftp是一个简单文件传输协议,是一个基于Client/Server的网络应用程序
    我们这里是把ubuntu18.04做为服务器,开发板是做为客户端的。
    客户端只需要网络畅通就行,而服务端需要做一些安装配置
    a.服务端的安装配置:
    1、先创建一个tftp服务目录,如:
    mkdir -p /home/china/tftpboot
    chmod 777 tftpboot
    2、下载安装
    sudo apt install tftpd-hpa
    3、配置
    打开配置文件:
    sudo vi /etc/default/tftpd-hpa
    修改该文件中的配置为:

    /etc/default/tftpd-hpa

    ​ TFTP_USERNAME=“tftp”
    ​ TFTP_DIRECTORY="/home/china/tftpboot" # 设置自己的服务目录
    ​ TFTP_ADDRESS=“0.0.0.0:69” # 设置IP地址,为本机的任意IP
    ​ TFTP_OPTIONS="-l -c -s" # 设置上传/下载的权限
    ​ 配置完成后,保存退出即可。

    ​ 4、重启tftp服务
    ​ sudo /etc/init.d/tftpd-hpa restart
    ​ 注:
    ​ 可以对tftp进行如下操作:
    ​ start 启动
    ​ restart 重启
    ​ stop 停止
    ​ status 查看状态

    ​ b.客户端配置
    ​ 客户端需要配置IP地址,配置IP有手动和自动之分
    ​ 使用指令 udhcpc 来自动获取IP地址,获取成功后,可使用ifconfig查看
    ​ 还可以使用 ping 网关IP ,来确认网络畅通

    ​ 使用tftp服务:
    ​ 1、把需要发送的文件 放到 tftp的服务目录,也就是 /home/china/tftpboot
    ​ 2、查看服务端的IP地址,也就是ubuntu的IP,使用指令ifconfig
    ​ 3、切换到SecureCRT, 进入工作目录
    ​ 4、执行下载指令:
    ​ tftp -g -r 文件名 服务端的IP
    ​ 例:
    ​ tftp -gr shui.mp3 192.168.2.157

    ​ 注:
    ​ 在使用tftp的过程中,可能会碰到一些常见的错误,如
    ​ 错误1: tftp: server error: (1) File not found
    ​ 解决方案:查看文件名是否正确,查看服务目录是否有你需要下载的文件

    ​ 错误2:tftp: timeout
    ​ 解决方案:检查服务端IP是否正确,检查网络是否畅通(ping 服务端IP), 网线有没有接好等

    ​ 错误3:tftp: sendto: Network is unreachable
    ​ 解决方案:请正确配置开发板的IP地址(在局域网内,推荐使用udhcpc)

    4、动态库和静态库

    1. 库 library
      库 是一种二进制的封装形式,简单的说,库中封装了一堆的目标文件(.o)
      当库封装好之后,就可以在其他(文件/程序)地方去使用它,但是用户是无法看到它的内部实现的。
      库的这种做法有利于 代码模块化,只要函数接口设计合理,改变库的内部实现,不会影响用户级别的代码使用。

    根据库的封装和链接格式,可以把库 分成 静态库 和 共享库(动态库)。

    1. 静态库
      静态库的特点:
      当把目标文件封装成静态库之后,如果有其它程序需要用到库中的功能,编译器会把相关代码直接拷贝到你的程序中去
      当程序编译完成后,运行时不再依赖静态库
      但是如果静态库更新了,你的程序必须再次编译
      创建静态库:
      1、编写源代码
      vi sum.h
      vi sum.c
      2、把源代码编译成目标文件
      gcc sum.c -c
      3、把目标文件封装成库
      ar -rc lib库名.a 目标文件
      例:
      ar -rc libmath.a sum.o
      说明:
      库的前级建议以 lib开头,静态库以.a结尾
      -rc中r 表示插入目标文件到静态库中去,c表示创建指定的静态库。

    使用静态库:
    用户在编译使用了库的代码时,需要指定头文件和库文件所在路径 及 库的 名字,格式如下:
    gcc 源文件/目标文件 -I 头文件所在路径 -L 库文件所在路径 -l库名
    编译完成后,程序运行不再需要这个静态库。

    1. 共享库(动态库)
      动态库的特点:
      当把目标文件封装成共享库之后,如果有其它程序需要用到库中的功能,编译器不会去拷贝相关的代码,而仅仅是做一个标记
      当程序执行时,根据这个标记去查找相关的代码,也就是说,程序执行时依赖于共享库。
      所谓依赖于某个库,指这个库必须存在,且编译器知道它的路径。
      当共享库更新后,只要接口不变,用户程序一般不需要做任何改变。

    2. 创建共享库:
      1、编写源代码
      vi sum.h
      vi sum.c
      2、把源代码编译成目标文件
      gcc sum.c -c -fPIC
      3、把目标文件封装成库
      gcc -shared -fPIC -o lib共享库名.so 目标文件
      例:
      gcc -shared -fPIC -o libmath.so sum.o sub.o
      注:
      -shared 指要创建一个共享库
      -fPIC 表示要生成与位置无关的代码
      -o 要创建的库的名字,一般约定共享库的名字格式为:
      lib库名.so

    3. 使用共享库:
      用户在编译使用了库的代码时,需要指定头文件和库文件所在路径 及 库的 名字,格式如下:
      gcc 源文件/目标文件 -I 头文件所在路径 -L 库文件所在路径 -l库名
      编译完成后,程序运行还需要这个共享库。
      用以下方式指定运行时库的路径:
      export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:共享库所在路径

    5、make

    1. 为什么需要make
      在我们的实际开发中,如果仅使用gcc来编译程序,效率较低:
      程序往往由多个模块(.h/.c)组成,源文件个数越来越多,那么GCC命令行就会越来越长,而且编译规则 还会增加命令行的复杂度。
      在编码工作中,调试时间往往大于编码时间,在调试的时候,每次可能 只会修改部分源文件,但是使用GCC命令行编译程序时,那些没有修改过的源文件也会被编译,会大大的影响编译效率。
      所以,我们需要一个工具能够自动检查文件的更新情况、自动进行编译。
      这个工具就叫做make
      make是由GNU项目提供的一个命令行的项目管理工具。

      make是一个工具,它能自动检查文件的更新情况,并能自动进行编译,那么它是怎么知道我们的项目中有哪些文件的呢?以及这些文件应该怎么编译的?

    2. Makefile
      make工具有一个专门的配置文件,我们只需要把项目相关的信息写入这个配置文件,make会自动的去读取这个配置文件,并根据配置文件中的规则 进行工作。
      这个配置文件,就叫做makefile

    Makefile怎么写?
    Makefile可理解为一门小型的编程语言,它有变量、流程控制、函数等,可以很复杂。
    但不管怎么复杂,它的核心规则 是一样的:
    需要生成的目标文件(target)
    生成目标文件所需要的依赖文件(dependency)
    生成目标文件的编译规则(command)

    以上三个核心规则以如下形式进行组织:
    target: dependency
    command

    说明:
    编译规则command前必须加一个tab键
    一个Makefile文件中目标可以有多个,可分两类:
    真正的目标:
    指需要生成一个文件的这种目标,如 可执行文件等
    make自动执行第一个目标,所以一般我们把真正的目标写在最前面
    如果需要执行其它目标,那么必须在make时明确说明
    make
    make 目标名
    伪目标:
    指不需要生成某个文件的目标,只是想执行某个操作
    最常用的伪目标: clean 和 install
    伪目标必须在make时明确指出,而且通常出现在真正的目标的后面
    make clean # 一般用于清除中间及结果文件
    make install # 一般用于拷贝/移动结果文件到指定的目录

    1. makefile中的变量
      makefile中的变量可分成多种,如自定义变量、内置变量、自动变量等
      makefile中的变量是没有类型的,或者说只有字符串类型
      定义一个变量,只需要起一个名字,然后给它一个值即可。

    引用变量时,不能直接使用变量名,而需要在变量名前加一个$符号,如果变量名由多个字符组成,还需要用括号把变量名括起来。
    例:

    1. 直接赋值
      变量名 := 值

    2. 递归赋值
      变量名 = 值
      A = $B
      B = hello

    3. 追加赋值
      变量名 += 值
      A = hello
      A += world

    4. 条件赋值
      变量名 ?= 值
      如果变量没有定义过,则定义,否则 什么都不做。
      A = hello
      A ?= world

    内置变量:
    CC 表示C语言编译器,默认值为 cc
    CXX 表示C++编译器,默认为g++

    自动变量:
    @ 在编译规则中表示目标的名字
    < 表示第一个依赖文件的名字
    ^ 表示所有的依赖文件的名字

    1. makefile中的函数
      makefile中有很多内置函数,可供用户直接使用。
      调用规则:
      $(函数名 参数列表)

    函数wildcard:
    调用方式: $(wildcard PATTERN)
    功能: 获取匹配模式为PATTERN的文件名
    返回:匹配模式为PATTERN的文件名
    例:
    SRC := $(wildcard *.c)
    如果当前目录下有a.c, b.c等,那么变量SRC的值就是 a.c b.c

    函数patsubst:
    调用方式: $(patsubst PATTERN, REPLACE, TEXT)
    功能: 按照PATTERN指定的模式从TEXT搜索子字符串,并将它们替换成REPLACE
    返回: 返回替换之后的新字符串
    例:
    DEPENDENCY := $(patsubst %.c, %.o, $(SRC))
    如果SRC的值为a.c b.c 那么,DEPENDENCY的值为a.o b.o

    6、实践

    1. 下载源码
      官网
      云盘
      飞秋

      下载完成后,把源码包拷贝到linux系统

    2. 解压
      进入源码压缩包所在目录(如我的共享目录)
      cd /mnt/hgfs/20197/20200702-0704-交叉开发/
      解压到指定目录(指定目录必须存在)
      tar xvf libjpeg-turbo-1.5.1.tar.gz -C /home/china/opensrclib/
      进入解压后生成的源码目录
      cd /home/china/opensrclib/libjpeg-turbo-1.5.1

    3. 配置(如果一切正常,会生成Makefile)
      ./configure --prefix=/home/china/opensrclib/libjpeg-arm --host=arm-linux

    说明:
    –prefix: 指定安装目录,该目录可以不存在,安装时会自动创建
    –host: 目标平台

    1. 编译
      make

    2. 安装(把生成的结果,分类存放到prefix指定的目录中去,正常情况会生成四个目录:bin/ include/ lib/ share/)
      make install

    3. 打包移植
      我们需要把生成的那个lib目录中所有的文件移植到开发板上去
      进入安装目录:
      cd /home/china/opensrclib/libjpeg-arm
      压缩打包:
      tar Jcvf jpeglib.tar.xz lib/
      把生成的压缩包,传输(如rx/rz/tftp等)到开发板的工作目录下

    4. 配置开发板上库的路径
      进入开发板的工作目录,解压上一步传输过来的压缩包
      cd /home/china
      tar xvf jpeglib.tar.xz
      解压生成一个lib目录,该lib目录的绝对路径为: /home/china/lib/
      把lib的绝对路径添加到环境变量LD_LIBRARY_PATH中去

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/china/lib/

    确保上述指令正确后,可以把该指令写入/etc/profile文件的末尾,以使其永久生效!

    展开全文
  • 测试开发笔记

    万次阅读 多人点赞 2019-11-14 17:11:58
    测试开发笔记 第一章 测试基础 7 什么是软件测试: 7 ★软件测试的目的、意义:(怎么做好软件测试) 7 3.软件生命周期: 7 第二章 测试过程 8 1.测试模型 8 H模型: 8 V模型 9 2.内部测试 10 ...

    测试开发笔记

    第一章 测试基础
    1.什么是软件测试
    2.软件测试的目的、意义(怎么做好软件测试)
    3.软件生命周期
    第二章 测试过程
    1.测试模型
    H模型
    V模型
    2.内部测试
    3外部测试
    验收测试(在系统测试之后)
    回归测试
    4.测试过程(干什么,怎么干)
    5.各阶段输入、输出标准以及入口、出口准则:(测试阶段过程要素)
    第三章 测试方法
    1.测试方法对比
    2.测试方法组合
    第四章 软件质量
    1.什么是软件质量
    2.质量要素
    3. 6大特性27个子特性ISO国际标准组织CMM/CMMI(Capability maturity model)能力程度度模型
    4.CMMI把企业分为5个等级
    5. CMM与CMMI的区别
    第五章 SQL
    约束
    1主键约束
    2 非空约束 not null
    3 外键约束 FOREIGN KEY
    4 默认约束
    5 检查约束 check
    6 唯一约束 unique
    SQL语句
    创建数据库.
    表、字段、类型
    查询
    批量处理
    视图/虚表 view
    索引
    存储过程 procedure
    事务 transaction
    触发器 trigger
    练习
    一、单表查询练习
    二、聚合函数练习
    三、分组查询练习
    四、嵌套查询练习
    五、联接查询练习
    六、外联接查询
    七、补充提高
    第六章 C语言
    C语言中的存储
    数据类型
    常量
    结构体
    条件/分支逻辑
    Switch
    If
    循环
    For
    while
    do…while
    函数
    第七章 Windows环境搭建
    一、名词注解与定义:
    C/S
    B/S
    进销存系统
    OA系统
    第八章 需求管理
    1.什么是需求
    2. 需求工程在做什么
    3. ★需求变更
    4.★需求的跟踪
    需求跟踪矩阵的作用
    需求的特点
    需求工程
    变更控制流程图
    第九章 缺陷管理
    缺陷相关概念
    缺陷管理相关概念
    BUG管理基本流程
    BUG单
    第十章 测试需求分析
    概念
    ★如何做测试需求分析
    ★UML统一建模语言(Unified Modeling Language)
    第十一章 配置管理
    1.什么是配置管理
    2.配置管理流程
    配置管理工具
    SVN操作过程手册
    一、 如何创建“project”项目版本库
    二、 如何查看创建的“project”项目版本库
    三、 在版本浏览器里面,创建文件,并进行检出
    四、 如何对该项目入基线
    五、 分支文件进行合并
    六、 分支冲突的解决
    第十二章 系统测试
    概念:
    分类:
    功能测试(Function testing中国 Feature testing国际)
    性能测试(Sercarity testing)
    安全性测试(Security Testing)
    安装测试
    GUI测试(Graphical user interface)
    可用性测试(Usability testing)
    异常性测试
    文档测试
    备份测试
    配置测试
    网络测试
    第十三章 用例设计
    等价类
    练习
    1.1年龄注册
    1.2.年龄注册
    1.3.扩充
    边界值
    2.1.年龄
    2.2.用户名注册
    2.3.变量命名
    2.4.进销存价格
    2.5.Windows文件命名
    总结
    边界值
    第十四章 系统测试执行
    测试环境搭建文档
    用例执行
    填BUG报告
    第十五章 QC(Quality Center)
    QC后台:
    QC前台:
    Requirements 需求模块
    Test Plan 测试用例模块
    Test Lab 测试执行模块
    第十六章 PYTHON
    Python的安装
    Python的集成环境
    数据类型
    运算符
    缩进
    控制语句
    IF条件
    WHILE循环
    FOR循环
    BREAK \ CONTINUE
    函数
    定义
    调用
    第十七章 单元测试
    单元测试概念
    单元测试静态测试
    单元测试动态测试
    测试评价准则
    逻辑覆盖率
    单元测试策略
    ⑴ 孤立测试
    ⑵自顶向下的单元测试策略
    ⑶自底向上的单元测试方法
    单元测试用例设计(基本路径覆盖法)
    程序控制流图
    单元测试执行
    单元测试框架
    第十八章 集成测试
    第一阶段总结
    Test platform
    Bug的其他说法
    第二阶段项目笔记
    一.建立项目JXC
    二.布置JXC
    三.配置SVN
    四.访问SVN
    进销存项目
    进销存项目总结
    测试需求分析
    1、定义测试范围
    2、建立需求项
    3、细化需求项
    4、需求覆盖率分析
    判定表
    3.1.读书选择
    3.2.Counter
    3.3:word中的判定表举例
    3.4.合并判定表
    3.4.密码修改
    3.5.进销存
    3.6.总结
    因果图
    4.1.字母判定
    4.2.自动售货机
    状态迁移
    5.1.飞机售票系统
    5.2.缺陷跟踪
    流程分析
    6.1.处理流程
    6.2.系统登录
    6.3.字母判断
    6.4.组合查询
    正交试验
    7.1.环境搭建
    7.2.Counter
    7.3.组合
    7.4.环境搭建
    其他
    输入域
    输出域
    异常分析
    错误猜测

    第一阶段
    第一章 测试基础
    1.什么是软件测试:
    两个依据(需求、测试用例),两个方法(手工、自动),一个对比(预期结果和实际结果的对比)
    2.软件测试的目的、意义:(怎么做好软件测试)
    初期: 尽量多的发现缺陷生成相关规范
    中期: 尽量早的发现缺陷
    后期: 尽量预防问题:通过以往的经验积累
    控制成本(贯穿始终)尽量少的时间和人力发现更多的缺陷
    3.软件生命周期:软件的产生直到报废或停止使用的生命周期。软件生命周期内有问题定义、可行性分析、总体描述、系统设计、编码、调试和测试、验收与运行、维护升级到废弃等阶段,也有将以上阶段的活动组合在内的迭代阶段,即迭代作为生命周期的阶段。

    如何尽量多的发现缺陷?
    沟通
    在测试前期与开发沟通 确认测试重点 确认测试的优先级
    了解开发人员技术和业务背景 业务水平 技术水平 代码质量 人员流动性
    在测试结束后
    对已发现的bug进行统计 知道高发概率bug 在新项目中要进行重点测试
    针对代码 代码复杂度
    版本管理
    针对基础测试基础版本要进行充分的测试
    验收前的最后一个版本一定要进行完全重复测试
    测试方法
    黑盒方法 功能问题 无法保证所有的代码逻辑都被执行到 用白盒测试思想补充黑盒测试
    静态测试方法 文档评审 代码走查
    测试过程
    上一阶段为下个阶段提供重点指导
    用户参与的测试或用户反映回来的错误和问题为下次测试的或测试补充的必备内容

    第二章 测试过程
    1.测试模型
    H模型:

    H模型图
    优点:
    1 介入早 与开发并行 更早的发现问题
    2 测试过程独立于开发过程 更客观 更主动
    V模型

    双V模型图
    ㈠需求阶段
    产品经理,项目经理,产品工程师写《需求规格说明书》Software Reqwirment Specaficalion(SRS)
    内容:需求项(业务,主要功能)需求子项,对子项的详细描述
    测试的工作:对需求进行测试和评审A系统测试计划《系统测试计划书》B系统测试计划《系统测试方案书》C系统测试实现《系统测试用例》
    ㈡设计阶段
    开发经理,架构师,开发工程师写出《概要设计说明书》High-level design(HLD)
    内容:系统程序中的模块,子模块和他们之间的关系和接口
    测试的工作:对HLD进行测试和评审A集成测试计划《集成测试计划书》B集成测试设计《集成测试方案书》C集成测试实现《集成测试用例》
    ㈢详细设计阶段
    开发工程师,架构师,写出《详细设计说明书》Low-level desragn(LLD)
    内容:函数 代码 逻辑
    测试工作:对LLD进行测试和评审A单元测试计划《单元测试计划书》B单元测试设计《单元测试方案书》C《单元测试用例》
    ㈣编码阶段
    开发工程师写代码
    优点:介入早,提高测试质量; 分成三个阶段,发现问题更有针对性;测试与开发并行,更好的利用项目资源。
    缺点:项目成本高;技术要求高,对人员要求高;并行工作中,一方未完成就会对整个造成延误。
    适用范围:规模大、软件成熟度高的项目。
    2.内部测试
    测试阶段 测试对象 测试方法 测试目的 经济价值 优点 缺点 必要性 资源
    系统测试
    system testing(ST) 整个系统
    (整个产品) 黑盒测试 验证产品是否符合需求规格说明书 能够保证产品以较高的的质量尽早的上市销售,从而使公司获取利润 1简单
    2技术要求低 1测试介入时间晚,修改成本高
    2有一些问题可能被遗留不会被修改 必须保证 1对被测产品
    2需求规格说明书
    3系统测试工程师
    4需求开发人员
    集成测试
    integration testing(IT) 模块
    子模块
    接口 灰盒测试 验证模块、子模块、接口是否符合
    概要设计说明书 能够帮助更准确的 定位缺陷的所在,从而降低了定位缺陷的成本 定位准确快速 1接口测试有技术要求,技术实现难度大
    2接口太多,数量庞大,做所有接口的集成测试成本高 不是必须做的,
    必须做测试的
    1公共的主要模块
    2核心模块
    3和外界软件接口模块 1被测的产品
    2概要设计说明书
    3集成测试工程师
    4概要设计人员
    单元测试
    unit testing(UT) 函数
    代码
    逻辑 白盒测试 验证函数代码逻辑是否符合详细设计说明书 能够最早的开展测试工作,降低修复成本,防止缺钱被扩大化(注意:加以重视:1公共的模块2全局性的数据结构3重要的使用频率较高的功能4以往项目经常出错的严重问题5复杂度较高的模块6当开发人员业务不熟悉编码不熟练的模块要进行单元测试) 介入时间早,发现问题早,修改成本低。 1技术难度高
    2工作量太大 不是必须的 1开发环境
    2LLD
    3单元测试工程师
    4架构师(详细设计人员)
    3外部测试:
    使用验收测试的原因
    1内部测试只能模拟用户使用却不能代替用户使用
    2由于专业不同业务背景不同无法模拟用户使用的习惯
    3测试人员和用户对产品的理解可能不同
    验收测试:(在系统测试之后)
    α测试:由用户组织一部分人在开发环境下来对产品进行测试 如网游的内侧
    β测试:所有系统使用者都可以参加的测试(在实际使用环境下) 如网游的公测
    分类 测试过程 参与人员 目的 过程主要内容
    针对项目类软件 验收测试 开发人员:提供满足验收要求的软件或系统,或用户需要的相关开发文档
    测试人员:
    1、搭建验收测试环境
    2、准备验收测试用例
    3、准备用户需要的相关测试文档
    4、组织人员进行验收演示
    用户代表:对系统进行一定的试用
    客户代表:签字确认验收是否通过
    行业:负责在验收过程中提出问题并协助用户和客户检查系统是否满足需求 1、检查软件的功能是否与用户最初需求相一致
    2、是客户回款的标志 1、进行验收前准备
    A、准备相关的资料
    B、搭建验收测试环境
    C、指定相关的验收参与人
    2、进行验收演示
    A 、对产品使用进行演示
    B、回答专家、用户的提问
    3、签署验收报告
    针对产品类软件 α测试 开发人员:
    1、提供可以进行α测试的软件
    2、负责修改用户代表发现的问题
    测试人员:
    1、检查或协助用户填写缺陷报告
    2、向用户学习相关的使用关注点
    邀请的用户或客户代表(付费)
    1、按照自己的操作习惯使用软件,提出易用性等方面的问题和改进建议 明确用户的使用体验,提高产品的适用范围和使用质量标准 1、明确进行α测试的版本
    2、邀请潜在用户进行使用体验
    3、针对用户提出的问题进行修复或改进
    β测试 潜在用户:
    1、安装软件并使用
    客服人员:
    记录并反馈用户的问题 提前占领市场 1、发布一个下载地址
    2、用户进行软件下载并使用
    回归测试:
    回归测试可以发生在任何一个阶段
    分为完全回归和选择回归
    回归范围 回归分类 特点 优点 缺点 适用范围
    完全回归 完全重复法 每次回归测试都要执行全部测试用例 回归测试充分,覆盖面广,不容遗漏 工作量大,时间长,成本高 时间充裕且测试资源较充分时,第一次和最后一次做回归测试的时候用这种方法
    选择性回归 覆盖修改法 每次回归测试时只执行发现错误的用例 时间最短,成本最低,简单效率高 回归测试不充分,漏洞较多 时间较紧且人力资源不足时,中间版本的测试轮次可以使用,关联度比较小的模块和功能
    周边影响法 每次回归除了执行发现bug的用例外,还要执行与其相关的用例 在考虑了测试成本的基础上有效提高了回归测试的质量 效率 很难确定影响的周边范围,相关用例定位较困难 适合于全局数据结构被修改或公共模块被修改,或核心算法业务被修改时,公用的模块,关系、关联复杂的模块
    指标达成法 每次回归测试达到规定的语气指标
    就可以停止测试了 所有的测试都可度量 1指标生成需要很长的周期,
    很多的项目区累计经验
    2要有比较稳定的团队这个指标才有意义 成熟度较高的测试团队应用于指标达成法
    (适用度很低,很少有公司使用)

    分类 步骤 优点
    确定周边
    范围的方法 界面检查法 1明确被修改的功能 简单
    2修改功能的上下游功能
    3调用修改功能的功能和
    修改功能调用了的功能
    4和修改功能游相同输入输出的功能
    5在测试中执行上诉关联的用例
    代码检查法 1明确被修改的函数和代码 准确,全面
    2在整个系统中检查所有
    调用了修改函数的函数
    3明确上诉所有函数对应的界面
    4测试上诉界面测试用例
    4.测试过程(干什么,怎么干)
    整个系统的内容 需求项(业务、主要功能) 需求项 测试计划 测试需求项 系统测试阶段
    需求子项 测试方案 测试需求子项
    详细内容 测试用例 具体如何进行测试
    整个系统的集成 概要设计 概要设计项 测试计划 集成测试阶段
    概要设计子项 测试方案
    具体内容 测试用例
    整个系统最小单元 详细设计 函数 测试计划 单元测试
    逻辑 测试方案
    代码 测试用例

    5.各阶段输入、输出标准以及入口、出口准则:(测试阶段过程要素)
    系统测试 入口准则 输入文档 输出文档 出口准则
    系统测试计划 开发计划通过评审并入基线
    需求规格说明书通过评审并入基线 开发计划书
    需求规格说明书 系统测试计划书 系统测试计划书通过评审并入基线
    系统测试设计 系统测试计划书通过评审并入基线 需求规格说明书
    开发计划书
    系统测试计划书 系统测试方案书 系统测试方案书通过评审并入基线
    系统测试实现 系统测试方案书通过评审并入基线 需求规格说明书
    系统测试计划书
    系统测试方案书 系统测试用例
    预测试项 系统测试用例、预测试项通过评审并入基线
    系统测试执行 系统测试用例、预测试项通过评审并入基线
    集成测试报告通过评审并入基线 需求规格说明书
    系统测试计划书
    系统测试方案书
    系统测试用例
    预测试项 缺陷报告
    预测试项报告
    系统测试报告 系统测试报告、预测试项报告、缺陷报告通过评审并入基线
    集成测试 入口准则 输入文档 输出文档 出口准则
    集成测试计划 概要设计说明书通过评审并入基线 概要设计说明书 集成测试计划书 集成测试计划书通过评审并入基线
    集成测试设计 集成测试计划书通过评审并入基线 集成测试计划书
    概要设计说明书 集成测试方案书 集成测试方案书通过评审并入基线
    集成测试实现 集成测试方案书通过评审并入基线 集成测试计划书
    集成测试方案书
    概要设计说明书 集成测试用例 集成测试用例通过评审并入基线
    集成测试执行 集成测试用例通过评审并入基线
    单元测试报告通过评审并入基线 集成测试计划书
    集成测试方案书
    集成测试用例
    概要设计说明书 集成测试报告
    缺陷报告 集成测试报告、缺陷报告通过评审并入基线
    单元测试 入口准则 输入文档 输出文档 出口准则
    单元测试计划 详细设计说明书通过评审并入基线 详细设计说明书 单元测试计划 单元测试计划通过评审并入基线
    单元测试设计 单元测试计划通过评审并入基线 详细设计说明书
    单元测试计划书 单元测试方案书 单元测试方案书通过评审并入基线
    单元测试实现 单元测试方案书通过评审并入基线 详细设计说明书
    单元测试计划书
    单元测试方案书 单元测试用例 单元测试用例通过评审并入基线
    单元测试执行 单元测试用例通过评审并入基线 详细设计说明书
    单元测试计划书
    单元测试方案书
    单元测试用例 单元测试报告
    缺陷报告 单元测试报告、缺陷报告通过评审并入基线

    第三章 测试方法
    测试方法对比
    分类方法 测试方法名称 依据 测试对象 理论上的测试目的 实际工作中的测试目的 测试评估标准 测试环境 测试工作介入点 优点 缺点 适用范围
    按照不同的测试对象划分(黑白灰盒的区别) 黑盒 SRS 整个软件产品 检查软件的功能实现是否与SRS相一致 尽早进行验收,收回开发成本 需求覆盖率 尽量与用户环境相一致 只要功能可以进行操作 简单,测试效率高 1、无法保证所有的代码逻辑都被测试到
    2、后台相关的非界面处理可能会遗漏(文件、数据库)
    3、当前功能与其他功能有联系的部分可能也会被遗漏 适合进行功能、性能等使用和外部特性的测试适用范围广泛,适用所有可见功能
    白盒 LLD 代码逻辑函数 检查代码的逻辑实现是否与LLD相一致 尽早发现问题缺陷,降低缺陷修复成本.便于定位问题 逻辑覆盖率
    语句覆盖
    分支覆盖
    条件覆盖
    分支-条件覆盖
    路径覆盖 开发环境 只要独立的函数或类代码编写完成后 覆盖充分,可以覆盖到每行代码 技术较难
    效率较低
    成本较高 针对核心业务、复杂算法、公共模块、全局数据结构、新增功能
    灰盒 HLD 模块\子模块接口 检查接口实现是否与HLD相一致 逐步集成,降低缺陷定位成本 接口覆盖率 子系统集成尽可能和用户环境一致,模块内部接口以及模块间接口可以在开发环境下进行
    子系统间的接口最后要在与用户环境下测试 进行测试的接口模块已完成 可以提早定位和发现问题 技术最难
    成本最高 公共模块之间的调用,复杂度较高的模块调用、使用频率较高的模块调用

    特点 分类 优点 缺点 适用范围
    按照是否运行程序划分 静态 不执行程序 1、文档评审
    A、正规检视
    B、技术评审
    C、同行评审
    2、静态分析技术
    A、控制流分析
    可以发现以下缺陷
    1、死循环
    2、执行不到的语句
    3、不存在的语句
    B、数据流分析
    可以发现以下缺陷
    1、变量未定义被使用
    2、变量已定义未使用
    C、信息流分析
    可以帮助开发人员定位缺陷
    1、输入变量与语句的关系
    2、输出变量与语句的关系
    3、输入变量与输出变量的关系 较动态测试时间早,不用写代码 工作量大 重要的功能模块、核心的业务、算法
    公共模块
    动态 执行程序 黑和测试
    动态白盒:插装—在代码中加入print打印语句,检查程序的中间运行结果 复杂,效率高 测试较晚,写代码 所有功能

    优点 缺点 适用范围
    按照不同的测试手段划分 手工 能够主动的发现bug 重复工作量大,容易引入疲劳缺陷,只能依靠见到的界面 绝大多数的场合
    自动化 可以无限制不断重复,把人从劳动里解放出来,提高劳动效率,提高了测试质量,能发现人不能发现的错误 无法发现脚本中未写明的缺陷 GUI界面稳定
    回归阶段
    需求稳定且功能已实现时才进行脚本的编写
    性能测试工具:提取相关的系统数据,构造并发用户
    测试方法组合
    测试方法组合 典型案例 使用时机 特点
    黑盒
    黑盒静态手工      
    黑盒静态自动化      
    黑盒动态手工      
    黑盒动态自动化功能测试 Mercury的QTP:用于检测应用程序是否能够达到预期的功能及正常运行
    通过自动录制、检测和回放用户的应用操作 1、能够有效地帮助测试人员对复杂的企业级应用的不同发布版进行测试
    2、提高测试人员的工作效率和质量,确保跨平台的、复杂的企业级应用无故障发布及长期稳定运行
    IBM Rational Robot 是功能测试工具 它集成在测试人员的桌面 IBM Rational TestManager 上,在这里测试人员可以计划、组织、执行、管理和报告所有测试活动,包括手动测试报告。这种测试和管理的双重功能是自动化测试的理想开始。
    Borland SilkTest属于软件功能测试工具 是Borland公司所提出软件质量管理解决方案的套件之一。这个工具采用精灵设定与自动化执行测试,无论是程序设计新手或资深的专家都能快速建立功能测试,并分析功能错误。
    基于Java语言的功能和性能测试工具 JMeter是Apache组织的开放源代码项目 主要针对Java语言 它是功能和性能测试的工具,100%的用java实现
    黑盒动态自动化性能测试 Mercury的LoadRunner:是一种预测系统行为和性能的负载测试工具。 通过以模拟上千万用户实施并发负载及实时性能监测的方式来确认和查找问题 能够对整个企业架构进行测试。通过使用LoadRunner ,企业能最大限度地缩短测试时间,优化性能和加速应用系统的发布周期。
    Microsoft Web Application Stress Tool 是由微软的网站测试人员所开发,专门用来进行实际网站压力测试的一套工具。 功能强大的压力测试工具 您可以使用少量的Client端计算机仿真大量用户上线对网站服务所可能造成的影响
    webload是RadView公司推出的一个性能测试和分析工具 它让web应用程序开发者自动执行压力测试; webload通过模拟真实用户的操作,生成压力负载来测试web的性能。
    白盒
    白盒静态手工      
    白盒静态自动化   检查语法规范、语法逻辑  
    白盒动态手工 目前的最流行的单元测试工具是xUnit系列框架 常用的根据语言不同分为JUnit(java),CppUnit(C++),DUnit(Delphi ),NUnit(.net),PhpUnit(Php )等等。 该测试框架的第一个和最杰出的应用就是由Erich Gamma (《设计模式》的作者)和Kent Beck(XP(Extreme Programming)的创始人 )提供的开放源代码的JUnit。
    白盒动态自动化 Jtest是parasoft公司推出的一款针对java语言的自动化白盒测试工具,它通过自动实现java的单元测试和代码标准校验,来提高代码的可靠性。parasoft同时出品的还有C++ test,是一款C/C++白盒测试工具    
    灰盒
    灰盒静态手工      
    灰盒静态自动化      
    灰盒动态手工      
    灰盒动态自动化 BMC的APPSight 系统会将问题发生的相关信息完整录制下来,包括问题发生的现场场景、信息及分析等,从而快速切入到问题根源  
    测试管理工具 是业界第一个基于Web的测试管理系统,它可以在您公司内部或外部进行全球范围内测试的管理。通过在一个整体的应用系统中集成了测试管理的各个部分,包括需求管理,测试计划,测试执行以及错误跟踪等功能,TestDirector极大地加速了测试过程。

    1自动化测试就是用程序驱动程序的测试
    2黑白灰测试的区别
    测试的对象不一样,对于代码实现逻辑程度不一样(黑盒不需要了解代码实现,白盒需要完全了解代码实现,灰盒需要部分了解代码实现)
    3静态与动态测试的区别
    被测程序执行与否 静态不执行程序包括文档评审静态分析技术代码走读,动态包括黑盒测试和动态分析技术
    4自动化合手工测试的不同
    测试手段不同

    第四章 软件质量
    1.什么是软件质量
    质量:确定一个实体的特性满足需求的程度
    内部质量:软件研发过程中,评价的软件质量
    外部质量:软件上市后,用户评价的质量
    过程质量:评价软件研发中每个过程的质量
    软件质量的三个层次
    ⑴流程质量,领导关注 ⑵产品质量 测试工程师关注 ⑶使用质量 用户关注
    2.质量要素
    质量铁三角 : 技术 过程 组织
    3. 6大特性27个子特性ISO国际标准组织CMM/CMMI(Capability maturity model)能力程度度模型

    质量模型列表
    质量模型特性 子特性 特点 常见测试点 案例说明
    功能性 适合性 合适的功能(用户提出要有哪些功能)功能的必要性 验证功能是否满足需求的要求,检测做没做 打电话、听音乐、发信息
    准确性 正确的功能 需求文档中的预期动作和预期输出,做对没有 信息的发送内容是否正确
    互操作性 和其他软件的互相操作 第三方软件的交互 word文档对打印机驱动程序的操作
    保密安全性 保护信息和数据 保护得到授权的人或者系统能正常访问相关的信息或数据 1、登录的用户名和密码
    2、权限使用
    3、防止DOS攻击(拒绝访问攻击)4、系统数据的保护和加密,如密码的加密
    5、传输加密,如密码的网络传输
    6、防病毒
    7、放溢出,如char与varchar的字符数
    保证未授权的人或系统无法看到相关的信息或数据
    功能性的依从性 遵循功能性相关的标准、约定或法规 是否符合国家法律规定 如色情网站
    可靠性 成熟性 缺陷尽可能的少    
    容错性 提前考察的异常情况出错问题 整个系统的外部接口 如word打印时,打印机死机出现报错,但不影响word的使用
    易恢复性 失效后恢复原有功能、性能 系统的性能测试 如网游延迟卡死现象。系统提示内存不足。银行系统的心跳监听。灾难备份。
    可靠性的依从性 法律法规   灾难备份。
    易用性(CUI测试) 易理解性 (快速理解) 系统交互的信息是否准确、清晰、易懂,指导下一步操作。 系统提示信息是否准确 如网银密码超出位数报错
    易学性 (快速上手) 易用好学 是否有说明书、是否在线帮助、是否有提示信息 msn的帮助手册
    易操作性 (快速做完) 方便快速使用 操作的直观程度,操作步骤、操作动作多少与时间长短 鼠标、gui层数、安装过程
    易测试性 软件可控 提供工具给测试工程师,可以控制系统运行,以达到测试目的 windows的性能工具与服务管理工具
    软件可观察 通过辅助手段可  
    吸引性 外观 外观  
    易用性的依从性 法律法规    
    可移植性 适应性 (跨平台、跨语言) 软件产品无需采用有别于为考虑该软件的目的而准备的活动或手段就可能适应不同的指定环境的能力;是否适应其他系统环境 软件、硬件、外设、数据库 微软与苹果的前期竞争。主板与CPU
    易安装性 在指定环境中是否易于安装 主流平台和系统100%测试用例,非主流10% flash安装
    共存性 不同的其他系统能共同运行 1、功能是否能正常运行满足要求
    2、系统性能能满足要求 是否会抢占资源。迅雷和pplive抢占资源。杀毒软件,瑞星和金山不能共存
    易替换性 替代为其他相同功能的产品的能力 升级过后的系统是否会造成系统崩溃 软件升级补丁升级
    可移植性的依从性 法律法规    
    效率-性能 时间效率 规定条件下,软件产品执行其功能时,提供适当的响应和处理时间以及吞吐率的能力 系统的反应时间 提款机取款时间的快慢
    资源效率 在规定条件下,软件产品执行其功能时,使用合适的资源数量和类别的能力 做一件事所占用的系统资源 电器所消耗的电能多少
    效率依从性 法律法规    
    维护性-维护的难易程度与成本 易分析性 软件产品诊断软件中的缺陷或失效原因或识别待修改部分的能力 辅助工具或者日志文件或者常用问题帮助手册 qq异常退出的帮助文件
    易改变性 代码容易被修复或修改 高内聚,低耦合  
    稳定性 软件产品避免由于软件修改而造成意外结果的能力 长期的监控一个系统的运行情况和系统的资源情况 淘宝的系统监控
    维护性的依从性 法律法规

    配置管理
    配置工具 有的话 用的工具叫什么名字
    安装------B/S(浏览器)(check in /check out:原理) C/S(客户端)

    4.CMMI把企业分为5个等级

    5.CMM与CMMI的区别
    cmmi:是不同cmm的集成,集成并发扬cmm的优点,并借鉴其他模型的优点融入新理论和实际研究成果,不仅能应用于软件领域,而且能应用于系统过程和其他过程领域,Cmmi和cmm最大不同: Cmmi1.1版本包含4个成分:系统工程(SE)、软件工程(SW)、应用集成产品和过程开发(IPPD)、供应商外包管理(SS) Cmmi有2种表示方法: 阶段式 连续式

    第五章 SQL
    数据库的价值目标:
    数据库的技术(不只是界面 还要知道数据库逻辑 1.要对数据库的设计理解 2.还有数据库对象的关系3.数据库的常见命令)
    常见数据库:MySQL Access(单机) MS-SQL(交互好) Oracle Sybase DB2
    MySQL 小巧 效率高 免费
    后三种Oracle Sybase DB2是大型收费,数据安全和备份好
    数据库作用:组织、存储、处理
    关系型数据库
    第一日:
    关系型数据库
    数据库的作用

    索引
    视图
    存储过程
    触发器
    事务 对象 优缺点 使用范围
    SQL Server具体操作
    建库
    建表
    备份 恢复 操作手册: 建库 建表 备份 恢复
    第二日:
    查询命令
    单表查询
    多表查询
    查询 统计功能测试点
    第三日:
    新增功能 新增功能测试点
    更新命令 修改功能测试点
    删除命令 删除功能测试点
    补:
    存储过程 学会构造大量测试数据
    触发器 了解 看懂 如何测试

    RDBMS 关系型数据库
    SQL Structured Query Language 结构化查询语言
    C/S Client/Server 客户 服务器
    B/S Browser/Server 浏览器 服务器
    第一天:
    文件类型:文件存储位置改变 程序代码更新 对大量数据量处理不恰当
    数据库的意义”
    1数据的重用(硬盘)
    2检索速度要提高(分类存储)
    3把数据与代码的耦合度降低(数据存放位置与代码无关)
    数据库管理系统 SQLServer
    Oracle
    MySQL
    DB2
    数据库的表结构
    1.数据分类
    2.数据关联
    数据库设计评审点
    1.数据存储是否有重复现象 不同表中是否存在相同字段(该字段既不是主键也不是外键)
    2.是否符合范式要求 同一个表中存在数据重复字段不要超过两个以上 可以保证冗余数据很少
    可以考虑有适当冗余
    3.对于业务有频繁查询要求的数据表
    4.表间关系是否正确 是否按照业务要求进行了数据关联
    5.数据库字段以及表的设计是否充分 数据字段内容是否涵盖需求要求的所有数据
    数据字段类型 及长度是否符合需求

    表 基本组成单元 有记录和 字段组成
    表中每一条数据
    存储数据
    数据分类
    字段位置变化 不影响程序
    索引 建立在字段上 可以对字段进行排序 同一张表索引
    更新索引字段值的时候 新增会打乱索引的顺序时
    视图 建立在数据库上 封装查询命令 存储数据 方便查询调用 提示安全性 显示结果固定
    如果在执行事务时没有执行完就实行事务回滚
    事务:是有两条以上的数据库命令组成的原子集合.该事务中的那条命令要么一次性执行成功,要么都不执行,如果在执行过程中执行失败那么该事务就进行回滚,将数据恢复到执行之前的状态
    是否存在某些业务要封装成事务?
    优点:可以保证有关联的数据库操作所对应的关联所需要的完整性和统一性
    缺点:不要将不相关的操作放在同一个事务中,否则会降低执行成功率和效率

    存储过程 存储过程封装了多条SQL命令,必须存放在数据库服务端
    优点: 减少了网络传输SQL命令的压力
    提高了访问的安全性
    SQL 命令存放在服务器端执行效率高
    缺点:需要编写和设计调试 它是一段程序 对于大批量的数据较弱 避免分支和循环
    触发器 自动执行 并且只能对一张表中进行触发 当某一张中发生操作时需要同时对其让表的数据进行操作可以考虑创建触发器

    过程:
    检查SQL服务是否启动
    图形界面建库 建表
    企业管理器
    命令行方式
    查询分析
    主键 用一标记该表中的记录 不能重复 不能为空
    外键 通过外键与其他表中的数据进行关联 只能是以存在主键值

    当前表的数据要被其他表使用时 要有主键
    外键 有主键存在时就要设置对应的外键

    搭建测试环境时或给用户安装产品
    海达票务处理
    C/B 建立空库hdpw1
    恢复
    安装服务器端
    安装客户端
    admin admin

    约束:
    1主键约束
    1 主键约束 primary key
    –特点:约束的字段数据,不能为空、不能重复。
    如果插入或者更新的数据为空或者重复将不允许进行操作。

    –语法:
    1)不命名的主键约束
    create table student
    (
    No int primary key,
    Name char(10),
    Sex char(2),
    ruxu datetime
    );
    2)命名的主键约束
    create table student
    (
    No int,
    Name char(10),
    Sex char(2),
    ruxu datetime,
    constraint pk_001 primary key(No)
    );
    3)删除主键约束
    –语法:alter table 表名 drop constraint 约束名;
    alter table student drop constraint pk_001;
    4)改主键约束
    –语法:alter table 表名 alter column 字段名 类型 not null;
    –alter table 表名 add constraint 约束名 primary key (字段名);
    alter table student alter column No int not null;
    alter table student add constraint PK_002 primary key(No);
    2 非空约束 not null
    1)增加非空约束
    create table student1
    (
    No int not null,
    Name char(10),
    Sex char(2),
    ruxu datetime
    );

    2)改非空约束
    alter table student1 alter column Name char(10) not null;
    3 外键约束 FOREIGN KEY
    –新增外键关系
    1)非命名的外键约束
    create table grade
    (
    no int foreign key references student(No),-- 字段名 字段类型 foreign key references 主表(主键字段)
    grade float
    );
    2)命名的外键约束
    create table grade
    (
    No int,
    grade float,
    constraint fk_001 foreign key (no) references student(no)
    );
    3)删除外键约束
    alter table grade drop constraint fk_002;
    4)改外键约束
    alter table grade add constraint FK_002 foreign key(no) references student(no) on delete cascade; --当主表进行数据删除时,从表一起删除
    alter table grade add constraint FK_002 foreign key(no) references student(no) on update cascade; --当主表进行数据更新时,从表一起更新
    alter table grade add constraint FK_002 foreign key(no) references student(no) on delete no action; --当主表进行数据删除时,违反了外键约束,拒绝进行删除操作
    alter table grade add constraint FK_002 foreign key(no) references student(no) on update no action; --当主表进行数据更新时,违反了外键约束,拒绝进行更新操作
    4 默认约束
    –default 当 一个字段不填写内为空时,默认插入一条数据
    1)增加default 约束
    create table sex
    (
    id int,
    sex char(2) default ‘男’
    );
    2)改 default 约束
    5 检查约束 check
    –只有满足检查约束的数据才能添加到表中,不满足的加不进来
    1)不命名的检查约束
    create table balance
    (
    id int,
    money float check (money >= 0)
    );

    2)命名的检查约束
    create table balance
    (
    id int,
    money float,
    constraint CK_001 check (money >= 0)
    );
    3)删除检查约束
    alter table balance drop constraint ck_001;

    4)改检查约束
    alter table balance add constraint CK_002 check (money >= 0);
    6 唯一约束 unique
    –对于字段输入的内容必须是唯一的,不能重复,但可以为空,多个字段都可以输入唯一约束
    1)不命名唯一约束
    create table tiger
    (
    tig_id int,
    tig_name char(10) unique
    );

    2)命名唯一约束
    create table tiger
    (
    tig_id int,
    tig_name char(10),
    constraint UN_001 unique(tig_name)
    );

    3)删除唯一约束
    alter table tiger drop constraint UN_001;
    4)改唯一约束
    alter table tiger add constraint UN_002 unique(tig_name);
    SQL语句
    创建数据库.
    语法:create database 数据库名字;
    数据库名字不能使用数字作为开头。可以使用字母或者_作为开头
    create database _51testing;

    开辟两块空间,一个是保存日志的,一个是保存表的
    删库 DROP DATABASE 库名;
    单行注释 ——
    多行注释 /* */
    切换数据库
    语法:use 数据库名;
    use _51testing;
    转换当前使用数据库
    备份数据库
    BACKUP DATABASE 库名 TO DISK=’文件名’;
    如BACKUP DATABASE xuanke TO DISK=’d:\test.bak’;
    恢复数据库
    RESTORE DATABASE 库名 FROM DISK=’文件名’;
    如RESTORE DATABASE xuanke FROM DISK=’D:\test.bak’;
    表、字段、类型
    建表
    语法:create table 表名字 ( 字段名 字段类型 字段约束 , 字段名 字段类型 字段约束 );
    create table tmp
    (
    NO int primarykey,
    NAME char(10)
    );
    字段约束可以没有
    删除表
    语法:drop table 表名
    注意:外键约束
    drop table grade
    建立外键
    Sid INT FOREIGN KEY (sid) REFERENCES student (sid)
    CREATE DATABASE xuanke1;
    USE xuanke1;
    –DROP database xuanke1;
    CREATE TABLE student1
    (sid INT PRImary KEY,
    sname CHAR(20) NOT NULL,
    sex CHAR(2) NOT NULL CHECK(sex IN (‘男’,‘女’)),
    card_id CHAR(20) NOT NULL unique CHECK(len(card_id) = 18),
    calss ChAR(20) NOT NULL,
    major CHAR(20) NOT NULL,
    birth_year INT CHECK(birth_year BETWEEN 1900 And 3000) NOT NULL,
    enrollment DATETIME NOT NULL,
    tel CHAR(20)
    )
    CREATE TABLE course1
    (
    cid INT PRIMARY KEY,
    cname CHAR NOT NULL,
    tname CHAR(20) NOT NULL,
    ctime DATETIME NOT NULL,
    cadress CHAR(20) NOT NULL,
    pre_course_id INT,
    )
    CREATE TABLE student_course1
    (
    sid INT FOREIGN KEY (sid) REFERENCES student1 (sid),
    cid INT FOREIGN KEY (cid) REFERENCES course1 (cid) PRIMARY KEY(sid,cid),
    grade INT
    )
    插入一条记录
    在表中增加数据(insert into)
    语法:
    1对表中所有的字段添加数据:insert into 表名 values (第一个字段的值,第二个字段的值,第三个字段的值…);
    注意1:values 值得个数一定要和表中字段的个数相等,一一对应。
    注意2:values 值得数据类型,必须要和表中字段的数据类型相匹配。int fload 值是数字,如果char 值得字符要用’值’。
    注意: 英文单引号 逗号 ,日期 要加单引号

    insert into student values (5,‘郑佳祺’,‘男’,‘003’,‘2011-08-23’,‘北京’,‘1979-01-01’);
    insert into student values (6,’’,‘男’,‘003’,‘2011-08-23’,‘北京’,‘1979-01-01’);
    insert into student values (7,‘庞鹏珏’,‘男’,3,‘2011-08-23’,‘北京’,‘1979-01-01’);

    2对表中指定字段添加数据:insert into 表名(字段1,字段2,字段3) values (值1,值2,值3);
    insert into student(stuid,stname,sex,family) values (8,‘齐倩’,‘女’,‘天津’);
    insert into student(stuid,stname,sex,family,birthday) values (9,‘例子1’,‘女’,‘天津’,’’);
    insert into student(stuid,stname,sex,family,class) values (10,‘例子2’,‘女’,‘天津’,’’);
    insert into student(stuid,stname,sex,family,class) values (11,‘例子3’,‘女’,‘天津’,NULL);
    insert into student(stuid,stname,sex,family,class) values (12,‘例子4’,‘女’,‘天津’,‘NULL’);
    删除数据
    语法:1.delete from 表名
    注意: 删除表中数据时要考虑约束。
    同样用法 truncate table 表名
    delete from grade
    truncate table grade;
    2.delete from 表名 [where 条件]
    delete from student where stname = ‘例子1’;
    1)单一条件
    DELETE FROM student WHERE sid=500;
    2)复合条件
    DELETE FROM student WHERE sex=‘男’ AND major=‘计算机’;
    DELETE FROM student WHERE major=‘计算机’ OR major=‘1’;
    DELETE FROM student WHERE sid BETWEEN 1 AND 500;
    DELETE FROM student WHERE sid>=1 AND sid<=500;
    3)模糊条件
    DELETE FROM student WHERE major LIKE ‘计算机%’; ———— % 通配符(计算机后面任意位任意字符)
    DELETE FROM student WHERE major LIKE ‘%务’;
    DELETE FROM student WHERE class LIKE ‘4%期’;
    DELETE FROM student WHERE class LIKE ‘4_期’; ———— _ 通配符(4后面一位的任意字符)
    DELETE FROM student WHERE sname LIKE ‘[xw]%’; ———— [] 从括号中取任意一个值
    Truncate table student 删除student表记录内容 但是后面不能加条件(不记录日志,速度快)
    更新表数据(修改一条记录)
    更新表数据
    –语法:update 表名 set 字段 = 值,字段2=值[where 条件]
    –注意1:字段类型 和 值得类型 要匹配,主键的值可以被修改
    –注意2:为了保证表数据的完整一直,最好在更新是增加WHERE 条件。
    select * from student
    update student set sex = ‘男’ ;
    update student set sex = ‘女’ where family = ‘天津’
    update student set family = ‘广州’ where family = ‘北京’
    将学号小于50的记录的入学时间更改为2011-5-18
    UPDATE student SET enrollment=‘2011-5-18’ WHERE sid<50;
    将‘计算机’专业的学生转成“计算机科学与技术”
    UPDATE student SET major=‘计算机科学与技术’ WHERE major LIKE ‘计算机’;
    将专业为“信管”开头和“汽车”开头的专业转成“自动化控制”
    UPDATE student SET major=‘自动化控制’ WHERE major LIKE ‘信管%’ OR major LIKE ‘汽车%’;
    将所有省为“北京”和“北京市”的记录统一成“北京”,并将这些记录的班级改成49期
    UPDATE student SET province=‘北京’,class=‘49期’ WHERE province LIKE ‘北京%’;
    将入学时间大于1985-1-1记录的出生时间改为比入学年月早18年
    UPDATE student SET borth_year=year(enrollment)-18 WHERE enrollment > ‘1985-1-1’;
    year() 是求DATE类型的年份
    查询
    简单的查询记录基础语法
    基础语法 select 查询的内容(也就是字段名1,字段名2) from 表名 where 条件
    (用*号可以显示所有字段)
    查询李进峰的所有基本信息
    SELECT * FROM student WHERE sname=‘李进峰’;
    查询李进峰和菲菲的所有基本信息
    SELECT * FROM student WHERE sname=‘李进峰’ OR sname=‘菲菲’;
    SELECT * FROM student WHERE sname IN (‘李进峰’, ‘菲菲’);
    查询所有姓张的同学的所有基本信息
    SELECT * FROM student WHERE sname LIKE ‘张%’;
    查询姓名中有“宇”的同学的所有信息
    SELECT * FROM student WHERE sname LIKE ‘%宇%’;
    查询姓名长度为3,第一个字为“李”最后一个字是“照”的记录
    SELECT * FROM student WHERE sname LIKE ‘李_照’;
    查询所有姓张和姓李的同学的学号和姓名以及出生年月
    SELECT sid,sname,borth_year FROM student WHERE sname LIKE ‘张%’ OR sname LIKE ‘李%’
    SELECT sid,sname,borth_year FROM student WHERE sname LIKE [张李]%’;
    查询姓“杨”并且所在省份为“河北省”的同学的学号
    SELECT sid FROM student WHERE sname LIKE ‘杨%’ AND province=‘河北省’;
    查询”北京”、”湖南”和”河南省”同学的所有信息
    SELECT * FROM student WHERE province=’北京’ OR province=‘湖南’ OR province=‘河南省’
    SELECT sid,sname,borth_year FROM student WHERE province IN (‘北京’, ‘湖南’, ‘河南省’);
    查询姓“”李但是所在省份没有“湖南”字样的同学的省份证号码
    SELECT card_id FROM student WHERE sname LIKE ‘李%’ AND province NOT LIKE ‘%湖南%’
    查询18岁(不含18)以前上学的同学的姓名和电话
    SELECT sname,tel FROM student WHERE year(enrollment)-borth_year<18;
    查询所有大于25岁的人的所有信息
    SELECT * FROM student WHERE year(getdate())-year(enrollment)>25;
    通配符
    使用环境,用于模糊查询,连接符号用Like 而非 =

    • 代表全部,所有,没有规定数量和内容。一般用于select 后面 不作为条件
      _ 代表一个字符,一个数据位。中文要用两个__ 。作为条件使用
      % 代表任意的,没有规定数量和内容。作为条件使用
      [值1,值2,值3] 从括号内的任意值。作为条件使用
      select * from student where stname like ‘张%’
      select * from student where stname like ‘[张李]%四’
      运算符。条件
      – = 两边内容相同。
      – > 左边大于右边。
      – < 右边大于左边。
      – >= 左边大于等于右边。
      – <= 右边大于等于左边。
      – <> 或者 != 不等于
      – between A and B 介于 A 和 B 之间,并且 >=a <=b .前面的数要小于后面的数,包含边界数的。
      select * from grade where coursegrade = 80
      select * from grade where coursegrade between 80 and 100
      条件关联
      – 条件1 and 条件2 :要同时满足条件1 和 条件2 是并且的关系。
      – 条件1 or 条件2 :只要满足一个条件就可以 是或的 关系。
      – () :先去执行括号中得条件
      – 字段 in (值1,值2,值3) :字段的内容要满足 值1 或 值2 或 值3
      select * from student where family = ‘北京’ and stname like ‘张%’
      select * from student where family in (‘上海’,‘天津’)
      排序
      –对查询到的结果按照升序或者降序的方式进行排列。
      –语法 order by 字段 排序方式 (desc,asc) asc 可以省略
      –注意:order by 一定要写在所有查询sql 的最后面
      select * from grade order by coursegrade
      聚合函数
      对查询的结果中某个字段进行函数运算
      sum(字段) :求和函数 字段需为数字类型
      avg(字段) :求平均值 字段需为数字类型.不会计算为空的条目。
      min(字段) :最小的值
      max(字段) :最大的值
      count(字段) :统计字段的个数,这里可以使用 * ,统计所有结果的行数。
      distinct(字段) :去重复
      注:聚合函数,不能放在WHERE中,需要放在HAVING里
      – 显示学生的总成绩
      select sum(coursegrade) from grade
      – 显示最高的成绩是多少
      select min(coursegrade) from grade
      select avg(coursegrade) from grade
      select * from grade
      select count(*) from student
      DISTINCT 去除重复行
      SELECT DISTINCT province FROM student;

    别名AS (Alias)
    as 临时别名
    列别名在WHERE中不能使用 GROUP BY 中不能使用 ORDER BY 中可以
    表别名可以在任何地方使用
    select class, sex, count(sex) as数量 FROM student GROUP BY class,sex ORDER BY class;
    select count(*) as 学生个数 from student
    select stname as 姓名,stuid as 学号from student
    SELECT和ORDER BY 不影响表中数据 所以可以使用别名
    分组里加WHERE和ORDER BY

    对真空的处理
    查询为空的字段 : 字段名 is null
    查询 不为空的字段 : 字段名 is not null
    select * from grade
    select * from grade where coursegrade is not null

    –统计每个课程的选修人数大于2个人的信息
    对课程分组,显示课程和对应的人数
    select couid,count(stuid) from grade group by couid having count(stuid) >2
    –统计<学生选修信息表>,统计每个同学的总成绩
    统计记录条数 count?
    查多少名学生
    SELECT count(*) FROM student
    查有多少种班级
    SELECT count (DISTINCT class) FROM student;
    查入学时间在1990-1-1到2000-12-31的学生个数
    SELECT count(enrollment) FROM student WHERE enrollment BETWEEN ‘1990-1-1’ AND ‘2000-12-31’ ;
    分组查询 GROUP BY
    先对查询内容进行分组、分类,然后在对一个组中的数据进行查询或者运算
    select 查询的内容 from 表名 group by 字段名
    select stuid,sum(coursegrade) from grade group by stuid
    select * from grade
    select stuid,sum(coursegrade) from grade where coursegrade is not null group by stuid
    分组前条件
    在group by 之前使用where 条件去选取数据
    分组后条件
    在 group by 分组后 + having 条件
    select stuid,sum(coursegrade) from grade where coursegrade is not null
    group by stuid having sum(coursegrade) >=200
    –统计<学生信息表>,统计每个班级中每种性别的学生人数
    select * from student
    –统计按照性别分得学生人数
    select sex,count(stuid) from student group by sex
    –统计<学生信息表>,统计每个班级中每种性别的学生人数,两个分组条件
    –统计<grade表>,统计每门课程的平均成绩,并按照成绩降序排序
    select couid,avg(coursegrade) from grade group by couid order by avg(coursegrade) desc

    RIGHT函数
    取身份证最后5位数
    SELECT right(card_id, 5) FROM student;
    将身份证补齐20位,前面用0补
    SELECT right(‘00’+card_id, 20) FROM student;
    SELECT ‘00’+card_id FROM student;
    LEFT函数
    取身份证的前10位
    SELECT left(card_id, 10) FROM student;
    将学号小于50的电话设置成NULL
    UPDATE student SET tel = NULL WHERE sid< 50;
    将电话为NULL的学生信息查询出来
    SELECT * FROM student WHERE tel IS NULL;
    判断条件是NULL的时候不能用= 要用IS IS NOT
    HAVING
    分组查询中,如果条件中有聚合函数,不能放在WHERE中,需要放在HAVING里
    查询平均出生年>1991的班级信息
    SELECT class,avg(borth_year) FROM student GROUP BY class HAVING avg(borth_year) > 1991 ;
    统计哪些班级男生平均年龄大于20
    SELECT calss FROM student WHERE sex=’男’ GROUP BY class HAVING avg(year(getdate())-borth_year)>20;
    优先级WHERE——GROUP BY——HAVING——PRDER BY
    查询学生的姓名和出生年,年龄最大的放前面
    SELECT sname, borth_year FROM student ORDER BY borth_year ;
    TOP 查询结果去前几个结果
    查询年龄最大的学生信息 年龄最大的前10名
    SELECT TOP 1 sname, borth_year FROM student ORDER BY borth_year ;
    SELECT TOP 10 sname, borth_year FROM student ORDER BY borth_year ;
    查询年龄最小的学生信息 年龄最大的前10名
    SELECT TOP 1 sname, borth_year FROM student ORDER BY borth_year DESC;
    SELECT TOP 10 sname, borth_year FROM student ORDER BY borth_year DESC;
    查询按照学号排序,前50个学生的信息
    SELECT TOP 50 * FROM student ORDER BY sid;
    查询最近入学的10名学生信息
    SELECT TOP 10 * FROM student ORDER BY enrollment DESC;
    关联查询(等值联接)
    内连接 等值连接
    外连接 1、左连 2、右连
    多表关联
    1内连接 等值连接 inner join
    语法 select 内容 from 表1 inner join 表2 on 等值条件
    select * from student inner join grade on grade.stuid = student.stuid
    select grade.couid,couname,coursegrade from grade inner join course on grade.couid = course.couid
    2外连接 outer join
    1)左连 select 内容 from 表1 left outer join 表2 on 条件
    2)右连 select 内容 from 表1 right outer join 表2 on 条件
    select * from grade outer join student on student.stuid = grade.stuid
    注:左连接 以 outer join 左边的表为准,要显示全部的左边表的数据,如果右边表没有关联的数据显示Null 与右边表比较 当右边表没有值时 只取左边表的记录
    select * from student right outer join grade on student.stuid = grade.stuid
    注:右连接 以 outer join 右边的表为准,要显示全部的右边表的数据,如果左边没有关联数据,显示Null
    多表关联
    语法:select 内容 from 表1,表2,表3 where 条件
    select stname,couname,coursegrade from student,course,grade
    where student.stuid = grade.stuid and course.couid= grade.couid and coursegrade >80
    select * from grade
    –所有男同学的平均成绩
    select avg(coursegrade) from student,grade where student.stuid = grade.stuid and sex = ‘男’ and coursegrade is not null
    select * from student
    3子查询,嵌套查询
    –当某一个查询的条件,是在另一个查询的结果集里面时,使用嵌套查询
    –查询李四的成绩。
    select * from grade where stuid = (select stuid from student where stname =‘李四’)
    –查询 张三和李四的成绩
    select * from grade where stuid in
    (select stuid from student where stname =‘张三’ or stname = ‘李四’)
    select * from grade where stuid = (select stuid from student where stname =‘张三’)
    or stuid = (select stuid from student where stname =‘李四’)
    –有考试成绩在 70~90的学生的姓名
    select stname from student where stuid in
    (select stuid from grade where coursegrade between 70 and 90)
    批量处理?
    DECLARE @sid INT 申请一个变量
    DECLARE @card_id CHAR(18)
    SET @sid=1 赋初值
    SET @card_id = ‘000000000000’+right(‘00000’+convert(VARCHAR(6),@sid),6) convert 强制转换数据类型
    PRINT @sid
    PRINT @card_id
    INSERT INTO student2 VALUES (@sid,‘蒋艳梅’,‘女’,‘49期’,‘计算机’,@card_id,1999,‘1999-9-9’,‘1111111’,‘1111’)

    CREATE PROCEDURE btInsert AS 或者 CREATE PROC btInsert AS --(保存一个过程)
    DECLARE @sid INT
    DECLARE @card_id CHAR(18)
    SET @sid = 1
    WHILE (@sid <= 100000)
    BEGIN
    SET @card_id=’1111111111111’+right(‘00000’+convert(VARCHAR(6),@sid),6)
    INSERT INTO student2 VALUES (@sid,‘蒋艳梅’,‘女’,‘49期’,‘计算机’,@card_id,1999,‘1999-9-9’,‘1111111’,‘1111’)
    SET @sid = @sid +1
    END
    EXECUTE btInsert 或者 EXEC btInsert (执行已经保存的过程)
    视图/虚表 view
    创建视图 create view 视图名 as (SQL)
    create view tiger as (
    select stname,couname,coursegrade from student,grade,course
    where student.stuid = grade.stuid and grade.couid = course.couid)
    –注意1.视图中不保存数据,不保存表结构,不保存表,没有约束。只保存sql 语句。
    –注意2.视图可以当表来使用,可以用视图去建视图。但是,不建议做 增 删 改的操作。
    –注意3.删除视图时,不会影响到原来的基础表。可以直接在视图中使用SELECT
    create view big_tiger as (select stname,coursegrade from tiger )
    delete from big_tiger where coursegrade is null
    删视图
    –语法:drop view 视图名
    drop view big_tiger
    drop view tiger

    视图的优点
    –1.对于使用sql 不熟练来说。视图是个很简单的查询途径
    –2.对于经常重复的复杂sql,使用视图可以提高查询效率
    –3.可以辅助用于权限管理,提高数据的安全性
    –4.帮助保护表和数据的完整一致性

    视图的缺点
    –1.降低了查询效率
    –2.增加保存空间
    –3.无法对数据和表进行操作。使得操作测试不方便进行。
    create view cll as (
    select class,count(stuid) as 人数 from student group by class
    )
    select * from cll where 人数 = 2

    –视图在企业中如何应用
    1.对于测试而言,降低测试的复杂度。例如:复杂 sql 写一次保存视图,以后都直接调用视图。
    2.对于测试而言,降低工作难度。例如:新来的新人可能对表结构不熟悉,对sql 也不熟悉,使用视图可以尽快上手开始工作。
    3.对于开发而言,降低服务器的工作。提高服务器运行效率。例如:如果不用视图,查询语句要在服务器端生成传给数据库。如果使用视图,服务器直接查询视图就可以满足查询功能。
    4.对产品设计和业务人员而言,降低了工作难度,不用学习和使用复杂sql 语言。例如:如果产品或者业务人员想去查询某些指定的数据时,只要让开发或测试人员建一个视图。直接去查询视图就可以了。
    索引
    –索引就像目录,表中对于一个字段的目录结构。如果想操作表中的数据,先在索引字段中找到那一行,然后再去操作那一条数据。
    –注意1:建议索引设置在主键、外键、唯一约束,效率高
    –注意2:索引是应用于查询条件的。经常使用的查询条件字段,应该被设置为索引字段。
    –注意3:一个表中可以有多个索引,索引之间可以交叉字段,一个索引可以有多个字段。

    索引的优点:
    –1.提高查询效率
    –2.提高了排序效率

    索引的缺点:
    –1.占用数据库资源
    –2.降低了对数据库增、删、改的效率

    索引在企业中如何应用:
    –1.页面上如果有很多的查询条件并且需要排序时,建议一一创建索引。
    –2.检查是否主键和外键、唯一约束建立了索引关系。
    –3.在测试过程中应该检查,运行查询条件时是否使用了索引。
    –4.测试中检查,平凡被更新的表,不要设置太多的索引。

    –建索引
    –语法:create index 索引名 on 表(字段,字段…);
    create index suoyin1 on student(stname,family);

    –删索引
    –语法:drop index 表名.索引名
    drop index student.suoyin
    存储过程 procedure
    –把一些sql 放在一起执行,并且有逻辑的执行。存储过程。
    –语法1:简单的无参数存储过程。
    – create procedure 存储过程名 as sql语句
    create procedure aa as
    update grade set couid = 6 where couid =1;
    update course set couid = 6 ,couname = ‘生物’ where couid =1;

    执行存储过程
    –语法 exec 存储过程名
    exec aa;

    select * from grade;
    select * from course;

    语法2:有参数的存储过程
    – create procedure 存储过程名 (@参数1 参数类型,@参数2 参数类型…) as sql语句
    create procedure BB (@id int,@NewId int,@name char(10))
    as
    update grade set couid = @NewId where couid = @id;
    update course set couid = @NewId ,couname = @name where couid =@id;

    执行存储过程
    –语法 exec 存储过程名(参数1,参数2,参数3)  
    SQL SERVER 参数不加括号
    –注意1.参数的个数和 数据类型必须与定义相一致
    –注意2.存储过程中的sql 是按照顺序执行的
    –注意3.当存储过程中一个sql失败时。不会影响其他sql的执行。
    exec BB 3,13,‘SQL SERVER’
    alter table grade add constraint CH check (couid < 20)
    update grade set couid = 21 where couid = 13;
    exec BB 13,21,‘ORACLE’
    create database bank;
    use bank;
    create table bj_bank
    (
    name char(10),
    money int check(money>=0)
    constraint pk_nanme_bj primary key (name)
    事务 transaction
    把所作的操作放在一组,如果有一个失败就全失败,都成功时候才成功
    事务是存储过程的一个部分,存储过程的一个写法
    – begin transacion 事务名
    – commit transacion 事务名
    – rollback transacion 事务名
    create procedure zz1
    (
    @a_name char(10),
    @b_name char(10),
    @a_money int,
    @b_money int,
    @c_name char(10)
    )
    as
    begin transaction c1 --开始事务c1
    if (select money from bj_bank where name = @a_name) > 0 --判断a账户
    begin
    update bj_bank --从a中减去
    set money=money-@a_money
    where name=@a_name;
    update zs_bank --向c中添加
    set money=money+@a_money
    where name=@c_name;
    commit transaction c1
    end
    else
    rollback transaction c1 --如果判断失败回滚所有操作

    begin transaction c2 --开始事务c2
    if (select money from bj_bank where name = @b_name) > 0 --判断b账户
    begin
    update bj_bank --从b中减去
    set money=money-@b_money
    where name=@b_name
    update zs_bank --向c中添加
    set money=money+@b_money
    where name=@c_name
    commit transaction c2
    end
    else
    rollback transaction c2 --如果判断失败回滚所有操作

    update bj_bank set money = 5000 where name = ‘a’;
    update bj_bank set money = 1000 where name = ‘b’;
    update zs_bank set money = 0 where name = ‘c’;

    exec zz1 a,b,250,600,c
    select * from bj_bank
    union
    select * from zs_bank
    exec zz2 a,b,500,700,c
    exec zz2 a,b,1000,500,c

    存储过程 zz2 开始
    create procedure zz2
    (
    @a_name char(10),
    @b_name char(10),
    @a_money int,
    @b_money int,
    @c_name char(10)
    )
    as
    begin transaction guopeng
    if (select money - @a_money from bj_bank where name = @a_name) >= 0
    begin
    update bj_bank set money = money - @a_money where name = @a_name;
    update zs_bank set money = money + @a_money where name =@c_name;
    commit transaction guopeng;
    end
    else
    begin
    rollback transaction guopeng;
    end
    begin transaction qiqian
    if (select money - @b_money from bj_bank where name = @b_name) < 0
    begin
    rollback transaction qiqian;
    end
    else
    begin
    update bj_bank set money = money - @b_money where name = @b_name;
    update zs_bank set money = money + @b_money where name =@c_name;
    commit transaction qiqian;
    end
    存储过程zz2 结束
    存储过程循环。大批量的制造测试数据。
    create procedure ww
    (
    @name char(10),
    @money int,
    @count int
    )
    as
    declare @num int;
    set @num = 0;
    while (@num < @count)
    begin
    insert into bj_bank values (@name,@money);
    set @num = @num +1;
    end;
    drop procedure ww
    alter table bj_bank drop constraint pk_nanme_bj
    exec ww ‘王沙’,900,1000000;
    select * from bj_bank where money = 30
    truncate table bj_bank

    –存储过程在企业中如何应用:
    –1.对于开发、对于测试而言,存储过程简化了工作难度。
    –2.对于开发、测试而言,存储过是可以实现逻辑的。
    –3.对于测试而言,帮助我们大批量的生成测试数据。
    –4.对于测试而言,帮助我们去检查对数据库的操作数据是否符合预期
    –5.对于开发而言,存储过程支持事务,可以做逻辑编程

    –删除存储过程
    –语法 drop procedure 存储过程名
    drop procedure ww
    触发器 trigger
    当满足触发条件时,执行后面的触发sql,支持事务
    语法: create trigger 触发器名 on 工作表表名 for 触发方式 as sql语句
    触发条件 delete,update 触发条件因数据库而异
    create trigger trigger_student_delete
    on student
    for delete
    as
    delete grade from grade,deleted where grade.stuid = deleted.stuid;
    select * from student
    select * from grade
    delete from student where stuid = 1
    alter table grade drop constraint FK__grade__stuid__7D78A4E7
    练习
    一、单表查询练习
    1、查询<学生信息表>,查询学生"张三"的全部基本信息
    Select * from student where stname=’张三’;
    2、查询<学生信息表>,查询学生"张三"和”李四”的基本信息
    select * from student where stname in (‘张三’,‘李四’)
    3、查询<学生信息表>,查询姓"张"学生的基本信息
    select * from student where stname like ‘张%’;
    4、查询<学生信息表>,查询姓名中含有"四"字的学生的基本信息
    select * from student where stname like ‘%四%’;
    5、查询<学生信息表>,查询姓名长度为三个字,姓“李”,且最后一个字是“强”的全部学生信息。
    select * from student where stname like ‘李_强’;
    6、查询<学生信息表>,查询姓"张"或者姓”李”的学生的基本信息。
    select * from student where stname like ‘张%’ or stname like ‘李%’;
    7、查询<学生信息表>,查询姓"张"并且"所属省份"是"北京"的学生信息
    select * from student where stname like ‘张%’ and family =‘北京’;
    8、查询<学生信息表>,查询"所属省份"是"北京"、”新疆”、”山东”或者"上海"的学生的信息
    select * from student where family in (‘北京’,‘新疆’,‘山东’,‘上海’);
    9、查询<学生信息表>,查询姓"张",但是"所属省份"不是"北京"的学生信息
    select * from student where family!=‘北京’ and stname like ‘张_’;
    10、查询<学生信息表>,查询全部学生信息,并按照“性别”排序,性别相同的情况下按照“所属省份”排序,所属省份相同的情况下再按照“班级”排序
    select * from student order by sex,family,class; (多个排序条件,用逗号以此分开,先排第一个、再排第二个。。。。)
    11、查询<学生信息表>,查询现有学生都来自于哪些不同的省份
    select distinct (family) from student;
    (注意distinct使用方法)
    12、查询<学生选修信息表>,查询没有填写成绩的学生的学号、课程号和成绩
    select couid,couid,coursegrade from grade where coursegrade is null;
    13、查询<学生选修信息表>,查询全部填写了成绩的学生的选修信息,并按照“成绩”从高到低进行排序
    select * from grade where coursegrade is not null order by coursegrade desc;
    二、聚合函数练习
    1、统计<学生信息表>,统计共有多少个学生
    select count(stname) from student;
    2、统计<学生信息表>,统计年龄大于20岁的学生有多少个
    select count(stname) from student where (year(getdate())-year(birthday))>20;
    3、统计<学生信息表>,统计入学时间在1998年至2000年的学生人数
    select count(stuid) from student where year(enrollment) between 1998 and 2000;
    4、统计<学生选修信息表>,统计学号为"S001"的学生的平均成绩
    select avg(coursegrade) from grade where stuid=‘1’;
    5、统计<学生选修信息表>,统计学号为"S001"的学生的总成绩
    select sum(coursegrade) from grade where stuid=‘1’;
    6、统计<学生选修信息表>,查询课程号为”C001”的课程的最高成绩
    select max(coursegrade) from grade where couid=‘1’;
    7、统计<学生信息表>,查询所有学生中的最大年龄是多少
    select max((year(getdate())-year(birthday))) from student;
    三、分组查询练习
    1、统计<学生选修信息表>,统计每个课程的选修人数
    select count(*) from grade group by couid;
    2、统计<学生选修信息表>,统计每个同学的总成绩
    select sum(coursegrade) from grade group by stuid;
    3、统计<学生信息表>,统计每个班级中每种性别的学生人数,并按照班级排序
    select class,sex,count(stuid) from student group by sex,class order by class;
    4、统计<学生选修信息表>,统计每门课程的平均成绩,并按照成绩降序排序
    select avg(coursegrade) from grade group by couid order by avg(coursegrade) desc;
    5、统计<学生选修信息表>,显示有两门以上课程不及格的学生的学号
    select stuid from grade where coursegrade<60 group by stuid having count(stuid)>2;
    6、统计<学生信息表>,统计每个班级中的最大年龄是多少
    select max(year(getdate())-year(birthday)) from student group by class ;
    四、嵌套查询练习
    1、用子查询实现,查询选修“高等数学”课的全部学生的总成绩
    select sum(coursegrade) from grade where couid=(select couid from course where couname=‘高等数学’);
    2、用子查询实现,统计<学生选修信息表>,显示学号为"S001"的学生在其各科成绩中,最高分成绩所对应的课程
    思考:如果该学号学生有两个课程分数都为最高的100分,查询会有什么结果(显示2个结果)
    select couname from course where couid=(select couid from grade where coursegrade in (select max(coursegrade) from grade where stuid=1)
    3、用子查询实现,查询2班选修"数据库技术"课的所有学生的成绩之和
    select sum(coursegrade) from grade where stuid in(select stuid from student where class=‘002’) and couid=(select couid from course where couname=‘数据库技术’);
    4、用子查询实现,查询3班"张三"同学的"测试管理"成绩
    select coursegrade from grade where stuid in (select stuid from student where class='003’and stname=‘张三’) and couid=(select couid from course where couname=‘测试管理’);
    五、联接查询练习
    1、查询"张三"的各科考试成绩,要求显示姓名、课程号和成绩
    select stname,couid,coursegrade from student inner join grade on student.stuid=grade.stuid and stname=‘张三’;

    select stname,couid,coursegrade from student,grade where student.stuid=grade.stuid and stname=‘张三’;
    2、查询"张三"的各科考试成绩中,哪科没有记录考试成绩,要求显示姓名、课程号和成绩
    select stname,couid,coursegrade from student inner join grade on student.stuid=grade.stuid and stname='张三’and coursegrade is null;

    select stname,couid,coursegrade from student,grade where student.stuid=grade.stuid and stname='张三’and coursegrade is null;
    3、查询"张三"的各门课程成绩,要求显示姓名、课程名称和成绩
    select stname,couname,coursegrade from student,course,grade where student.stuid=grade.stuid and course.couid=grade.couid and stname=‘张三’;
    4、查询3班"张三"的"测试管理"成绩,要求显示姓名、成绩
    select stname,coursegrade from student,course,grade where student.stuid=grade.stuid and course.couid=grade.couid and couname=‘测试管理’ and stname='张三’and class=003;
    5、查询所有2000年以前入学的,各班男生的各科考试平均成绩
    select class,avg(coursegrade) from grade,student where grade.stuid=student.stuid and sex='男’and year(enrollment)<2000 group by class ,couid;
    六、外联接查询
    查询”李坚强”所有课程的成绩,并显示学号、姓名、课程号和成绩,没有成绩记录的学号包括:(‘S009’,‘S010’,‘S011’)
    1、使用右联接
    select grade.stuid,stname,couid,coursegrade from grade right outer join student on student.stuid=grade.stuid and stname=‘李坚强’;
    2、使用左联接
    select grade.stuid,stname,couid,coursegrade from student left outer join grade on student.stuid=grade.stuid and stname=‘李坚强’;
    3、对比等值连接
    select grade.stuid,stname,couid,coursegrade from grade inner join student on student.stuid=grade.stuid and stname=‘李坚强’;
    七、补充提高
    1、查询“张三”比“王三”入学早几年
    select year(enrollment)-(select year(enrollment) from student where stname=‘王三’) from student where stname='张三;
    2、查询所在班级和该班内学生的年龄之和,其中每个人的年龄都大于20岁,每个班的年龄之和大于60岁
    select class,sum(year(getdate())-year(birthday)) from student group by class;

    第六章 C语言
    ATM机
    1.取钱 2.存钱 3.查询余额 4.转账

    作业1:存钱、查询、转账的流程图

    软件模块结构图
    需求:十进制一位数加法
    XX.C ——C语言的源文件
    编译 ——转换成二进制的机器语言
    XX.exe ——可执行文件

    不需要编译的脚本语言: PHP ASP JSP PYTHON VBS PEER TCL
    需要编译的高级语言: C VC C# Delphi Java .Net

    注释: // 和/* */

    作业3:绘制流程图中所有界面

    C语言 面向过程的语言 执行过程是自上向下 函数
    F10 单步执行 但不进入函数体
    F11 单步执行 进入函数体
    C语言中的存储
    数据类型
    基本数据类型
    1浮点型
    默认小数位是6位,若输出《6位,完成四舍五入
    若赋予的值小数位《5,后边会随机补数
    vc 对于定义的浮点型变量会默认为double类型,因此会产生警告。想没有警告,强制在赋值语句中的数据后加f. 比如,
    float x;
    x=0.33f;

    数组
    1)一维数据
    定义:数据类型 数组名[长度];
    初始化:1)先定义,后赋值;
    int a[3];
    a[0]=34;
    a[1]=45;
    a[2]=345;
    2) 边定义,边初始化
    float b[2]={4556.234,45.345};
    3) 只给第0个初始化,后边补0
    double c[3]={345.345345};
    访问:下标从0开始遍历数组

    2)二维数组
    定义:数据类型 数组组[行的长度][列的长度];
    初始化: 1)先定义,后赋值

         int a[2][4];
           a[0][0]=3;
           a[0][1]=4;
           a[0][2]=5;
           a[0][3]=6;
           a[1][0]=7;
           a[1][1]=8;
           a[1][2]=9;
           a[1][3]=10;
           2)边定义,变赋值;
             int b[2][4]={{3,4,5,6},{7,8,9,10}};
    

    访问: 行和列的下标从0开始遍历数组

    2字符串
    定义:char 字符串名[长度];
    初始化:先定义,后赋值
    边定义,边赋值
    1)
    char p1[5]=“abcd”; 对 (因为自动补\0占一位)
    char p2[5]=“abcde”; 错
    2)
    char p3[5]={‘a’,‘b’,‘c’,‘d’,’\0’}; 对
    char p4[5]={‘a’,‘b’,‘c’,‘d’,‘0’}; 错
    输出:prinf("%s",p1);
    printf("%c",p1[0]);
    输入:scanf("%s",&p1); /读整个字符串/
    scanf("%c",&p1[2]); /读单个字符/
    注意:赋值的长度小于定义长度时,会逐个补空

    结构体
    边定义,边初始化: struct 结构体名 {
    数据类型 数组名[长度];
    数据类型 变量名;
    …} 结构体变量名={初始化对应值}
    struct student {
    char name[10];
    int age;
    } s1={“zhangsan”,18};
    访问:结构体变量名.结构体内部定义的变量名。
    printf("%s",s1.name);
    printf("%d",s1.age);

    结构体数组
    边定义,变初始化:
    struct 结构体名 {
    数据类型 数组名[长度]; /表示长度/
    数据类型 变量名;
    …} 结构体数组变量名[长度]={{初始化对应值1},{初始化对应值2},} /这里的长度表示多少个,相当于表中的记录数/

      struct student {
                  char name[10]; /*name这个字符串能有效存储字符数9个,还有1位补空*/
              int age;
            } s[2]={{"zhangsan",18},{"lisi",20}};   /*这里的2表示有2条记录*/
    

    3运算符
    算数运算符: + - * /(求商) %(取余)
    关系运算符: > < >= <= ==(等于) != (不等于)
    真(非0) 假0
    逻辑运算符
    && (与) || (或) ! (非)

    常量
    const 数据类型 常量名=值;
    例如,圆周率 const int pi=3.14;

    变量

    1. 变量是什么?

    2. 先定义,后使用
      标准c
      int x;
      x=3;
      int j;
      j=89;

      vc
      int x;
      int j;
      x=3;
      j=89;

    3. 使用赋值语句修改变量值

    4. 变量赋予的值由数据类型决定

    5. 变量包含名字、值和地址

    6. 不同的数据类型在计算机中存储的字节大小不一样
      16位 32位
      int 2个字节 4
      long 4 4
      float 4 4
      double 8 8
      char 1 1

    7. 变量的名字
      首字母:字母,下划线
      包含:字母,下划线,%, 数字
      不能使用c语言的保留字

    8. 全局变量和局部变量
      1)局部变量如何定义:在函数中定义的变量都成为局部变量。离开函数(调用完函数),该变量消失。
      2)全局变量如何定义:在main函数上边定义的变量成为全局变量。对所有的函数都生效。
      3)当局部变量和全局变量同名时,实际上修改的是局部变量。
      常量
      常量的定义

    define 常量名 常量值

    常量名要全用大写字母
    常量没有数据类型
    1.数组
    定义数组
    数据类型 数组名[N] ;
    N 代表数组的个数

    结构体
    定义
    Struct 结构体名
    {
    变量1
    变量2



    }
    例:
    Struct
    {
    Char name[8];
    Char sex[2];
    Int age;
    Int grade;
    } Stu_49[2]={{“张三”,”男”,18,60},{“李四”,”女”,19,100}};
    结构体的显示
    Printf(“ %s”,Stu_49[0].name);
    条件/分支逻辑
    Switch
    switch (表达式)
    {
    case 值1: 处理语句1;
    break;
    case 值2:处理语句2;
    break;
    case 值3:处理语句3;
    break;
    。。。。

    }
    注意1:值的数据类型要和表达式返回值的类型要匹配;
    注意2:不要忘了使用break退出后续执行;
    注意3:表达式要使用括号括起来;
    

    条件 只能输入固定的值
    If
    分支结构
    条件
    情况1: 对应流程图,假分支直接指向后续语句,不含有处理语句
    if (条件)
    处理语句1;
    处理语句2;

    情况2: 对应流程图,处理语句1和处理语句对应真分支,处理3和4对应假分支
    if (条件)
    处理语句1;
    处理语句2;

    else
    处理语句3;
    处理语句4;

    情况3
    If (表达式1)
    if(表达式2)
    语句2;
    Else
    语句3;
    Else
    语句1;
    循环
    For
    循环结构
    定义循环控制变量
    for (控制变量赋初始值;控制变量终止条件;累加(减)器)
    {
    循环体语句;
    }

    while (条件)
    {

    循环体语句;
    }

    do
    {
    循环体语句;
    } while (条件)

    for(表达式1;满足循环条件;表达式2)
    {
    循环体;
    }
    while
    while (表达式)
    {
    循环体
    }
    do…while
    do
    {
    循环体
    }
    While(表达式)
    申请卡号时,多申请一位 并用\0座位数据的结束
    Do while 在条件不满足时,会执行一次do中的循环体
    有参数有返回值的函数
    错误跟踪 写日志
    函数
    函数:

    1. 输出函数
      1.1 printf(控制格式,变量);
      控制格式 %d - 整形
      %c - 字符型
      %ld -长整形
      %f -浮点型 (想控制小数位 %.3f)
      %lf --双精度 (想控制小数位 %.5lf)
      1.2 printf(“你想输出的内容”);
    2. 输入函数
      scanf(“控制格式”,&变量1,&变量2,…);
      %c
      %d
      %ld
      %f
      %lf
      int x,y;
      x=234;
      y=234;
      scanf("%d%d", &x,&y);
    3. 存在的必要性
      1) 职能单一
      2)定位问题
      3)便于使用
      4) 减少代码冗余
    4. 项目中只能有一个main函数。否则移除。
    5. 函数使用
      先定义(在main函数外定义)-》调用-》申明(在main函数外边申明)
      注意1:定义的函数名、调用的函数名、申明的函数名必须同名
      5.无返回且无形参的函数
      定义:
      void 函数名()
      {
      语句1;
      语句2;
      。。。。。
      }
      调用:
      函数名();
      申明:
      void 函数名();
    6. 无返回有形参的函数
      定义:
      void 函数名(形参列表)
      {
      语句1;
      语句2;
      。。。。。
      }
      在这里,形参列表实际上就是变量定义列表,只是因为放在函数定义中就叫叫它形参。
      比如:int x,int y,int z,char m
      调用:
      函数名(实参列表);
      在这里,实参列表的个数和形参列表个数一致;类型一致;实参列表可以相同数据类型的值,也可以是相同数据类型的变量
      申明:
      void 函数名(形参列表);
    7. 有返回有形参的函数
      定义
      数据类型 函数名(形参列表)
      {
      语句1;
      语句2;
      。。。。。
      return 值
      }
      在这里,return的值必须和函数名之前的数据类型匹配。
      调用:
      定义一个和函数返回数据类型相同的变量
      变量=函数名(实参列表);
      申明
      数据类型 函数名(形参列表);
    8. 函数名在一个程序中不能同名
      程序结构
      #include 语句
      #include <stdio.h>
      函数申明
      main函数
      自己定义的函数
      其他
    9. 字节
    10. ascii
      char m;
      m=“k”;
      /* 输出k字符的ascii码*/
      printf(“m=%d\n”,m);
    11. 转义
      \ - 转义符
      \n -控制换行
      \t -控制tab键的距离
      \0 -空
    12. 注释
      单行
      跨行 /* 语句 */
      Void 函数名()
      Void 函数名(参数1,参数2…)
      Int 函数名()
      Int 函数名(参数1,参数2…)
      注:1调用函数时 传入的参数类型 要和函数参数的类型一致,返回值也是一样
      2对有参数没有返回值的函数测试
      3对没有参数 没有返回值的函数测试
      4 测试main()函数 复制了一个定义为test_main()

    补充知识:
    1个字节=8位 编码是ASCII码 又叫ANSI(美国标准码)
    用两个字节表示中文 编码是GB2312
    当16位全部占用时 编码是GB18030
    后来同意标准 全部用16位表示 编码用UTF-8 只翻译16位中的低8位
    注: C语言中main()函数默认是返回int 类型的值

    第七章 Windows环境搭建
    一、名词注解与定义:
    环境:分为{1、生产环境;2、测试环境;3、开发环境。
    生产环境(也称为:上线环境)是运维人员的工作环境,有时候测试人员也会参与运维的部署工作)。
    测试环境:测试人员为了测试软件在生产环境中的功能和性能的表现,而尽量可能的模拟了一个生产环境来进行软件测试。
    开发环境:就是开发人员编写软件代码的工作环境。
    一个软件要从开发环境——>测试环境——>生产环境这个环境流程。
    问:为什么不在开发环境中进行软件测试,要测试环境中进行?
    答:因为开发环境它具有可变性,其影响测试的准确性,所以为了保证数据独立性和其测试的准确性,软件测试最好在测试环境中进行。
    测试环境-分为:1、硬件环境;2、OS(操作系统)环境;3、软件环境。
    其硬件环境和OS(操作系统)环境都是要根据被测软件的需求来搭建;软件环境包括:被测试软件和一些用户常用软件,主要测试被测软件和常用软件之间的兼容性、冲突。
    搭建:先要根据需求架设硬件环境,再根据需求架设OS系统环境,要保证架设的OS系统是无毒的,最后架设软件环境,卸载无用的软件,确认软件的证件号来保证一些不必要的错误和冲突。
    为什么要保证架设的OS操作系统环境是无毒的?因为病毒可能产生一些和被测软件无关的BUG。解决方法:可安装杀毒软件,重装系统来防止和保证。
    被测软件-分为:1、单机版;2、C/S(client/server);3、B/S(browser/server)。三种运行模式。
    C/S(client/server):是分为客户端、服务端和数据库端(如:PPS、QQ需要用户先安装客户端)。其架设的软件会用客户端来分担一部分工作;
    优点:运行速度快、部分数据存放在本地;
    缺点:兼容性差,要根据不同的系统来开发不同的系统版本,成本高和测试成本高。
    B/S(browser/server):是可以用IE浏览器直接访问和运行的一种模式,不用预先安装客户端(如:网页游戏、网上订票系统等)。
    优点:兼容性好,数据保密性好;
    缺点:运行速度较慢。
    软件要根据不同的运行环境、性能的要求来选择使用C/S架设,还是用B/S架设。
    扩展内容:
    app:应用软件,是安装在OS(操作系统)上面的。
    光的三原色:红。绿。蓝。
    服务器(软件):
    1、应用服务器:IIS,Weblogic,JBoss;
    2、Web服务器软件:Apache,Nginx,LightHttpd;
    3、数据库服务器:SQL Server,MySQL(Strucrure Query Language),Oracle;
    4、邮件服务器:QMail,Exchange,Lotus;
    5、FTP服务器

    C/S
    海达票务系统
    1.硬件环境和操作系统(略)
    2.安装SqlServer,安装客户端和服务器端软件
    3.测试数据准备,环境初始化
    DROP DATABASE hdpw1;
    CREATE DATABASE hdpw1;
    RESTORE DATABASE hdpw1 FROM DISK=‘D:\training\doc\win\student\海达票务\hdpw1’;
    4.参数配置
    4.1 Client端配置,和Server端的链接
    4.2 服务器端配置,和数据库的链接
    4.3 数据库端配置(略)
    5.启动整个海达票务系统
    系统更新时,需要更新C和S端,而B/S架构只用更新S端
    B/S
    安装虚拟机:
    1.打开VMWare
    2.新建一个虚拟机
    3.更改光驱加载的ISO
    4.开启电源
    5.将鼠标焦点放到GuestOS里(如何到HostOS?热键)
    6.格式化磁盘
    7.后续安装的步骤
    8.配置网络
    9.安装VMWareTools

    配置共享文件夹:

    进销存系统
    1.安装IIS (通过本机IP访问和netstat查看进程是否成功启动)

    2.把jxc文件夹拷贝到guest
    3.在IIS里新建一个虚拟目录->指向jxc文件夹

    4.设置jxc文件夹的权限

    5.启动相关扩展

    6.启用虚拟目录的父路径

    7.设置默认首页

    OA系统
    1.安装JDK

    2.将Jdk的bin目录追加到环境变量的Path变量里(如:C:\jdk6\bin)
    注:放在path里可以在cmd中输入命令运行,系统将自动定位jdk所在目录

    3.新建一个系统变量 JAVA_HOME,值为jdk的安装目录(如:C:\jdk6)

    4.新建一个系统变量 CLASSPATH,(如:.;C:\jdk6\lib\tools.jar;C:\jdk6\lib\dt.jar) . 指当前目录 注:CLASSPATH (java的类库)

    注: . 表示当前目录 允许jdk查找当前目录
    5.安装Tomcat,解压后运行startup.bat
    通过127.0.0.1:8080 访问,可以看到Tomcat的欢迎页面
    也可以修改conf/server.xml文件,更改Tomcat启动的端口号

    注:在conf下server.xml中查找8080(默认端口)修改端口号 更改配置后要重启服务器
    用startup.bat启动tomcat
    6.安装MySql

    7.部署OA的程序,将程序拷贝到tomcat的webapps目录

    1)先到Mysql里把测试数据导入
    登录mysql mysql -uroot -p
    进入mysql控制命令行,显示如下
    mysql>

    从硬盘上导入一个sql文件

    mysql> source c:~~~~~\oa\setup\redmoon.sql (本质是执行Sql文件里的每一个SQL语句)
    2)修改和数据库的连接、日志和缓存参数
    oa/WEB-INF/proxool.xml 改里面的数据库密码即可

    oa/WEB-INF/log4j.properties 改日志的路径,并创建相应的路径

    oa/WEB-INF/classes/cache.ccf 改缓存的路径

    8.重新启动Tomcat
    访问 127.0.0.1/oa
    admin
    111111
    注:参考 windows环境搭建
    补充知识:
    查看服务:

    MySql相关命令
    show databases 查看有哪些库
    show tables 查看库有哪些表

    desc 表名 查看表结构

    浏览器引擎: 1.渲染页面 2.执行客户端脚本JavaScript 3.执行自由控件
    w3school.com.cn学习前端语言的网站

    Trident IE
    Gecko FireFox
    Presto Opera
    Webkit Safari

    Cookies 保存用户名 密码 根据浏览器、域名保存 一个浏览器、域名一个Cookies 唯一标识一个客户
    Session 和cookies类似 是服务器端保存的
    Session 和cookies是一一对应的
    TCP/IP分四层 OSI七层

    应用层传输协议:http pop3 smtp
    传输层协议:tcp udp
    网络层协议:ip arp
    物理层协议:mac pppo
    三次握手
    目的:建立连接
    1.给服务器发送一个包[SYN] 处于send状态
    2.服务器回复一个包[SYN,ACK] 处于receive状态
    3.给服务器返回一个包[ACK] 两边同步待命 准备发送

    注:参考 网络模型和协议.vsd
    Session/Cookie:Session是存在服务器的,关闭浏览器则删除Cookie存在客户端,可以设置生命周期

    JAVA环境搭建
    1.安装jdk程序
    2.配置环境变量
    1)增加JAVA_HOME,值为jdk的根目录
    2)修改Path,在后面追加 ;%JAVA_HOME%/bin
    3)增加CLASS_PATH,值为 .;%JAVA_HOME%/lib/tools.jar
    3.运行cmd,检查java版本
    java -version
    4.运行一个java程序
    1)编辑文件 HelloWorld.java,内容为
    public class HelloWorld {
    public static void main(String[] args) {
    System.out.println(“Hello, world!”);
    }
    }
    2) 编译java文件,生成字节码文件
    javac HelloWorld.java
    3) 运行字节码文件
    java HelloWorld

    安装Tomcat

    1. 解压至某目录
    2. 运行 bin/startup.bat
    3. 使用浏览器访问
      http://127.0.0.1:8080

    安装MySQL

    1. 运行MySQL安装程序,next
    2. MySQL的配置
      1. 编码
      2. 密码
      3. 服务
    3. mysql -uroot -p

    部署oa

    1. 将程序文件拷贝到tomcat的webapps目录
    2. 初始化测试数据,登录到mysql控制台,运行source命令
      mysql> source c:…\redmoonoa.sql
    3. 程序配置
      1. oa程序和数据库的连接配置
        WEB-INF\proxool.xml
        修改用户名和密码
      2. oa的日志配置文件
        log4j.properties
        log4j.appender.R.File=C:/apache-tomcat-7.0.6/webapps/oa/log/oa.log
      3. oa的缓存配置文件
        WEB-INF\classes\cache.ccf
        jcs.auxiliary.DC.attributes.DiskPath=C:/apache-tomcat-7.0.6/webapps/oa/CacheTemp
    4. 重启一下tomcat
    5. 访问
      http://127.0.0.1:8080/oa
      admin
      11111

    第八章 需求管理
    1.什么是需求
    明确要什么做什么
    2. 需求工程在做什么
    ㈠需求开发:需求获取 需求分析 需求格式化 需求验证
    ㈡需求管理:需求分配 需求评审 需求基线 需求变更 需求跟踪
    3. ★需求变更
    a)为什么要变更:外因:市场,客户。内因:技术不足 缺陷 人员资源
    b)变更影响了什么:SRS HLD LLD SP UI ZI CODE
    c)怎么做变更的控制(需求变更控制目标):控制项目成本,控制项目风险
    d)需求变更的越早,影响范围越小,变更越晚,影响范围越大
        原则 方法
    变更控制的目标 降低变更引起的成本 防止随意的变更 通过评审和会议让用户或者企业负责人在变更上签字来确认变更
    尽量早的发生变更 多设计一些产品原形,由用户确认,
    尽量控制变更影响的范围 尽量不变更,如果变更尽量发生在后续版本
    尽量减少变更所引起的反工 当变更的需求稳定后在介入开发和测试
    降低变更引起的风险 高内聚,低耦合 代码内部干的是一件事,函数与函数之间关联尽量小,尽量使变更只影响到局部,而不影响到整个系统
    4.★需求的跟踪
    a)目的(为什么要需求变更跟踪)将和SRS有关的文档统一管理和关联起来,从而可以从任何一点找到其他文档的相关内容
    b)★★★★★输入、输出(RTM)
    ①开发的需求跟踪:SRS HLD LLD
    ②系统的需求跟踪:SRS ST计划 ST方案 ST用例
    ③集成的需求跟踪:HLD IT计划 ITf方案 IT用例
    ④单元的需求跟踪:LLD UT计划 UT方案 UT用例
    输出(RTM)Requirement Tvace Matrix需求跟踪矩阵
    c)每个阶段,跟踪的内容和变更的跟踪.
    SRS编号 SRS名称 系统测试项ID ST描述 ST子项ID ST子项描述 系统测试用例ID 系统测试用例描述
    HLD编号 HLD名称 集成测试项ID IT描述 IT子项ID IT子项描述 集成测试用例ID 集成测试用例描述
    LLD编号 LLD名称 单元测试项ID UT描述 UT子项ID UT子项描述 单元测试用例代码声明 单元测试用例代码描述
    需求跟踪矩阵的作用:
    开发RTM: 保证所有的需求都被设计实现了
    测试RTM: 保证所有的需求都被测试了
    保证可以通过需求,确定需求变更影响的范围,找到所有的成果物(HLD、LLD、系统测试计划…)
    需求的特点:
    只关心想要什么,不关心怎么去做
    需求工程

    不同阶段的需求变更的影响范围      
           
    需求阶段需求变更影响      
    需求规格说明书 系统测试计划    
    开发RTM 系统测试RTM    
           
    概要设计需求变更影响      
    需求规格说明书 概要设计    
    系统测试计划 系统测试方案 系统测试用例  
    集成测试计划      
    开发RTM 系统测试RTM 集成测试RTM  
           
    详细设计需求变更影响      
    需求规格说明书 概要设计 详细设计  
    系统测试计划 系统测试方案 系统测试用例  
    集成测试计划 集成测试方案 集成测试用例  
    单元测试计划      
    开发RTM 系统测试RTM 集成测试RTM 单元测试RTM
           
    编码以及后期测试阶段需求变更      
    需求规格说明书 概要设计 详细设计 编码
    系统测试计划 系统测试方案 系统测试用例  
    集成测试计划 集成测试方案 集成测试用例  
    单元测试计划 单元测试方案 单元测试用例  
    开发RTM 系统测试RTM 集成测试RTM 单元测试RTM
    补充知识:
    1代码编写原则:
    1).高内聚,低耦合
    2).可续性高
    3).查阅代码编写规范
    2在公司中出现以下问题如何解决
    (1)业务背景不同,导致项目延期
    明确需求文档的格式和标准,尽可能细化需求文档
    (2)需求变化频繁
    建立变更控制
    (3)需求相关的代码,用例找不到,找不全
    建立雪球跟踪

    CR(Changes requirement)需求变更
    CCB(Changes control board)变更控制委员会
    CMO(Configuration management officer)配置管理员
    PM 项目经理
    SWE 软件开发工程师
    STE 软件测试工程师
    QA 质量保证人员
    CI 基线

    —基线变更流程
    1)项目成员提交CR
    2)CMO将CR状态标识为已提交,并将CR提交给CCB进行签发
    3)CCB召开会议对CR进行评估
    4)未通过CMO将CR状态标识为已拒绝并返回提交人
    5)通过,CMO将CR状态标识为已接受,将CR与要修改的配置项发给项目组成员并开放CI的配置库权限
    6)项目组成员执行更改并进行验证
    7)CCB召开会议对修改进行审核,如果通过将CR状态标识为已验证,发给CMO,否则返回修改人
    8)CMO检查验证CR记录,收回配置权限,将CR状态标识为已关闭,返回提交人
    变更控制流程图

    第九章 缺陷管理
    缺陷相关概念
    1什么是缺陷:被测得产品部符合需求和用户使用的实际结果,不符合法律法规
    软件:满足某个功能的逻辑体
    系统:硬件、支撑软件、人员、数据等,综合起来满足某个业务需求的集合体
    2什么可以被定义为缺陷:(缺陷的分类)
    ①缺陷(defect)产品设计与需求设计部符合
    ②错误(error)没有定义的或者未知的错误信息
    ③故障(fault)由于一些原因导致产品失效,重新启动调整后可以恢复用户使用
    ④失效(failure)由于一些原因产品失效,无法自行恢复
    3缺陷提出的目的和意义
    对开发:更好发现缺陷现象,重现和定位缺陷,查找原因,保证所有的缺陷都被修复
    对测试:记录和保证BUG完整一致,回归保证所有的 BUG都验证
    提出问题,把问题交给开发去改
    跟踪缺陷,看是否已经修改
    测试报告,统计数据
    缺陷管理相关概念
    1.BUG管理的目的:
    ①.保证每个缺陷都被修改
    ②.保证每个缺陷都被回归
    ③.缺陷的完整性和一致性
    ④.避免纠纷,降低沟通成本
    2缺陷管理的意义:
    ①提高工作效率(BUG分类,状态负责人)
    ②记录唯一的缺陷信息,保证BUG完整一致(通过设置权限实现)
    ③记录中间环节,是BUG可追溯
    ④统计为测试报告提供数据
    3.参与缺陷管理的角色:
    测试工程师:发现和回归BUG
    测试经理:判断BUG的有效性
    开发经理:分配BUG
    开发工程师:修改BUG
    评审:解决矛盾
    4.缺陷的分类(属性)
    ①按模块分类:例如:登录模块,查询模块
    ②按严重级别分类:blocker阻碍的(不修改该BUG之后的开发测试无法执行)
    Critical崩溃(系统部能用)
    major严重的(严重影响功能使用流程)
    anormal一般的(不会影响主要的功能流程)
    minor轻微的(不会2影响业务流程也不影响使用)
    trvival 界面的
    suggestion建议(可用性,易用性,侧重用户体验)
    ③按优先级别分类:P1----P5(同意 BUG可能会变)
    BUG管理基本流程:

    BUG管理基本流程及相关角色
    1缺陷管理常见流程
    1)BUG回归时没有修改好:测试工程师REOPEN——开发工程师
    2)测试经理认为BUG无效,原因:不是BGU,对需求的理解误差,描述不清楚。BUG不全,重复
    测试工程师NEW----测试经理CAN OPEN-----REJECTED-----测试工程师CLOSED
    3)开发工程师拒绝修改BUG,原因:修复提高项目风险,理解分歧,技术难度大,修复成本高,修改范围广,优先级低
    测试工程师NEW----测试经理OPEN-----开发经理ASSIGNED-----开发工程师CANFIX------开发经理
    4)开发经理拒绝修改或分配BUG,原因:开发与测试已经不同意,偶发,项目风险高,关系进度成败,技术难度大,无法实现,修改成本高,难度大,影响大,影响进度优先级别低
    测试工程师NEW----测试经理OPEN----开发经理ASSIGNED----评审委员会CAN LATER----Y(LATER)-----N开发经理
    5)一般BUG生命周期
    测试工程师NEW----测试经理OPEN—开发经理ASSIGNED----开发工程师fixed----测试工程师CLOSED
    2缺陷状态:
    New新BUG单 Open确认 Reject拒绝 Assigned已分配 Fixed已修复 Reopen回归时未修改正确重新开放 Closed关闭 Later稍后再改 Postpone延迟 Abandon放弃 duplicate重复 verify验证
    测试人员: 无 → New Fixed → Reopen Fixed → Close
    测试组长: New → Open New → Abandon
    开发经理: Open → Reject Open → Postpone Open → Assign
    开发人员: Assign → Fixed
    项目经理: Reject → Passed Reject → Faild Faild → Abandon
    BUG单
    1.BUG单写作准则(5C):
    correct(准确)每个组成部分的描述准确,不会引起误解
    clear(清晰)每个组成部分的描述清晰,易于理解
    concise(简洁)只包含必不可少的信息,不包括任何多余的内容
    complete(完整) 包含复现改缺陷的完整步骤和其他本质信息
    consistent(一致)按照一致的格式书写全部缺陷报告

    2.BUG单模板

    注意:
    1一定可以重现的BUG可以不写“重复几次操作,出现几次,我认为,标题里不能写步骤,不能用主观的话描述,我在 。。。。的,不确定语句:某些好像,禁止使用”之后”,然后之类的语句”之类的话
    2需求规格说明书以外的错误可以当建议报告,不当BUG报告,开发可以改,也可以不改
    3若是随机出现的BUG,要写出操作几次,出现几次
    4若被测软件是跨平台软件,要写上在其他平台下无误
    5禁止写冗余的操作的步骤。常识性的步骤不用写进缺陷操作步骤
    6写明环境数据,如何选择数据,数据如何被破坏
    7一定要交代清楚测试书记,明确处理对那些数据进行操作

    第十章 测试需求分析
    概念:
    1.什么是需求分析:明确做什么,明确测什么,怎么测
    2.需求分析的目的(针对测试而言):
    1)对需求进行细化和分解,从而找到所有的测试点
    2)使从测试覆盖所有的需求(方法:先覆盖业务流,然后模块,关联 非功能)
    3)更细致的需求分析有利于提高测试质量(非软件质量)
    3.测试需求分析的特征
    1)所有的需求项要通过需求分析被核实
    2)测试需求分析应明确指出满足需求的前置条件和不满足需求的前置条件
    3)测试需求分析不涉及具体的测试数据,测试数据是在测试用例中产生
    ★如何做测试需求分析
    1.明确系统框架,有多少个业务流程
    2.明确业务流中有多少个功能测试点,细化分解业务流:
    a)明确每个功能模块的输入、输出、逻辑
    b)满足功能需求的条件和不满足功能需求的条件
    3.明确每个功能的独立处理流程关系
    4.明确功能之间的处理、联系
    5.明确非功能需求和隐性需求 如:安全性、性能、界面美观、易用性等…
    6.系统运行环境包括代码 硬件、软件、外设、数据库、网络
    罗老师的答案
    1考虑非功能性需求
    2挖掘规范需求形成规范需求流程
    3仔细阅读需求规格说明书(找出问题所在)形成问题列表
    4明确该系统的子系统,模块,子模块,功能,子功能(可以借助用例图的方法)
    5明确功能,子功能的流程和逻辑(可以使用活动图,状态图或流程图)
    6挖掘隐性功能,形成隐性功能规范需求
    7找出模块与模块,功能与与功能之间的 关系,确定组合测试需求
    ★UML统一建模语言(Unified Modeling Language)
    1.用例图:被称为参与者的外部用户所能观察到的系统功能模型图
    关系:
    1.关联
    2.泛化 指向父用例 如:
    3.依赖
    a)扩展 指向被扩展者
    b)包含 大的指向小的
    2.活动图:描述了一组顺序的或并发的活动
    状态 活动 开始 结束
    状态转移 循环 集 判断
    泳道
    3包含3个因素:参与者(Actor执行者),系统(Use Case用例),关系(Association关联,Dependency依赖,Generalize继承)

    第十一章 配置管理
    1.什么是配置管理
    a)对所有配置项进行标识,解决了在不同时间周期内,这些文档贯穿整个项目的生命周期并且对配置项进行权限的控制
    b)配置管理的目的(配置管理在解决生命事情,为什么要进行配置管理):解决了保证了软件产品的完整性,一致性,共享性、权限,变更可控、可追溯性
    c)配置管理管理了什么(配置项都包括哪些):配置项 版本 状态
    配置项:项目过程中每个阶段文档产物(SRS,HLD,LLD)代码,开发工具,测试工具,环境(应用服务器,数据库服务器)第三方软件、用户手册,方案、用例等等,
    对象的版本:XX.YY.ZZ.PP
    XX 主版本号——内核程序,核心代号
    YY 子版本号——主要功能、添加功能
    ZZ 维护版本号——增加次要功能,功能改进
    PP 补丁号——SP
    对象的状态状态: 未检查 入基线 冲突 锁
    注:BUG单也算配置项,但是一般单独管理 常用管理工具:QC、Jira、Bugfree、Bugzilla
    2.配置管理流程

    角色:
    项目经理(Project Manger PM)配置管理员(Configuration Mange Officer CMO)开发经理(Development Manger)测试经理 开发工程师 测试工程师
    质量保证人员(Quality Assurance)变更控制委员会(Change Control Board CCB)
    3.SVN实战
    开发可以生成branch 测试经理可以合并branch入trunk 评审可以使trunk入基线并打tag
    启动数据库服务器subversion: 用start svnserve.exe –d –r

    为每个文档建立trunk 然后再为单独的文档建立branch 测试后合并入trunk生成新版本的该文档
    优点:节省空间 缺点:tag版本不配套

    为所有文档建立trunk 每次建立branch都包括所有文档
    优点:所有文档版本相同 缺点:浪费空间
    配置管理工具SVN操作过程手册
    一、如何创建“project”项目版本库
    第一步:在D盘根目录下创建文件夹:“SVNROOT”如图所示:

    第二步:在“SVNROOT”文件夹内创建两个文件夹分别为:“project”,“project1”两个项目。

    第三步:对“project”创建版本库;
    A.选中“project”文件夹,点击右键;

    B.点击“在此创建版本库”。

    C.版本库创建成功后,“project”文件内自动生产以下文件;

    D.打开“conf”文件夹

    备注:对上述三个文件进行解释
    “authz”文件设置“project”操作人员的权限“read、write”;
    “passwd”文件设置操作的用户名和密码;
    “svnserve.conf”文件是“系统配置文件”
    E.对上述3个文件分别进行修改;
    修改“svnserve.conf”

    未修改
    修改处:

    修改方法:将“#”及空格,去掉即可。

    修改后
    修改后对文件另存,存储过程中格式选择“UTF-无BOM”然后点击“保存”。

    点击“保存后”在原文件夹内生产如图文件,这个是ultra edit 的备份文件

    修改完成。
    

    修改“authz”文件

    未修改前
    添加内容:
    p1_group_a=p1_a1
    p1_group_d=p1_d1,p1_d2
    p1_group_t=p1_t1

    [/]
    *=r
    root=rw

    [project:/]
    @p1_group_a=rw
    @p1_group_d=rw
    @p1_group_t=rw

    修改后
    修改后对文件另存,存储过程中格式选择“UTF-无BOM”然后点击“保存”。
    点击“保存后”在原文件夹内生产如图文件

    修改完成。
    修改“passwd”文件

    未修改前
    添加内容为:
    p1_a1=p1_a1
    p1_d1=p1_d1
    p1_d2=p1_d2
    p1_t1=p1_t1

    修改后对文件另存,存储过程中格式选择“UTF-无BOM”然后点击“保存”。
    点击“保存后”在原文件夹内生产如图文件

    修改完成。
    二、如何查看创建的“project”项目版本库
    通过“版本库浏览器”进行查看
    任意空白处点击“鼠标右键”

    点击:“版本库浏览器”

    输入:“svn://localhost/project”

    备注:“localhost”本机的IP地址;
    Project为项目工程名;
    点击“确定”

    问题:为何会出现“无法连接主机“localhost”:由于目前机器积极拒绝,无法连接”
    分析:“Subversion”服务器端“svnserve”服务未启动;

    如何启动“svnserve”服务,操作步骤:
    A.桌面“开始”----“运行”----输入“cmd”;

    B.用“DOS”命令打开此服务
    首先找到该文件:cd c:\Program Files\subversion 进入该目录

    查看该目录里面有哪些文件,用到命令“dir”

    3启动该项服务
    输入:start svnserve.exe –d –r D:/SVNROOT
    备注:D:/SVNROOT为客户端路径。

    运行后弹出一个窗口

    表示此服务已经运行。

    备注:在SVN运行过程中,此窗口 必须一直打开运行。

    服务运行后再次查看创建的版本库

    如图所示,创建版本库成功。
    三、在版本浏览器里面,创建文件,并进行检出
    如何在版本库里面创建文件
    A.在根目录下点击“右键”点击“创建文件夹”

    C.点击“创建文件夹”

    输入文件夹名“trunck”
    D.填写“创建日志”

    E.认证:输入用户名称和密码:
    用户名:p1_a1
    密码:p1_a1

    F.创建成功
    按照此方法在“trunck”根目录下创建“需求分析、RTM文档、测试报告、代码文档、概设文档、详设文档、用例文档”7个文件夹。

    在代码文档里面添加5个代码程序

    A.将5个代码程序 选中后直接拖入“代码文档”中;
    B.点击“复制项到此”

    添加成功。
    C.同样的方法,添加另外4个文件:min.c;mul.c;div.c;main.c;

    添加完成。
    检出添加的文件夹及文件
    A.A.在D盘根目录下建立文件夹“worksp”

    备注:此文件夹为空文件夹
    B.空白处点击“点击右键”

    C.点击“SVN检出(K)….”

    D.检出完成

    备注:检出成功
    E.打开“wroksp”文件夹,出现“trunck”文件夹

    F.打开“trunckt”文件

    G.打开“代码文档”

    备注:版本库浏览器里面的文件全部被检出,检出成功(如图所示)。

    四、如何对该项目入基线
    第一步:打开D盘文件夹“worksp”找到“trunck”文件夹。
    第二步:选中“trunck”文件夹点击“右键”
    选择“分支/标记”

    点击“确定”

    第三步:在D盘根目录中选择“worksp”文件夹,点击“右键”选择“提交更新”

    第四步:查看入基线是否成功,打开文件“worksp”

    第五步:通过“版本浏览器”进行查看;

    入基线成功。

    五、分支文件进行合并
    第一步:在D盘根目录下创建两个文件夹“group1”、“group2”

    第二步:用入基线的操作的方式,创建两个分支“branch1”、“branch2”

    “group1”文件夹

    “group2”文件夹

    第二步:
    “group1”–“branch1”中“代码文档”内添加文件:chengfang.c
    “group2”—“branch2”中“代码文档”内添加文件:kaifang.c
    以添加“chengfang.c”为例:
    A.添加文件“chengfang.c”

    B.选中“chengfang.c”文件点击“增加”

    C.点击“增加”后

    D.选中后“右键”点击“SVN提交”:

    备注:未提交前“代码文档”显示为:

    E.点击确定、添加成功

    添加“kaifang.c”
    同样的方法进行添加
    添加成功后:

    校验是否添加成功
    方法1:点击“worksp”进行更新,检查“branch1”、“branch2”中是否存在添加的两个文件;
    方法2: 版本浏览器查看

    将“chengfang.c”和“kaifang.c”进行合并;
    A.“合并”前“trunck”里面如图

    B.“合并”步骤:
    a.点击 “worksp”中的“trunck”点击“右键”

    将“kaifang.c”合并

    同样的方法对“branch1”中的“changfang.c”进行合并
    C.对“trunck”文件右键进行“提交”

    D.查看合并是否成功
    方法1:“worksp”----“trunck”----“代码文档”查看

    方法二:版本浏览器进行查看

    六、分支冲突的解决
    在D盘根目录下创建2个文件夹分别为“dev1”、“dev2”

    分别点击该文件夹的“右键”—“检出”—“trunck”

    针对“dev1”里面的“代码文档”

    进行修改添加“除数不能为0”;

    修改后“保存”

    “右键”点击“提交”

    针对“dev2”—“代码文档”里面

    进行修改添加“除数不能为0”;

    修改后“保存”

    “右键”进行提交“提交”

    提交失败,起冲突。
    解决冲突
    A.对“dev2”中的“div.c”文件进行更新

    B.更新完成后打开该文件:

    C.对该程序进行修改,完成后对该文件进行“提交”

    D.然后对“代码文档” —“右键”进行“更新”

    E.查看冲突是否解决
    方法1:“worksp”—“trunck”—“代码文档”—“dev.c”
    方法2: 版本浏览器进行查看。

    第十二章 系统测试
    概念:
    1什么事系统测试
    在对软件,硬件,外设,第三方软件,数据,人员,环境,代码,数据库考虑了的情况下,尽可能的模拟用户的使用环境下所做的测试
    另一答案:将已集成的软件系统,作为整个基于计算机系统的一个元素,与计算机硬件、外设、数据、支撑软件、人员等其他元素结合在一起,在实际运行环境下,对计算机系统进行的一系列测试活动
    注:代码称之为数据流,数据称之为信息流
    2系统测试在做什么工作
    验证系统是否满足需求规格说明书SRS
    验证是都满足隐性需求
    验证系统可以支付用户使用
    3系统测试的工作过程
    系统测试个阶段(计划,设计,实现,执行)的输入,输出,入口准则,出口准则
    4系统测试的对象:对整个产品(整个软件系统)
    5系统测试依据什么:SRS
    6系统:整体性、独立性、功能性、环境适应性
    7软件系统:包括支撑软件、数据、硬件、外设、人员及目标软件
    分类:
    功能测试:(Function testing中国 Feature testing国际)
    根据产品的功能是否满足用户需求
    工作内容 1业务,业务流是否正确实现
    2功能点是否正确实现
    3输入是否正确实现
    4输出是否正确实现
    测试工具:QTP(使用 B/S和C/S软件),LR(C/S软件),RIA TEST(针对Flash,Flex软件,用Flash编写),Selenium(firefox的插件), IBM Rational Robot
    工作原理:模拟用户操作
    性能测试:(Sercarity testing)
    定义:验证产品是否满足性能需求
    常用测试点:响应时间和资源性能(CPU,I/O,内存,信道,传输速度)
    例:1.先确认记事本的性能需求(加入50万行内正常)
    2.先输入50万行文本(造场景)
    3.监控所占用的系统资源
    4.报告,提出改进意见
    注:1内存和硬盘的区别
    内存临时存储,电脑关机,信息就消失,内存容量速度快
    硬盘是靠执行存储,断电后也能保存数据,硬盘存储量大,速度慢
    2信道与宽带有关,与访问人数有关
    3吞吐量,每个时间单元的处理数据
    4测试方法:压力测试(stres stesting)短时间
    负载测试(load testing)正常负荷下,长时间运行
    容量测试(volume testing)最大访问量
    5高级录制能找到每个按钮的控件名,低级录制只能找到鼠标移动到的位置
    6没有需求的性能测试无法进行
    测试工具:LR,Webload , Jmeter(开源软件,JAVA编写),Silk Performance
    工作原理:(B或者C端通过传送协议与S进行通信)
    录制协议,模拟多个永和传送协议(可以几句到以点,同时发给S也可以迭代发送给S)通过IP骑在变成不通的IP地址,突显多线程并发操作
    安全性测试:(Security Testing)

    定义:验证产品在系统的内部的安全保护机制和系统外对入侵的防护能力
    考虑内容:1内部包括身份验证,权限,数据的完整一致,数据的保密性(DB中有些数据加密保存)
    2外部,病毒木马,未授权攻击,传输数据安全(传输过程中密码加密,通过HTTP协议传输)
    注:病毒与木马的区别:病毒主要是针对计算机程序的破坏,木马主要用于盗取计算机内的相关机密
    测试工具:MBSA(Microsoft Basehne Sercurity Analyzer),IBM Rational Appscan,X-scan(某黑客组织开发)
    工作原理:监控服务器或客户端那些端口应该被禁止
    安装测试
    定义:产品的安装过程和结果进行测试
    工作内容:根据软件的测试特性列表,软件安装,配置文档,设计安装过程的测试用例
    包括安装前
    安装后
    安装过程中
    安装时异常终止包括:进程终止(操作系统未关闭)断电模式,断网
    测试对象:安装文件、安装系统、安装文档、配置项
    安装后检查:1件是否产生,是否正确
    2否按人工修改的方式安装
    3装日志是否记录正确
    4否有临时目录,垃圾文件,是否清理掉冷补丁(需要关闭系统的补丁) 热补丁(多数网站补丁属于热补丁)
    GUI测试(Graphical user interface)
    又称为用户界面测试,接口测试
    注:GUI测试无法脱离功能测试而独立存在,否则只能测试外观,布局,无法测试行为
    测试内容:对界面元素进行测试,
    验证产品界面是否与SRS设计一致(包括布局,外观,配色,元素行为,元素功能)
    验证界面元素的交互是否正确
    界面元素包括:整体界面,独立元素组合,独立元素
    思路:先找整体界面,再测独立元素组合和独立元素(据对用户的影响严重程度不同)
    测试步骤:对完整的界面进行测试 (包括布局,功能组合,页面展现的外观)
    组合元素(包括拆分,组合行为,独立行为,展现,外观)
    独立元素(包括外观,为)
    工具:所有做功能测试的工具都可以做GUI的测试
    可用性测试(Usability testing)
    又称易用性测试

    定义:验证用户管理和使用软件的容易程度
    工作内容:是否符合用户的实际习惯
    是否符合用户的特殊要求
    操作是否合理,简单,容易理解
    是否有明确的提示可以指导下一步操作
    异常性测试
    系统允许的操作
    健壮性测试,系统不允许的操作
    文档测试
    说明书,与易用性一起做
    备份测试
    主要测试备份策略
    目的:为了解决风险
    备份策略包括:本地备份,异地热备份(实时备份),本地异步备份,异地异步备份
    还原策略:(又称恢复策略)
    配置测试
    又称兼容性测试
    包括软件配置和硬件配置,验证系统都可以使用那些软硬件配置
    网络测试

    主要测试网络中的协议和数据
    工作内容:1网络协议测试(协议是否正确)
    2网络传输是否正确(不同网络是否正常)
    3网络结果测试

    第十三章 用例设计
    等价类
    定义:1、等价:如果多个输入在程序中处理方式(路径)相同,则认为这些输入是等价的,测试一个即可。(前提:测试不能穷举)
    2、输入:分为两类,有效输入(可以保存)、无效输入(不可保存)
    3、结合:有效等价类、无效等价类
    满足规则:只需寻找一个全部满足规则的(有效等价类)
    不满足规则:需分开,每条不满足条件的举出一个,方便定位错误(无效等价类)
    规则的几种情况:
    1 若规则是布尔式的
    有效、无效分别取一个 一个真,一个假
    2. 若规则是区
    有效的取一个 无效的,在小于区间的取一个,大于区间的取一个,空或零取一个
    3. 规则是集合:
    有效取一个 无效的在集合外取一个
    4. 规则是必须满足的一个条件:
    对无效,要细分无效(先试试其他有效等价类,再试试全部等价类全都不满足)
    例:邮箱注册,注册名只能以小写字母开头,设计无效等价类时,先试试其他有效等价类,如大写字母、数字等,再试试其他有效全部都不满足的情况
    有效等价类:程序规格说明有意义,合理的输入数据
    无效等价类:程序规格说明无意义,不合理的输入数据

    ASCII码
    7位 表示27=128个字符 每个字符存储占用1个字节
    分类:不可见字符
    控制字符:LF(换行)、CR(回车)
    通信字符
    NULL(空)
    可见字符
    空格
    数字
    字母(大写、小写)
    符号
    练习
    1.1年龄注册
    注册页面要求输入年龄,限制:1到150期间的正整数
    1、需求分析—找出全部的输入条件
    1)、正整数
    2)、[1,150]
    注意:分解的过程中,条件之间不用组合(完全独立),在设计有效用例输入的时候再考虑组合(一对多)
    2、绘制等价类表格
    条件 有效等价类 有效编号 无效等价类 无效编号
    正整数 >1 A01 数字 小数 B01
    负数 B02
    0 B03
    非数字 空(NULL) B04
    空格 B05
    字母 B06
    符号 B07
    [1,150] [1,150] A02 <1 B08
    >150 B09

    3、设计测试用例输入
    原则:有效输入—尽可能多去覆盖有效等价类 (一对多)
    无效输入—只能覆盖一个无效等价类 (一对一)
    目的:A、出现问题可以更好的去定位
    B、有可能第一个无效处理后,后续无效值被漏测
    输入序号 有效输入值 覆盖有效等价类 输入序号 无效输入值 覆盖无效等价类
    1 100 A01、A02 2 1.8 B01
    3 -9 B02
    4 0 B03、B08
    5 空(NULL) B04
    6 空格 B05
    7 W B06
    8 @ B07
    9 200 B09
    1.2.年龄注册
    某保险公司注册页面要求输入年龄,限制:1到150期间的正整数,其中:
    [1,10] 适用的费率 10%
    [11,50] 适用的费率 30%
    [51,150] 适用的费率 80%

    条件 有效等价类 有效编号 无效等价类 无效编号
    正整数 >1 A01 数字 小数 B01
    负数 B02
    0 B03
    非数字 空(NULL) B04
    空格 B05
    字母 B06
    符号 B07
    [1,150] [1,10] A02 <1 B08
    [11,50] A03 >150
    [51,150] A04

    输入序号 有效输入值 覆盖有效等价类 输入序号 无效输入值 覆盖无效等价类
    1 5 A01、A02 4 1.8 B01
    2 30 A01、A03 5 -9 B02
    3 100 A01、A04 6 0 B03、B08
    7 空(NULL) B04
    8 空格 B05
    9 W B06
    10 @ B07
    11 200 B09
    1.3.扩充
    考虑全角和半角问题(GB231)
    其中,半角占1个字节
    全角占2个字节

    字符集
    1、ASCII
    2、GB2312 -> GB18030 一个汉字占2个字节
    BIG5(繁体)
    3、ISO Unicode (UTF-16) -> UTF-8(变长存储) 一个汉字可能占3个字节
    条件 有效等价类 有效编号 无效等价类 无效编号
    正整数 >1(半角) A01

    			0	B03
    >1(全角)	A02	半角字符	空(NULL)	B04
    			空格	B05
    			字母	B06
    			符号	B07
    		全角字符	空格	B08
    			字母	B09
    			符号	B10
    		汉字
    

    (字符集) GB-2312 B11
    BIG-5 B12
    [1,150] [1,150] A03 <1 B13
    >150 B14

    分解粒度:根据功能的重要性决定(用例图----执行者角色,考虑用户的关注功能)
    根据成本、时间决定
    取消负数、小数的原因:
    1、前提:在编辑框内输入年龄,程序在接收编辑框的内容时,一般以字符(或字符串)的形式接收,再根据需要进行类型转换,如年龄,需要转换为整型
    2、小数中的“小数点”和负数中的“负号”都认为是符号,不允许保存
    边界值
    取值(5个):上点、内点、离点
    1、上点、内点取值与区间的开闭无关
    2、离点和上点互为有效
    作用:(有序、有范围)等价类的补充
    补充:考虑数据类型的边界
    如 int 类型 占4个字节 即 32bit 取值范围[-231, 231-1]
    上点:边界上的点
    内点:区间内的点
    离点:离边界值最近且与上点不属于同一等价类的点(对于小数,没有离点,不用取)
    规则的几种情况:

    1. 规则是区间:
      按上点、内点、离点取
    2. 规则是取值的个数:
      取最小、最大、中间个数
      3.规则是a~z序列:
      取a、z
      4.规则是集合:
      取一个集合内的,取一个集合外的
      (0,20)上点是0,20 离点是1,19 [0,20]上点是0,20 离点是-1,21
      若规则是下拉菜单:建议每个下拉值都选择一个
      2.1.年龄
      条件 有效等价类 有效边界值 有效编号 无效等价类 无效边界值 无效编号
      正整数 >=1 上点:1 A01 数字 小数 B01
      内点:100 A02 负数 B02
      离点:0 0 B03
      非数字 空(NULL) B04
      空格 B05
      大写字母 上点:A B06
      上点:Z
      内点:M
      符号 离点:@ B07
      离点:[
      [1,150] [1,150] 上点:1 A03 离点: 0 B08
      上点:150 A04 离点: 151 B09
      内点:100 A05
      有效用例输入:1 、100、150
      2.2.用户名注册

    1、测试需求分析
    1、内容:字母、数字、
    2、长度:[6,18]
    3、约束:字母开头
    字母或数字结尾
    不允许重名
    不允许使用保留字
    自动去除首尾空格
    2、等价类划分
    条件 有效等价类 有效编号 无效等价类 无效编号
    内容 字母 大写字母 A01 符号(除下划线) B01
    小写字母 A02 NULL(空) B02
    数字 [0,9] A03 空格 B03
    下划线 下划线 A04 GB2312 B04
    BIG5 B05
    长度 [6,18] [6,18] A05 <6 B06
    >18 B07
    约束 字母开头 大写字母开头 A06 数字开头 B08
    小写字母开头 A07 下划线开头 B09
    符号(非下划线)开头 B10
    汉字开头 B11
    字母或数字结尾 大写字母结尾 A08 下划线结尾 B12
    小写字母结尾 A09 符号(非下划线)结尾 B13
    数字结尾 A10 汉字结尾 B13
    不允许重名 不重名 A11 重名 B15
    去除首尾空格 A12
    不允许使用保留字 不使用 A13 使用保留字 B16
    3、用例设计
    序号 有效输入 有效边界值 序号 无效输入 无效边界值
    1 (当前系统无AAb_4)
    AAbb_4 A01、A02、A04、A03
    A05、A06、A10
    A11、A13 5 abc@a B01
    2 (当前系统无AAb_4)
    aAbcvb_A A01、A02、A04、A03
    A05、A07、A08
    A11、A13 …………
    3 (当前系统无AAb_4)
    aA555b_b A01、A02、A04、A03
    A05、A07、A09
    A11、A13 (当前系统存在aaf5bc)
    (空格)aaf5bc(空格) B15
    4 (当前系统无aaf5bc)
    (空格)aaf5bc(空格) A12 Administrator B16
    2.3.变量命名
    在某一版的编程语言中对变量名称规格作如下规定:变量名称是由字母开头的,后跟字母或者数字的任意组合构成,并且区分字母大小写。编译器能够区分的有效字符数为8个,并且变量名称必须先声明,后使用,在同一声明语句中,变量名称至少必须有一个。
    1、测试需求分析
    内容:字母、数字
    长度:[1,8]
    约束:字母开头
    大小写敏感
    先声明后使用
    变量的个数[1,?] (需要和需求人员沟通)
    在同一作用域中不允许重名
    不能使用关键字
    2、等价类划分
    3、确定边界值
    4、设计用例输入
    2.4.进销存价格

    代码实现:
    if (isNumberString(document.form2.tichen.value,“1234567890.”)!=1)
    {
    alert(“价格只能为数字!”);
    return false;
    }

    根据代码的实现,价格编辑框只接受键盘的“数字键”和“小数点”共11个字符

    等价类
    条件 有效等价类 无效等价类
    内容 数字 字母
    字母、符号处理方式(路径)相同,认为都是等价的
    小数点
    约束 小数点最多有1个 >1个小数点

    2.5.Windows文件命名
    目录 目录长度 文件最大长度 目录+文件最大长度
    C:\ 3 255个 = 258
    C:\ABCD 7 251个 =258
    C:\ABCD\AAAA 12 246个 =258

    根目录: 255
    非根目录: 254 (文件夹最小长度为1)

    1、测试需求分析
    内容:非“/😗?"<>|”的字符
    长度: 根目录: 255
    非根目录: 254 (文件夹最小长度为1)
    约束:同目录下不能重名(去除首尾空格)
    不同扩展名使用不同的图标
    不能为空
    总结
    1、适用范围:针对程序的输入
    2、使用步骤
    1)、测试需求分析,找出全部条件(显示、隐士)(条件之间不能交叉或者组合,到设计用例的时候再考虑多条件的组合)
    2)、划分等价类
    划分依据:相同的处理方式(路径)
    分类:有效等价类、无效等价类
    3)、使用边界值补充(有序、有范围的)等价类
    内容:上点、离点、内点
    要求:上点、内点与区间开闭无关,离点和上点互为有效
    分类:将边界值分为有效边界和无效边界,填入等价类表格
    4)、对每个等价类进行唯一的编号
    5)、设计用例的输入
    原则:有效等价类,一对多
    无效等价类,一对一
    3、优点:对输入的考虑充分
    4、缺点:如果不清楚系统的实现方式,造成大量的冗余用例(黑盒方法共有)
    对于多输入的组合不太适宜
    规则的几种情况:
    1 .若规则是布尔式的
    有效、无效分别取一个 一个真,一个假
    2. 若规则是区间
    有效的取一个 无效的,在小于区间的取一个,大于区间的取一个,空或零取一个
    3. 规则是集合:
    有效取一个 无效的在集合外取一个
    4. 规则是必须满足的一个条件:
    对无效,要细分无效(先试试其他有效等价类,再试试全部等价类全都不满足)
    例:邮箱注册,注册名只能以小写字母开头,设计无效等价类时,先试试其他有效等价类,如大写字母、数字等,再试试其他有效全部都不满足的情况
    有效等价类:程序规格说明有意义,合理的输入数据
    无效等价类:程序规格说明无意义,不合理的输入数据
    边界值
    上点:边界上的点
    内点:区间内的点
    离点:离边界值最近且与上点不属于同一等价类的点(对于小数,没有离点,不用取)
    规则的几种情况:

    1. 规则是区间:
      按上点、内点、离点取
    2. 规则是取值的个数:
      取最小、最大、中间个数
      3.规则是a~z序列:
      取a、z
      4.规则是集合:
      取一个集合内的,取一个集合外的
      (0,20)上点是0,20 离点是1,19 [0,20]上点是0,20 离点是-1,21
      若规则是下拉菜单:建议每个下拉值都选择一个

    第十四章 系统测试执行
    测试用例
    编号组成: 项目名—测试阶段—需求—用例
    测试环境搭建文档:
    1.为日后回归测试等搭建环境做指导
    2.刚开始写完后,评审,防止日后因环境搭建而引起测试时的问题
    3.可为日后上线的文档做参考
    4.可以做自动化步骤的参考
    5.项目留存
    用例执行:
    1.严格按照用例步骤,执行用例
    2.发现结果与预期结果不一致:
    a)重复步骤,重现发现的问题
    b)找同类型的数据,重新执行用例
    c)定位发现问题的步骤 (每执行一步都要做记录)
    3.提交BUG (先确认不是重复BUG)
    填BUG报告:
    (一)若开发返回”不可重现的BUG”,可能原因:
    1.开发步骤不对
    2.测试环境和开发环境不同
    3.出现时有概率的,或者其他原因导致,不是每次重现 (环境、概率)
    (二)合并BUG的原则
    1)同样的原因产生的BUG可以合并
    2)与开发沟通后如果修改一处就可以修改一些BUG可以合并
    3)当BUG之间有制约关系,BUG可以合并
    (三)补充 为什么.TXT文件中报春”联通”重新打开后会有乱码
    文件保存格式默认为ASCII码,但恰好”联通”是以EF开头的,保存时误认为UFT-8格式,导致重新打开时歘先乱码
    (四)书写测试用例应该注意一下几点
    1)测试输入数据必须是唯一的,并且明确的
    2)步骤要完整,按照步骤可以测试测试点和预期结果,建议每个步骤后面都有预期结果,步骤要编号
    3)结果要和需求规格说明书完全一致,如果SRS没有明确结果,需要产品人员补充和定义
    4)无效等价类不能合并

    第十五章 QC(Quality Center)
    QC (Quality Control)质量控制
    QC(前身TD Test Director与QTP、LoadRunner同是MI公司开发)
    QC是B/S架构的
    QC 9.0支持JBoss、IIS两款服务器支持SQL Server和Oracle两个数据库
    QC默认端口是8080 数据库连接端口是1433
    Quality Center QC前台
    Site Administration QC后台
    Add-Ins Page QC插件
    Qcsiteadmin_db 是保存后台数据的 而前台中项目的数据,是单独保存在另一个数据库中
    QC预置5个用户组,只能查看,不能修改权限
    Developer Project Manger QATester TDAdmin Viewer
    外部测试人员,只有Defects Module权限,只执行测试,报BUG
    组内测试人员,有QC所有模块权限
    QC后台:
    Site Project 设置项目
    Create Domain 建立区域
    Create Project 建立项目
    Create an empty Project 建立一个空项目
    Create project by copying data from an existing project
    从已有项目拷贝创建一个新项目

    Create a project by importing data from an exported Quality Center project file
    从一个已有项目的导出文件创建一个新项目

    QC前台:
    TOOLS下的Customize…选项
    Customize Project Entities 设置输入项 可添加新选项
    Customize Project Lists 项目列表 可设置下拉列表中的项
    Requirements 需求模块
    菜单栏下Requirements菜单项
    Covert to Tests 将需求转换成测试用例 用于比较系统的测试
    Generate Test…将需求生成测试执行 用于临时的测试
    菜单栏中View菜单项
    Expend 扩展,全部展开
    Collapse 收起
    Numeration 排序
    Full Coverage 完全覆盖(考虑测试覆盖率)
    Requirements Tree 需求树结构 用于项目经理等管理者
    Requirements Grid 需求表结构 用于浏览者(可用Favorites)
    Requirements Coverage 需求覆盖率 用于测试人员
    Coverage Analysis 需求分析视图 用于测试管理者
    菜单栏中Analysis菜单项
    Reports选项下
    Standard Requirements Report 标准需求表 用于评审
    Tabular Requirements 概要表 用于产品经理
    Requirements with Coverage Tests 带覆盖率的表 用于测试经理
    Requirements with Coverage Tests and Steps 带步骤的 用于测试用例评审
    Requirements with Linked Defects 带缺陷的 用于生成测试报告
    Graphs选项下
    Progress 给项目经理
    Requirements Coverage 给测试经理
    Trend 给BOSS
    工具条中Set filter/Sort 过滤器 用*做通配符
    View Order 结果排序 同级才能排序
    双击一条需求 Requirement Details 需求详细信息
    Coverage 覆盖率
    Linked Defects 连接缺陷
    需求的状态:not covered not run not complete passed failed
    Test Plan 测试用例模块
    点击一条测试用例,右侧在Design Steps标签页下
    Call to Test 调用测试用例 只能调用到一个参数 可用于回归测试
    Generate Script 生成脚本
    Insert Parameter 添加参数
    Renumber Steps 重新写序号 (不影响步骤的内容)
    菜单栏中Tests菜单项
    Flag for Follow up 标记一个执行
    Mark as Template Test 标记成为模板用例
    菜单栏下View菜单项
    Trace Changes 变更跟踪警告
    Analysis中所有报表均是测试工程师用
    Test Lab 测试执行模块
    需要添加一个集,用例才能被添加到集
    菜单栏下Test Sets菜单项
    Reset Test Set 重置测试集 用于测试回归,所有状态均为No Run
    Purge Runs 清理执行的状态 清理执行的状态,上个是全部,此为条件式
    状态优先级:
    Failed > Not Complete或N/A或No Run > Passed
    Trace Changes
    在Test Plan中,跟踪的是需求Requirements
    在Test Lab中,跟踪的是缺陷Defects状态时”Fixed”时
    在Defects中,跟踪的是Test Lab成功运行时
    其中红色! 表示未看过 灰色表示已看过
    QC中,Defects只能连接自己,不能连接其他而 Requirements、Test Plan、Test Lab可以连接其他任何一个,不能连接自己,所以,Defects单独划出一个模块
    权限设置:
    需求人员:写需求
    测试人员:用例、BUG、执行用例
    开发人员:改BUG
    项目经理:所有权限
    当产生纠纷时,在设置中增加一个状态,在Defects中的Description选项中的Comments下添加分歧的描述、原因等等,分配给解决纠纷的人,只有被分配的人可以修改状态,其他人不能更改

    变更控制:
    能否变更 用Reviewed(评审)字段,将之设置成必填项,默认值是Not Reviewed
    设置权限中,不给需求人员修改Reviewed的权限

    第十六章 PYTHON
    Python 是面向过程、面向对象,跨平台的高级脚本语言。 是解释性语言,执行源代码,提供丰富的库,支持多线,多进程,网络编程,可以支持C/C++的代码,可以测试C/C++和Python开发的单元产品,Python越来越多的成为开源测试自动化工具的首选语言
    Python的安装
    1.安装之前,先退出杀毒软件
    2.安装 缺省安装
    3.完毕后,配置系统环境变量 path (把解释器pathon.exe所在目录加入path)
    Python的集成环境:
    1.Python文件夹下IDLE
    2.新建文件 New Window
    3.保存(用Save As…后缀.py)
    4.运行方式:
    a)Run Module (若提示”Socket Error”是因为杀毒软件引起的错误)
    b)命令行方式 在DOS下,进入文件目录,输入命令python hello.py
    python可以用#来做注释
    输入中文时在前面加#coding:gbk
    在GUI界面下 若不加保存时会报警告

    补充知识:
    DOS命令:
    切换盘符 盘符名:
    进入文件夹 cd 文件夹名\文件夹名…
    退到根目录 cd
    退出一层目录 cd…
    数据类型:
    Str字符型字符串(可以用单引号、双引号) Int 整形 long长整形 float浮点型 bool(布尔型):True真/False假(首字母大写,不用加引号)
    运算符:
    算术运算符: + — * /
    逻辑运算符: and or not
    比较运算符: 相等 = = 不等于 != < > <= >=
    缩进:
    在行首用空格或者Tab 缩进相当于C语言中的{ } 表示对应一段完整的逻辑
    一般用TAB 因为一段代码中不能同时使用两种缩进方式,默认是TAB
    控制语句:
    IF条件
    1 if (条件1):
    处理语句1
    处理语句2
    处理语句3

    语法解释:满足条件1执行语句1,2,3,不满足条件1执行语句
    2 if (条件1):
    处理语句1
    处理语句2
    elif
    处理语句3

    语法解释:满足条件1执行语句1,2不满足条件1,执行语句3
    3 (1) if (条件1): (2)if (条件1):
    处理语句1 处理语句1
    处理语句2 处理语句2
    elif (条件2): else:
    处理语句3 if(条件2):
    处理语句4 处理语句3
    … 处理语句4
    else: else:
    处理语句5 处理语句5
    处理语句6 处理语句6
    … 。。。。
    处理语句7 处理语句7

    语法解释:满足条件1执行语句1,2,7,不满足条件1,满足条件2,执行语句3,4,7,不满足条件1,2,执行语句5,6,7
    注:条件中可以用逻辑运算符 比较运算符
    条件后面要加“;”
    WHILE循环
    while (条件):
    处理语句1
    处理语句2

    处理语句3

    语法解释:条件为真(满足条件)执行语句1,2,在判断条件,还满足条件的话,还执行1,2直到不满足条件,执行语句3

    while (条件1):
    if (条件2):
    处理语句1
    处理语句2

    elif (条件3):
    处理语句3
    处理语句4

    else:
    处理语句5
    处理语句6

    处理语句7

    语法解释:条件1为真,判断条件2,条件2为真,执行语句1,2,在判断条件1,当条件1 为假,执行7
    条件1为真,判断条件2,条件2为假,,在判断条件3,当条件3为真,执行语句3,4,判断条件1,当条件1为假,执行语句7
    条件1为真,判断条件2,条件2为假,,在判断条件3,当条件3为假,执行语句5,6,判断条件1,当条件1为假,执行语句7
    FOR循环
    for 变量 in 集合函数: 注:range是一个集合函数
    处理语句1
    处理语句2

    处理语句3

    语法解释:变量值在这个集合函数之内执行语句1,2,循环执行1,2,直到变量值不在集合函数范围内,执行语句3
    例题:for I in range(1,7); #循环了6次
    print”sjsddsj”
    BREAK \ CONTINUE
    break \ continue 只能用在循环语句中(for ,while)。
    break:跳出循环,执行循环体外的第一条语句,无论循环体内还有多少语句
    continue:跳过循环体内的语句去执行循环条件的条件判断

    	while (条件1):
    		  处理语句1
            处理语句2
    			if (条件2):
        			处理语句3
       			break
    		 	else:
        			处理语句4
        			continue
    

    处理语句5
    处理语句6

    语法解释:条件1为真,条件2为真,执行1,2,3,6
    条件1为真,条件2为假,执行语句1,2,4,1,2,4执行到条件1为假后,执行语句6
    条件1为假,执行语句6
    这个程序没有执行过语句5

    程序举例:
    a=1
    i=1
    while (a<=10):
    a=a+1
    if (a==10):
    break
    else:
    continue
    i=i+1
    print a
    print i
    运行结果:a=10 i=1
    函数
    1 type () 查看变量的数据类型

    2 Raw-input (“提示信息”) 输入函数(从界面输入的均是字符型)

    3 isdigit() 判断变量a是否是纯数字

    4 int() 强制转换类型

    5 Print输出函数
    6 range 集合函数
    Range(起始值,结束值,步长)求从开始值到小于结束值,并且以步长为某一个值的等差数列

    定义:
    Def 函数名(形参列表):
    函数体语句
    Return 返回值 #若没有返回值,不加这句
    程序举例:Def fun(a,b,c):
    Print a,b,c
    Return a+b+c
    调用:
    有返回值
    变量名=函数名(实参列表)
    例:M=fun(‘3’,’4’,’asd’)
    无返回值
    函数名(实参列表)

    第十七章 单元测试
    单元测试概念:
    1什么是单元测试:对软件的基本组成单元所作的测试(面向过程(一组函数或一个函数)面向对象(类中得方法))
    2语句:真正的处理语句才算是语句(判断框中的语句不算)。
    判定:流程图中的菱形框;
    判定数:流程图中菱形框的个数;
    分支:判定的真或假;
    分支数:判定数2;
    条件:判定中关系(比较)运算符;
    条件数:判定中关系(比较)运算符的个数;
    条件结果数:条件数
    2(每个条件有真、假两个取值)。
    3单元测试的目的:与LLD是否符合;与SRS是否符合;编程是否存在问题。
    4关注重点包括:单元接口(类型,顺序,长度,参数个数);局部数据结构;独立路径;边界值;出错处理。
    5单元测试环境包括:被测单元、驱动单元(把被测单元驱动起来,完成被测单元的调用)、桩单元(被测单元的调用的替代品,替代输入与输出),测试用例(测试数据)。
    6驱动单元的四个职责1)接收侧四数据包含测试用例输入好预期输出
    2)吧测试用例输入传送给要测试的单元
    3)将被测单元的实际输出和预期输出进行比较,得到测试结果
    4)将测试结果输出到指定位置
    7辅助技术:评估,框架应用
    8桩单元:通过一组输入和输出模拟被替代单元的行为
    单元测试静态测试:
    1.从详设的评审开始介入
    2.详设评审、编码完成后,作代码的静态检查
    (可以用专门的检查工具 如:PC_lint)
    3.代码的交叉走读 (要制定标准,标准越清晰,任务被分配者越有目标,工作越细)
    单元测试动态测试:
    1写用例之前,先确定覆盖率标准
    2写用例
    3搭建测试环境
    4执行
    5测试报告
    测试评价准则:
    系统测试评价准则:需求覆盖率(=至少被用例覆盖一次的需求项数/测试需求分析列表中的需求项数)。
    单元测试评价准则:逻辑覆盖率(=item至少被评估一次的次数/item总数)【这是一个总公式】。
    逻辑覆盖率
    逻辑覆盖率包括以下几种:语句覆盖率、分支覆盖率、条件覆盖率、分支条件覆盖率、路径覆盖率。【掌握计算公式、每种覆盖率的问题】
    1语句覆盖率=语句至少被执行一次的次数/语句总数。
    问题:有可能语句覆盖率为100%,有可能发现逻辑运算符的问题
    2判定覆盖率=每个分支取值至少被执行一次的次数/分支总数(判定数2)
    问题:当分支覆盖率为100%时,可能不能发现关系运算符的缺陷
    3条件覆盖率=每个条件取值至少被执行一次的次数/条件结果总数(条件数
    2)
    问题:条件覆盖率为100%时,有可能某个分支没有执行到,若该分支有缺陷,可能会遗漏。
    4分支覆盖率=(每个分支至少被执行一次的次数+每个条件取值至少被执行一次的次数)/(分支总数+条件结果数)
    问题:分支条件覆盖率为100%时,有可能漏路径,若该路径上有缺陷,可能遗漏
    5路径覆盖率=每个路径至少被执行一次的次数/路径总数
    问题:路径覆盖率为100%时,条件覆盖率可能不为100%
    注:独立路径覆盖,若路径覆盖率100%则条件、语句、分支覆盖率均100%
    路径一定要从始点到终点
    可以用软件来计算路径覆盖率 如BullseyeCoverage

    单元测试策略
    孤立、自顶向下、自底向下。
    ⑴ 孤立测试
    缺点:需要大量的桩和驱动
    优点:改方法是最简单最容易操作的 ,可以达到高的结构覆盖率,该方法是纯粹的单元测试
    方法:不考虑每个模块与其他模块之间的关系,为每个模块设计桩模块和驱动模块,每个模块进行独立的单元测试
    【例1】
    对象 驱动 桩
    A Driver-A Stub-B
    B Driver-B Stub-C
    C Driver-C X

    【例2】
    对象 驱动 桩
    A Driver-A Stub-B,C
    B Driver-B Stub-D
    C Driver-C Stub-E
    D Driver-D X
    E Driver-E X

    ⑵自顶向下的单元测试策略
    方法:先对最顶层的单元进行测试,把顶层所调用的单元做成桩模块。其次,对第二层进行测试,使用上面已测试的单元做驱动模块。如此类推直到测试完所有模块。
    优点:可以节省驱动函数的开发工作量,测试效率高。
    缺点:随着被测单元一个一个被加入,测试过程将变得越来越复杂,并且开发和维护的成本将增加。
    【例1】
    对象 驱动 桩
    A Driver-A Stub-B
    B Driver-A Stub-C
    C Driver-A Stub-D
    D Driver-A X

    【例2】
    对象 驱动 桩
    A Driver-A Stub-B,C,D
    B Driver-A Stub-E,C,D
    C Driver-A Stub-E,D
    D Driver-A Stub-F,E
    E Driver-A Stub-F
    F Driver-A X

    【例3】
    对象 驱动 桩
    A Driver-A Stub-B,C
    B Driver-A Stub-C,D
    C Driver-A Stub-E,D
    D Driver-A Stub-F,E
    E Driver-A Stub-F
    F Driver-A Stub-G,H
    G Driver-A Stub-H
    H Driver-A X

    a. 看被测函数下边有没有调用,如果被调用则打一个桩
    b. 假如曾经被测过的函数的时候,这些函数下边是否有调用,而那些调用是否也被测过,如果没有被测过,也需要打桩
    c. 只要驱动单元驱动的时候,所依赖的函数要run的时候,相关的调用都需要加入
    ⑶自底向上的单元测试方法
    方法:先对模块调用层次图上最低层的模块进行单元测试,模拟调用该模块的模块做驱动模块。然后再对上面一层做单元测试,用下面已被测试过的模块做桩模块。以此类推,直到测试完所有的模块
    优点:可以节省桩函数的开发工作量,测试效率较高。
    缺点:不是纯粹的单元测试,底层函数的测试质量对上层函数的测试将产生很大的影响。
    对象 驱动 桩
    E Driver-E X
    C Driver-C X
    F Driver-F X
    B Driver-B X
    D Driver-D X
    A Driver-A X

    如果桩难写,采用自底向上;如果驱动难写,采用自顶向下。
    打桩原则:1被测函数有没有调动,若有调动则打桩
    2加入曾经被测过的函数,这些函数是否有调动,这些调动是否被测过,都没有则打桩
    【例子】
    自底向下
    对象 驱动 桩
    F Driver-F X
    I Driver-I X
    J Driver-J X
    G Driver-G X
    H Driver-H X
    E Driver-E X
    C Driver-C X
    D Driver-D X
    B Driver-B X
    A Driver-A X
    自顶向下
    对象 驱动 桩
    A Driver-A Stub-B
    B Driver-A Stub-C,D
    C Driver-A Stub-E,D
    D Driver-A Stub-E
    E Driver-A Stub-F,G,H
    F Driver-A Stub-G,H
    G Driver-A Stub-I,H
    H Driver-A Stub-I,J
    I Driver-A Stub-J
    J Driver-A

    单元测试用例设计(基本路径覆盖法)★ (面试)
    步骤:(所有的循环仅执行一次)
    1)画流程图
    2)根据流程图画出流图
    3)根据流图找出独立路径
    4)根据独立路径设计用例
    结点:表示一个或者多个无分支的语句
    边:表示处理流向
    分支:判定真假的语句
    区域:由结点和边构成的,域的个数等于独立路径的条数
    注:路径一定要从始点到终点
    复杂性计算 :V(G)=E-N+2
    V ( G ) =P+1
    E:边,
    N:结点数量,
    P:条件结点的数量,
    V最好不要大于10
    程序控制流图
    1顺序结构
    2if结构
    3while循环结构
    4until重复结构
    5Case分支结构(swith结构)

    单元测试执行
    单元测试执行的过程:
    单元计划—单元设计—单元测试用例脚本----单元测试执行
    1.搭建环境 引入googletest
    a)将googletest的include和lib两个文件夹复制到VS的项目文件夹下
    b)在Visual Studio中选择项目,属性,将include和lib导入
    c)引入googletest头文件
    #include “gtest/gtest.h”
    d)在main函数中初始化GTEST
    testing::InitGoogleTest(&argc,argv); 初始化google test
    RUN_ALL_TESTS(); 运行当前工程所有test
    2.加入被测代码
    将被测代码头文件引入
    3.新建测试代码
    新建一个文件,编写测试代码
    调用googletest宏
    TEST(测试套名字,测试用例名字)
    {
    ………
    }
    用断言函数(ASSERT、EXPECT)来判断预期结果与实际结果
    ASSERT:致命断言,若前一个执行失败,则不继续执行
    EXPECT:一般断言,前一个执行失败,继续执行
    系统测试中发现不了在单元测试中比较容易发现的问题,如内存泄露、算法缺陷
    补充:
    C语言中,用malloc申请内存,free释放内存
    C++中,用new申请内存,delete释放内存
    TDD(测试驱动开发)
    内存中的堆、栈
    编译器自动分配的内存是在栈中,栈会自动维护、清理
    手工分配的内存是在堆中,堆不会自动清理,需要手工释放,容易忽略造成内存泄露

    单元测试框架

    1. 框架是一组为重用而设计的方法,单元测试框架包括junit\cppunit\phpunit\c#unit\pyunit
    2. pyunit是 d:\py26\unittest.py
    3. 单元测试框架概念
      测试固件(test fixture)
      一组测试函数执行前或执行后要执行的语句。
      例如,void insertDB(chr sql[30])
      {
      //执行insert语句
      }
      若现在测试该函数,实际上每次测试之前都要建立数据库连接,测试完成之后都要断开断开数据库连接。
      建立连接和断开连接称之为测试固件。测试固件在框架如何体现:
      setUP(…) —表示测试函数执行之前要执行的语句,比如建立连接
      teardown(…) —表示测试函数执行之后要执行的语句,比如断开连接
      有没有测试固件,取决于被测函数在测试执行需要否

    测试用例
    主要以测试函数为主,什么是测试函数?就是对被测单元完成测试的函数,类似于原始的驱动单元。
    在框架中一般来说要继承单元测试框架的TestCase。

    测试套件
    装配测试用例的车间。
    在框架中一般来说使用TestSuite的addTest方法来进行装配,装配的就是测试用例,实际上装配的用例中的测试函数。

    测试运行器
    加载测试套件,对套件中装配的测试函数的运行。
    在框架中一般来说使用TestRunner中的run方法来进行运行TestSuite。
    4. pyunit框架中有:
    unittest.py
    测试固件 -----》TestCase类中有setUp和tearDown有这两个方法
    测试用例 -----》TestCase类,在该类中写测试函数的方法 ????
    测试套件 -----》通过TestSuite类中的addTest方法将测试用例中的测试函数加载
    测试运行器-----》通过TextTestRunner中的run方法将测试套件运行起来。
    5. 实例:
    见例子
    6. 使用pyunit单元测试步骤:
    1)import unittest
    2)继承unittest.TestCase构建自己的测试类
    3)在自己构建的测试类中,若对于测试函数有测试固件,则在setUp和tearDown中进行代码编写。否则跳到1)

    第十八章 集成测试
    1什么是集成测试
    依据概要设计说明书,对软件组成的所有函数模块和子模块进行的测试
    2目的:检查软件是否符合概要设计说明书,是否符合需求
    3关注重点
    全局变量 组合功能(集成后的问题)单元接口(1穿越模块的数据是否会丢失,即做输入输出的的形参定义是否正确2全局数据结构是否被异常修改)
    4集成测试环境
    集成后的功能:单个功能都没有问题,组合在一起时否有问题,单个功能之间是否相互影响
    进程:是一个程序在计算机上的一次执行活动,当运行了一个程序就启动了一个进程,进程是操作系统进行资源分配的单位
    线程:是进行中的一个片段
    集成测试没有联系,不存在集成,联系时全局变量,全局变量可能是内存的一片区域,也可能是同一份文件,数组,堆栈,字段,记录,变量,队列,集成也需要考虑到性能匹配问题,网络集成
    5集成测试的依据:LLD
    6集成测试的对象:接口
    7集成测试策略:大爆炸集成测试,自顶向下,自底向上,三明治集成,基于集成,分层集成,基于功能集成,基于消息集成,基于进度的集成,基于风险的集成
    1)大爆炸集成测试
    方法:对每个模块分别进行单元测试,在吧所有单元组装在一起测试
    优点:从未投入模块间,子系统间角度节省时间,减少桩和驱动的开发,节省成本,方法简单

    使用范围:小型项目,大型项目已经稳定,只有少量修改
    2)自顶向下集成测试

    深度优先:在系树的根优先,根—左—右
    广度优先:从上到下,从左到右,一层一层的
    注:调用没有加入过的都需要打桩
    优点:减少驱动的开发,测试充分(一个模块一个模块的加入)定位问题容易,效率有所下降,最容易让高层人物建立信心
    缺点:打桩开发成本较高,效率有所下降,下层容易测试不充分
    适用范围:上层稳定,下层相对不稳定的系统
    3)自底向上集成测试
    优点:桩少,定位问题容易,小测试成分,下层测试充分,问题容易暴漏
    缺点:驱动开发成本高,顶层测试不充分
    适用范围:下层稳定,上层变化较多
    4)三明治集成测试方法

    优点:桩和驱动都减少,测试灵活,问题好隔离,好定位
    缺点:测试中间层可能不充分
    适用范围:大项目
    注:采用哪种方法根据系统本身确定
    8集成测试用例可借用单元测试和系统测试用例设计技术进行用例设计
    9接口覆盖率:每个接口至少被覆盖一次的次数/系统中所有的接口
    10集成测试的层次:子系统间集成测试,模块内集成测试,子系统内集成测试,还要考虑模块间集成测试

    11集成测试过程:计划(输入HLD测试计划,输出IT计划)——设计(输出IT方案)——实施(输出IT用例,脚本——执行(输出集成测试报告,缺陷报告)

    第一阶段总结
    基础课程:测试基础、测试过程、测试方法、软件质量
    开发基础:SQL、C语言
    需求分析、需求管理(变更控制、需求跟踪)
    环境搭建
    配置管理、QC
    缺陷管理
    系统测试、集成测试、单元测试、python
    要做好测试还应该学习DB 网络知识 数据结构 算法 语言(C JAVA PYTHON)OS
    所有课程全部基于测试目的:尽量多、尽量的发现BUG,并预防BUG
    在做测试之前,先考虑可以套用哪些软件质量特性,再根据特性考虑测试点

    Test platform
    管理工具:QC ,RQM
    执行工具:QTP,LR ,WinRunner,BRAT
    数据库:SQL,Oracle,MySQL
    配置管理工具:SVN,CVS,VSS,CC,DB2
    服务器:Tomcat,IIS,JBOSS
    2. 系统测试流程:
    测试流程:需求阶段(产出测试计划):1)来自客户(用户需求)特点:用户自身根据自己的需要提出来,不考虑技术的实现能力,功能和具体细节的实现不2)来自研发(开发文档):特点,进一步明确客户的需求3)来自标准协议(手机网络协议:CSM,CDMA,WCDMA,TD_WCDMA,EDEE)
    需求分析(产出测试方案):分析测试项。罗列功能模块和功能点,产出测试项1)从质量特性的角度对测试项进行分析,包括6大特性,27个子特性2)从功能交互的角度对测试项进行分析,功能是否存在交合,交互过程中有什么影响3)按用户场景进行测试分析
    设计阶段(产出测试用例)设计方法:等价类、边界值、状态迁移图、因果图等
    执行阶段(产出测试报告)提交缺陷报告: 测试结束,研发人员根据提交的bug进行修改,之后release 1.1(新版本),进行回归测试(REG)。
    补充:
    敏捷开发模式 scrum 短小、快。 没有需求、不便于管理。
    User story 功能点。
    3. 与bug相关
    Bug的其他说法
    Defect、CR(change Request)(Moto使用这种说法、submit a CR)、issue。
    缺陷流程:
    缺陷管理工具:QC、Mantis(开源工具)、bugfree(开源)、bugzilla、DDTS(Moto)、DMS(索爱)。
    缺陷状态:New、open、fixed、reopen、assigned、reject、later(postpone)、closed、abandon、duplicate(很常见的一个状态,重复bug,原有的有效,引用时引用原来的bug)。摩托罗拉的缺陷管理系统DDTS
    Postpone原因:有争议的、项目进度紧,优先级低的bug、以后版本就没有这个功能了。
    Retest时可能是不同的测试人员做回归测试:testerA(原)、TesterB(新),测试完后需要测试经理verify
    验证完成后bug没问题tester是否可以直接closed?如果tester没有对bug进行测试,直接closed后可能导致bug遗漏。

    第二阶段项目笔记
    JXC项目
    扩展名为ASP的文件是微软开发的
    扩展名为JSP的文件是JAVA编写的
    一.建立项目JXC
    1把JXC项目方在d:
    2点JXC右键—共享和安全----WEB共享----编辑别名----执行包括脚本等权限都选上
    3删掉JXC布置:控制面板—管理工具—Internet—网站----默认网站----JXC—右键删除
    4给权限:d:\点上边的文件夹—JXC—data—右键属性----安全与共享----添加—everyone----检查名称----确定----点中everyone—权限都选上—确定
    5登录:控制面板—管理工具—Internet信息服务-----JXC—右边栏里找到index.asp右键—浏览
    6找WEB共享或者安全:工具—文件夹—查看—使用简单文件共享前面的对号去掉
    7客户端需要建TSVN,服务器需要建SVN(必须)/TSVN(可建,可不建)
    二.布置JXC
    1建立仓库:新建文件夹SVN—新建文件夹jxc52-niuxiaoqing和文件夹JXC—在文件夹jxc52-niuxiaoqing里分别新建文件夹trunk branches tags—在文件夹trunk里分别新建文件夹doc code tools—在文件夹doc里分别建立文件夹croup person—在文件person里分别新建文件夹niu wang guo
    2点SVN文件夹—jxc52-niuxiaoqing右键----create repository here
    3创建的文件结构放到仓库:SVN文件夹------tortoisvn----import
    4binary文件时二进制文件(可执行的文件)
    5.Dll动态链接库文件有什么作用
    6 1)开始—运行—CMD—目录—cd空格c:\program files\svbversion\bin(svnserve的路径)—回车
    2)svnserve.exe空格–(2个下划线)help-------回车
    3)svnserve.exe空格-d空格-r空格d:\svn\jxc52-niuxiaoqing----回车
    4)停掉服务ctrl+c
    5)上光标,又出现3)回车,启动服务

    三.配置SVN
    1、svn搭建的服务环境:svnserve方式

    2、修改文件:

    svnserve.conf //修改服务器配置文件
    anon-access = none //去除注释 匿名访问 不允许
    auth-access = write //去除注释 指定用户访问 允许

     password-db = passwd //去除注释 启用密码文件passwd
     authz-db = authz     //去除注释 启用用户文件authz
    

    passwd //增加用户并设置密码
    zhangsan = 1111 // 用户名 = 密码

    authz //控制仓库的访问权限
    [groups]
    组名 = 用户名(逗号分隔)

     [/] 代表仓库的根目录
     如果使用组:@组名 = rw
    
     [/trunk/doc/person/lisi] 控制仓库里具体目录的权限
    
     如果没有特别规定某个目录的权限,则使用根目录[\]权限
    

    3、启动服务
    1、进入svn安装目录:cd C:\Program Files\Subversion\bin

    四.访问SVN
    1 svn checkout
    输入要访问的电脑IP
    File:///仓库建立在之间的计算机上
    SVN://仓库建立在其他机器上,要通过网络方式访问
    Apache为HTTP协议请求提供服务
    Tomcat为JAVA的容器,为JAVA编译的文件解释
    IIS为ASP提供服务
    QC的前身叫testdirector
    9.0之前是mercury公司
    10.0之后是惠普公司
    支持的数据库SQL ,Oracle
    支持的应用服务器JBoss
    支持的WEB服务器JBoss,IIS

    进销存项目
    上传图片:数据库中保存的是图片名称,实体保存在jxc/upload下。access中没有存储图片的类型。

    【SqlServer数据库中binary(二进制)类型可以用来保存图片。】

    为什么改名? ------有可能重名,同一个windows目录下不能重名

    为什么是日期时间?------重名的可能性小

    在哪见过类似的实现方式?----QC生成日志,日志保存名称,年月日秒毫秒(1秒=1000毫秒)
    系统生成的文件,为了解决文件重名的问题,使用日期时间命名,做好精确到毫秒级。

    日志功能怎么测?
    保存4个内容:日志级别、日志的最大保存行数(边界值)、保存天数(边界值)、日志保存路径。

    QC非活动状态(选择域后项目下拉列表中没有这个项目了)才能导出(export)----没有人操作

    离点(10001):预期结果(有三种实现方式):保存一个新的日志、覆盖第一条、整个全删了从第一条开始写。

    保存天数(-1):不限制。
    保存路径:目录空间是否够,如果不限制保存时间,硬盘保存空间不够时怎么办?tester是否对硬盘空间

    可操作?

    安装文件后会有一个bin目录,存有大量二进制文件(编译后),扩展名为.exe,为可运行程序。

    路径写到上一级,不包括本级
    文字相同

    001 用户名 用户名和编号
    002 密码

    新密码 确认新密码合为一个需求 新密码处验证特殊符号等,确认新密码只验证是否与新密码相同。

    排序 翻页 打印 详细信息

    所在仓库 有读取数据库的代码

    测试需求:

    测试需求的目的:保证测试的完整性。
    将需求导入QC中,能得出什么东西??-------not covered 应该被用例覆盖但是还没被覆盖。
    细化需求
    每个需求项下边的description:描述该项需求具体的 测试内容,提供测试思路。
    例如:
    产品图片:
    1.浏览功能
    支持的图片格式 jpg、gif(打开文件窗口对该文件类型进行过滤,默认显示过滤类型为jpg、gif)(不区分扩展名的大小写)。
    浏览本地路径、网络路径。
    2.上传功能
    被选文件路径是否合法(选择U盘中的文件,上传前拔掉U盘;存在本地,上传前删除);
    文件的大小限制(0,1M】
    被上传文件是否被独占打开(需要编写程序来独占打开该图片)。
    图片被上传到服务器的upload目录中,而且被修改图片名称(防止该目录下出现重名文件),名称格式:YYYYMMDDHHMMSS。
    上传成功后相关图片信息(图片的新名称)被保存到buy(photo字段)和produit(photo字段)。
    3.预览功能
    预览模式:平铺、拉伸、居中【一般预览功能就这几种模式】
    使用“居中”的预览模式。

    Buy表中 shulian(数量)保存时采用四舍五入。(有bug)。如何提bug???
    输多个小数点出错 编辑框输入的内容按字符(字符串)处理,放到数据库前需要进行字符转换,多个小数点时不能转换成float型,导致语法错误。
    Bug:
    页面允许输入浮点类型,数据库中为整形。
    页面控制的类型和数据库的类型不一致。
    进销存项目总结
    测试需求分析
    工作思路参考QC需求工作流:

    1、定义测试范围

        依据:ISO9126质量模型
        确定测试范围:被测质量特性
    

    2、建立需求项
    参考需求(SRS),明确具体要测试的需求项(测试点、需求点、功能点。。。)
    树形结构,考虑分析的“粒度”(参考QC)

        (1)、粗:文件夹级(只分解到模块或者页面层次)
        (2)、中:用例级  (只分解到页面中的具体控件,如“产品名称”、“入库数量”,意味这最底层需求可以直接转换为测试用例)
        (3)、细:步骤级  (分解到用例的操作步骤 Step)
        (4)、默认使用级别:用例级
    
         考虑后期用例执行,分解出一些特殊的需求(以后会专门对应某些测试类型)
    
        (1)、页面同名:(作为模板),只考虑该页面中所有控件都输入最正确的值
                       (控件同名的需求,目的从有效、无效两方面反复验证该控件输入的合法性)
        (2)、页面同名 Page: 以后作为“界面测试”使用
        (3)、模块同名:(调用该模块内所有页面同名的用例)作为预测试使用,证明版本的基本功能是否正确
    

    3、细化需求项
    描述每个需求项的详细内容

    详细内容:
    1、页面:(星号)是否允许为空
    2、数据库: 输入类型、长度(边界值)
    3、设计:跑到(所有)的路径----精简测试用例的个数

    如:入库管理模块–新产品入库页面–入库数量控件:
    1、页面:入库输入量不能为空

    2、数据库:
    数字类型(整型)
    边界:-231 ~ 231-1
    31:整型类型占用4个字节(4B),每个字节有8位(8bit),每位有两个取值(0、1),考虑符号(正、负)占用1位
    2:代表每位(bit)有两个取值(0、1)
    31:除去符号位,还剩31位

    3、代码实现:
    1)、当键盘抬起的时候,重置输入
    测试思路:(1)、抬起按键,非法字符的输入被重置
    (2)、绕过该事件,按下字母键不抬起进行鼠标焦点切换
    2)、当粘贴之前,重置输入
    考虑粘贴功能的实现(鼠标右键进行粘贴,快捷键粘贴 Crtl+V)
    3)、小数点个数最多1个(考虑边界值0,1,2个)

     具体分析思路:
    

    4.需要进行评审
    借助Rose的活动图统一思路

    4、需求覆盖率分析
    借助工具----QC
    将写好的需求导入到QC中的需求模块
    切换到需求的第四种视图方式:Coverage Analysis (需求覆盖率分析),看需求的状态(Not Covered 未覆盖状态),得知应该被覆盖到的需求的数量(只统计最底层需求的个数)(被测对象的测试规模),进而预测试出用例的数量

    当粘贴之前
    课前复习:
    需求名称为必填项,有空行不能导到QC中。
    把相同需求分类
    从需求详细描述从哪几方面去找?(1)页面角度 获取需求(星号—是否允许为空);(2)数据库 (长度----边界值、类型);(3)代码 实现方式----【目的:精简用例的个数,路径全部覆盖】
    代码实现讲解:
    onKeyUp="value=value.replace(/[^\d.]/g,’’)
    Onkeyup:当键盘键抬起的时候
    Replace:重新设置
    (/[^\d.]/g,’’):正则表达式 d----代表数字(0~9) .------代表小数点
    整个句子解释:
    当键盘抬起的时候,判断按键是否属于数组或者小数点,如果不属于这些键,则重置该输入(取消该输入)。

    这样只要设计2个用例就可(1)输入字母;(2)输入1.5。
    如果没有的代码,只按照等价类边界值的思想设计用例,需要考虑很多情况(此处略)。
    此处总结如下:

    onbeforepaste=“clipboardData.setData(‘text’,clipboardData.getData(‘text’).replace(/[^\d.]/g,’’))” value=“1”>
    onbeforepaste:当粘贴之前
    入库数量测试(设计):
    1.输出-------入库输入量不能为空;
    2.代码实现:
    (1)当键盘抬起的时候,重置输入;
    测试思路:绕过该事件,按下字母键不抬起鼠标焦点切换
    (2)当粘贴之前,重置输入
    考虑粘贴功能的实现(鼠标右键进行粘贴,快捷键粘贴Ctrl+V)
    3.小数点个数最多1个
    测试需求分析:
    如何做??1.工作思路参考QC需求工作流
    2.定义测试范围; 依据:ISO9126质量特性确定测试范围:被测质量特性
    3.建立需求项------参考需求(SRS)明确具体要测试的需求项(又叫测试点、需求点、功能点….)树型结构,考虑分析的“粒度”
    【粗—文件夹级(只分解到模块或者页面层次);
    中------用例级(只分解到页面中的具体控件,如“产品名称”、“入库数量”)
    细-----步骤级】
    考虑后期用例执行,分解出一些特殊的需求(以后)
    1.页面同名
    2.页面同名page
    3.模块同名
    4.细化需求项
    5.需求覆盖率分析

    判定表
    解决:多个输入的组合问题

    方法1:利用数据库的查询命令—笛卡尔积(全排列组合)
    计算最终的组合数量:每个表记录数的乘积
    如:A(a1,a2)
    B(b1,b2,b3,b4)
    C(c1,c2,c3)
    Select * from A、B、C

    方法2:判定表多个条件,每个条件2个取值

    3.1.读书选择
    1、如果觉得不疲倦,并且对书中的内容不感兴趣,同时书中的内容让你不糊涂,跳到下一章去读
    2、如果觉得不疲倦,并且对书中的内容不感兴趣,同时书中的内容让你糊涂, 跳到下一章去读
    3、如果觉得不疲倦,并且对书中的内容感兴趣, 同时书中的内容让你不糊涂,继续读下去
    4、如果觉得不疲倦,并且对中书的内容感兴趣, 同时书中的内容让你糊涂, 回到本章重读
    5、如果觉得疲倦, 并且对书中的内容不感兴趣,同时书中的内容让你不糊涂,停止阅读,请休息
    6、如果觉得疲倦, 并且对书中的内容不感兴趣,同时书中的内容让你糊涂, 请停止阅读,休息
    7、如果觉得疲倦, 并且对书中的内容感兴趣, 同时书中的内容让你不糊涂,继续读下去
    8、如果觉得疲倦, 并且对书中的内容感兴趣, 同时书中的内容让你糊涂, 回到本章重读

    提炼需求:多个条件的组合生成不同的结果
    1、需求分析:
    条件:是否疲倦(是、否)、是否感兴趣(是、否)、是否糊涂(是、否)
    结果:跳到下一章、继续读、本章重读
    2、绘制判定表
    1、分别填入条件和结果,确定表格的“行数”
    2、计算条件组合的数量,规划表格的“列数”
    3、将条件进行排列组合(全排列–笛卡尔积),利用二进制原理(0代表否,1代表是)。
    4、根据每种组合方式(每列),推出其对应的结果

    	1	2	3	4	5	6	7	8
    

    条件 是否疲倦 0 0 0 0 1 1 1 1
    是否感兴趣 0 0 1 1 0 0 1 1
    是否糊涂 0 1 0 1 0 1 0 1
    结果 跳到下一章 X X
    继续读 X X
    本章重读 X X
    休息 X X
    注:虽然1、2的结果是一样的,但是不能使用等价类的思想将其合并,原因:处理路径不同。(时间紧张可以合并)。

    3、编写测试用例
    原则1:判定表中的每一列生成一个测试用例,多个测试用例
    原则2:判定表中的每一列生成一个测试用例的步骤,一个测试用例

    我们项目使用:原则2
    两个原则测试的充分程度(覆盖率)相同;
    第二种进行需求跟踪更简单易操作;

    原则1:----8个测试用例
    用例编号 用例标题 用例输入 操作步骤 预期结果
    ST-001 不疲倦+没兴趣+不糊涂 是否疲倦: 否
    是否感兴趣:否
    是否糊涂: 否 1、启动系统
    2、输入以上内容
    3、点击“提交”按钮 跳到下一章
    ST-002 不疲倦+没兴趣+糊涂 是否疲倦: 否
    是否感兴趣:否
    是否糊涂: 是 1、启动系统
    2、输入以上内容
    3、点击“提交”按钮 跳到下一章
    ST-008 。。。。。。。。 。。。。。。。。 。。。。。。。。 。。。。。。。。

    原则2:-----1个测试用例,8个步骤
    用例编号 用例标题 步骤名称 步骤输入 操作描述 预期结果
    ST-001 读书选择 启动系统 。。。。。。。。 。。。。。。。。 。。。。。。。。
    准备测试 。。。。。。。。 。。。。。。。。 。。。。。。。。
    Step 1不疲倦+没兴趣+不糊涂 是否疲倦: 否
    是否感兴趣:否
    是否糊涂: 否 1、启动系统
    2、输入以上内容
    3、点击“提交”按钮 跳到下一章
    Step 2不疲倦+没兴趣+糊涂 是否疲倦: 否
    是否感兴趣:否
    是否糊涂: 是 1、启动系统
    2、输入以上内容
    3、点击“提交”按钮 跳到下一章
    Step 8 。。。。。。。。 。。。。。。。。
    3.2.Counter

    1、测试需求分析
    条件:是否统计代码行、是否统计空行、是否统计注释行、是否统计总行
    结果:统计代码行、统计空行、统计注释行、统计总行

    2、绘制判定表
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
    条件 是否统计代码行 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
    是否统计空行 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
    是否统计注释行 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
    是否统计总行 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
    结果 统计代码行 X X X X X X X X
    统计空行 X X X X X X X X
    统计注释行 X X X X X X X X
    统计总行 X X X X X X X X

    3、生成测试用例
    每一列生成一个测试用例,一共16种组合方式
    原则1:----16个用例
    用例编号 用例编号 用例输入 操作步骤 预期结果 编写人 编写时间
    ST-001 1.
    ST-002 1.
    ST-003
    ST-004
    ST-005

    原则2:----1个测试用例,16个步骤
    用例编号 用例标题 步骤名称 步骤输入 操作描述 预期结果 编写人 编写时间
    ST-001 Counter统计

    3.3:word中的判定表举例
    Word中的判定表举例:
    (1)字体和字号

    输入太多,选择有代表的处理(等价类—减少输入个数)。
    字体:中文、英文(英文又可以分为2类:带横线(serif—如times new roman)、不带横线(sens serif----arial Unicode ))
    (2)

    组合:4个条件,每个条件2个值。
    (3)

    这个不能用判定表,因为不能同时选中“左对齐”和“右对齐”,不满足判定表使用条件。

    3.4.合并判定表
    前提:时间紧张,成本过高;
    原则:结果相同,条件有一个不同(貌似该条件没有作用);
    风险:被合并的条件可能走不同的“路径”,合并可能会造成漏测。
    对练习1(读书选择)中的判定表进行合并:

    	1	2	3	4	5	6	7	8
    

    条件 是否疲倦 0 0 0 0 1 1 1 1
    是否感兴趣 0 0 1 1 0 0 1 1
    是否糊涂 0 1 0 1 0 1 0 1
    结果 跳到下一章 X X
    继续读 X X
    本章重读 X X
    休息 X X

    判定表合并:

    	1	2	3	4
    	1、2	3、7	4、8	5、6
    

    条件 是否疲倦 0 ---- ---- 1
    是否感兴趣 0 1 1 0
    是否糊涂 — 0 1 —
    结果 跳到下一章 X
    继续读 X
    本章重读 X
    休息 X

    前提:
    合并:时间紧张,成本过高
    原则:结果相同,条件有一个不同(“貌似”该条件没有作用)
    风险:被合并的条件可能走不同的“路径”,合并会造出漏测

    3.4.密码修改
    若需修改密码,系统验证旧密码正确,两个新密码相同,则更新密码,旧密码即失效,其他修改项也生效,并提示“用户信息修改成功”; 若旧密码不正确,则提示“用户密码错”,系统将不修改个人信息;若两个新密码不同,则提示“新密码与验证新密码不同”,系统将不修改个人信息。
    若只修改密码外其他信息,则不需输入两个新密码,系统只验证旧密码正确,就成功更改个人信息,并提示“用户信息修改成功”;如果系统验证旧密码输入不正确,则提示“用户密码错”。
    流程图如下

    答案:
    (1)需求分析
    条件:只修改密码外其他信息(是/否)、旧密码(正确/错误)、新密码和验证新密码(相同/不相同)
    结果:提示“用户信息修改成功”、提示“用户密码错”、提示“新密码与验证新密码不同”
    (2)绘制判定表
    1 2 3 4 5 6 7 8
    条件 只修改密码外其他信息 0 0 0 0 1 1 1 1
    旧密码 0 0 1 1 0 0 1 1
    新密码和验证新密码 0 1 0 1 0 1 0 1
    结果 提示“用户信息修改成功” x x x
    提示“用户密码错” x x x
    提示“新密码与验证新密码不同” x
    说明 无效 无效
    (3)编写测试用例
    原则2:----1个测试用例,8个步骤
    用例编号 用例标题 步骤名称 步骤输入 操作描述 预期结果
    ST-001 修改信息 启动系统 无 双击 系统正常启动
    Step1:修改密码+旧密码错误+新密码与验证密码一致 是否只修改密码外其他信息:否;
    旧密码是否正确:否;
    新密码和验证新密码是否一致:否 1.启动系统;
    2.输入以上修改信息;
    3.点击“提交”按钮
    无任何提示信息
    Step2:修改密码+旧密码错误+新密码与验证密码一致 是否只修改密码外其他信息:否;
    旧密码是否正确:否;
    新密码和验证新密码是否一致:是 1.启动系统;
    2.输入以上修改信息;
    3.点击“提交”按钮
    提示“用户密码错”,个人信息未修改
    Step3:修改密码+旧密码正确+新密码与验证密码不一致 是否只修改密码外其他信息:否;
    旧密码是否正确:是;
    新密码和验证新密码是否一致:否 1.启动系统;
    2.输入以上修改信息;
    3.点击“提交”按钮
    提示“新密码与验证新密码不同”,个人信息未修改
    Step4:修改密码+旧密码正确+新密码与验证密码一致 是否只修改密码外其他信息:否;
    旧密码是否正确:是;
    新密码和验证新密码是否一致:是 1.启动系统;
    2.输入以上修改信息;
    3.点击“提交”按钮
    提示“用户信息修改成功”,旧密码生效,其他个人信息修改
    Step5:只修改密码外信息+旧密码错误 是否只修改密码外其他信息:是;
    旧密码是否正确:否;
    新密码和验证新密码是否一致:否 1.启动系统;
    2.输入以上修改信息;
    3.点击“提交”按钮
    提示“用户密码错”,个人信息未修改
    Step7:只修改密码外信息+旧密码正确 是否只修改密码外其他信息:是;
    旧密码是否正确:是;
    新密码和验证新密码是否一致:否 1.启动系统;
    2.输入以上修改信息;
    3.点击“提交”按钮
    提示“用户信息修改成功”,其他个人信息修改

    3.5.进销存
    进销存中的下列选框可以使用判定表的方法设计用例:

    (1)需求分析
    条件: 仓库(所有仓库/具体仓库)(0表示所有仓库,1表示具体仓库)【“具体”只测试一个即可,处理方式相同,等价类思想】
    类别(包括大类和小类,有三种组合,分别为所有/所有、具体/所有、具体/具体)(分别使用0、1、2表示)
    关键字(填/不填)(0表示不填,1表示填)
    结果:所有仓库所有库存、所有仓库具体库存、具体仓库所有库存、具体仓库具体库存
    (2)绘制判定表
    1 2 3 4 5 6 7 8 9 10 11 12
    条件 仓库 0 0 0 0 0 0 1 1 1 1 1 1
    类别 0 0 1 1 2 2 0 0 1 1 2 2
    关键字 0 1 0 1 0 1 0 1 0 1 0 1
    结果 所有仓库所有库存 X X
    所有仓库具体库存 X X X X
    具体仓库所有库存 X X
    具体仓库具体库存 X X X X
    (3)编写测试用例
    使用原则2:----1个测试用例,12个步骤
    用例编号 用例标题 步骤名称 步骤输入 操作描述 预期结果
    ST-001 库存查询信息组合查询 进入库存查询页面。 无 1.打开进销存网页;2.点击库存管理模块中的库存查询页面。 界面显示库存查询页面。
    Step1:所有仓库+所有大类+所有小类+不填关键字 仓库:所有仓库;
    类别:所有大类和所有小类;
    关键字:不填 1.在页面右上角搜索处选择所有仓库;
    2.在页面右上角搜索处选择所有大类和所有小类;
    3.不填写关键字;
    4.点击“查询”按钮。 页面中显示所有仓库的所有库存信息
    Step2:所有仓库+所有大类+所有小类+填关键字 仓库:所有仓库;
    类别:所有大类和所有小类;
    关键字:填 1.在页面右上角搜索处选择所有仓库;
    2.在页面右上角搜索处选择所有大类和所有小类;
    3.填写关键字;
    4.点击“查询”按钮。 页面中显示所有仓库的所有库存信息
    Step3:所有仓库+具体大类+所有小类+不填关键字 仓库:所有仓库;
    类别:具体大类和所有小类;
    关键字:不填 1.在页面右上角搜索处选择所有仓库;
    2.在页面右上角搜索处选择具体某一个大类和所有小类;
    3.不填写关键字;
    4.点击“查询”按钮。 页面中显示所有仓库的具体库存信息
    Step4:所有仓库+具体大类+所有小类+填关键字 仓库:所有仓库;
    类别:具体大类和所有小类;
    关键字:填 1.在页面右上角搜索处选择所有仓库;
    2.在页面右上角搜索处选择具体某一个大类和所有小类;
    3.填写关键字;
    4.点击“查询”按钮。 页面中显示所有仓库的具体库存信息
    Step5:所有仓库+具体大类+具体小类+不填关键字 仓库:所有仓库;
    类别:具体大类和具体小类;
    关键字:不填 1.在页面右上角搜索处选择所有仓库;
    2.在页面右上角搜索处选择具体某一个大类和具体某一个小类;
    3.不填写关键字;
    4.点击“查询”按钮。 页面中显示所有仓库的具体库存信息
    Step6:所有仓库+具体大类+具体小类+填关键字 仓库:所有仓库;
    类别:具体大类和具体小类;
    关键字:填 1.在页面右上角搜索处选择所有仓库;
    2.在页面右上角搜索处选择具体某一个大类和具体某一个小类;
    3.填写关键字;
    4.点击“查询”按钮。 页面中显示所有仓库的具体库存信息
    Step7:具体仓库+所有大类+所有小类+不填关键字 仓库:具体仓库;
    类别:所有大类和所有小类;
    关键字:不填 1.在页面右上角搜索处选择具体某一个仓库;
    2.在页面右上角搜索处选择所有大类和所有小类;
    3.不填写关键字;
    4.点击“查询”按钮。 页面中显示具体仓库的所有库存信息
    Step8:具体仓库+所有大类+所有小类+填关键字 仓库:具体仓库;
    类别:所有大类和所有小类;
    关键字:填 1.在页面右上角搜索处选择具体某一个仓库;
    2.在页面右上角搜索处选择所有大类和所有小类;
    3.填写关键字;
    4.点击“查询”按钮。 页面中显示具体仓库的所有库存信息
    Step9:具体仓库+具体大类+所有小类+不填关键字 仓库:具体仓库;
    类别:具体大类和所有小类;
    关键字:不填 1.在页面右上角搜索处选择具体某一个仓库;
    2.在页面右上角搜索处选择具体某一个大类和所有小类;
    3.不填写关键字;
    4.点击“查询”按钮。 页面中显示具体仓库的具体库存信息
    Step10:具体仓库+具体大类+所有小类+填关键字 仓库:具体仓库;
    类别:具体大类和所有小类;
    关键字:填 1.在页面右上角搜索处选择具体某一个仓库;
    2.在页面右上角搜索处选择具体某一个大类和所有小类;
    3.填写关键字;
    4.点击“查询”按钮。 页面中显示具体仓库的具体库存信息
    Step11:具体仓库+具体大类+具体小类+不填关键字 仓库:具体仓库;
    类别:具体大类和具体小类;
    关键字:不填 1.在页面右上角搜索处选择具体某一个仓库;
    2.在页面右上角搜索处选择具体某一个大类和具体某一个小类;
    3.不填写关键字;
    4.点击“查询”按钮。 页面中显示具体仓库的具体库存信息
    Step12:具体仓库+具体大类+具体小类+填关键字 仓库:具体仓库;
    类别:具体大类和具体小类;
    关键字:填 1.在页面右上角搜索处选择具体某一个仓库;
    2.在页面右上角搜索处选择具体某一个大类和具体某一个小类;
    3.填写关键字;
    4.点击“查询”按钮。 页面中显示具体仓库的具体库存信息

    3.6.总结
    1、什么时候用:
    (1)有多个输入需要组合的时候,采用判定表进行用例设计;
    2、怎么用:
    (2)使用判定表进行用例设计,有以下3个步骤:
    a)需求分析,通过对多个条件的组合生成不同的结果进行分析,得出条件和结果。
    b)绘制判定表。
    i.分别填入条件和结果,确定表格的“行数”;
    ii.计算条件的组合数量,规划表格的“列数”;
    iii.将条件进行排列组合,利用二进制原理;
    iv.根据每种组合方式,推出其对应的结果。
    c)编写测试用例
    有2种方式:判定表中的每一列生成一个测试用例,最终生成多个测试用例;
    判定表中的每一列生成一个测试用例的步骤,最终生成一个测试用例。
    3判定表的优点和缺点
    (3)优点:组合充分,没有遗漏;
    缺点:当条件数多的时候(超过5个)用例数量多,成本高。

    因果图

    条件和结果之间的关系:

    恒等:条件成立,结果成立
    非: 条件成立,结果不成立
    或: 只要有一个条件成立,结果成立
    与: 必须所有条件都成立,结果成立

    条件之间的关系:

    E:不能同时为“真”
    I:不能同时为“假”
    O:有且仅有一个为“真”

    第一个举例:呼吸,用鼻子和嘴(异)
    因果图作用:1、条件和结果之间的关系:分析业务逻辑(类似流程图的作用)
    2、条件之间的关系:去除判定表中的无效的列
    使用viso绘制因果图:
    操作步骤:
    (1):在viso中选择基本流程图,
    (2)按照等价(处理方式相同)条件,添加中间节点(临时结果)。如:A、B处理相同(等价类),做中间节点(如A or B)。
    (3)分析条件和结果之间的关系(恒等、与、或、非)。
    如果不是一次退出结果,或者连线较多,可以增加中间节点。
    (4)分析条件之间的关系(E、I、O)。

    4.1.字母判定
    第一列字符必须是A或B,第二列字符必须是一个数字(每列只能输入一个字符),在此情况下(只有这个时候才)进行文件的修改,但如果第一列字符不正确,则给出信息L;如果第二列字符不是数字,则给出信息M。
    不能使用等价类【不是单一条件】

    1、测试需求分析
    条件:第一列是A、第一列是B、第二列是数字
    结果:修改文件、 提示L、 提示M

    2、绘制因果图

    3、绘制判定表
    假设:当判断完是否是AorB条件后,如果取“否”,则退出系统运行。【实际工作中不允许假设】。

    利用因果图条件之间的关系,去除无效列

    	1	2	3	4	5	6	7	8
    

    条件 第一列是A 0 0 0 0 1 1 1 1
    第一列是B 0 0 1 1 0 0 1 1
    第二列是数字 0 1 0 1 0 1 0 1
    结果 修改文件 X X
    提示L X X
    提示M X X
    实际输入 CC T7 B@ B5 AF A6 无效 无效

    第一种条件是提示L还是提示L、M,在公司中要找开发人员询问,不能主观猜测。

    编写测试用例
    原则2:----1个测试用例,8个步骤
    用例编号 用例标题 步骤名称 步骤输入 操作描述 预期结果 编写人 编写时间
    ST-001 修改文件

    4.2.自动售货机
    有一个处理单价为5角钱的饮料的自动售货机软件测试用例的设计。其规格说明如下:若投入5角钱或1元钱的硬币,押下〖橙汁〗或〖啤酒〗的按钮,则相应的饮料就送出来。若售货机没有零钱找,则一个显示〖零钱找完〗的红灯亮,这时在投入1元硬币并押下按钮后,饮料不送出来而且1元硬币也退出来;若有零钱找,则显示〖零钱找完〗的红灯灭,在送出饮料的同时退还5角硬币。

    1、测试需求分析:
    条件:有零钱、投1元、投5角、选啤酒、选橙汁
    结果:红灯亮、退1元、找5角、出啤酒、出橙汁

    2、绘制因果图

    3、绘制判定表

    红色列为无效组合

    4、生成测试用例
    经办人不能为空,程序中通过管理员ID判断当前登陆用户是否为管理员,如果在数据库login表中删除再添加一个管理员后id变了,导致查询错误。
    Admin登陆,下拉列表中显示所有系统的用户,非admin登陆,下拉列表中只显示当前登陆用户。
    关于下拉列表的问题:

    关于单元测试逻辑覆盖率:
    在只有一个条件时,路径覆盖率为100%时,条件覆盖率也是100%。
    如果条件不是布尔类型,可以使用数据库中的多表关联,计算笛卡尔积。
    如:
    A表(a1、a2)
    B表(b1、b2、b3、b4)
    C表(c1、c2、c3)
    使用select * from A、B、C;查询。

    状态迁移
    5.1.飞机售票系统
    1、客户向航空公司打电话预定机票—>此时机票信息处于“完成”状态
    2、顾客支付了机票费用后—>机票信息就变为“已支付”状态
    3、旅行当天到达机场后,拿到机票后—>机票信息就变为“已出票”状态
    4、登机检票后—>机票信息就变为“已使用”状态
    5、在登上飞机之前任何时间可以取消自己的订票信息,如果已经支付了机票的费用,则还可以得到退款,取消后—>订票信息处于“已被取消”状态

    1、测试需求分析
    状态:完成、已支付、已出票、已使用、已被取消

    2、绘制状态迁移图
    使用rose画状态图:
    方法:
    (1)右键,新建状态图New -----stagechar Diagram。

    特点:每个状态只出现一次

    3、生成用例 — 路径覆盖
    绘制状态迁移树-----每个树枝生成一个测试用例

    特点:
    1、每个状态可以出现多次
    2、箭头方向统一向“右”延伸
    3、状态转换如果出现循环,该路径只遍历一次
    4、编写测试用例
    用例编号 标题 步骤名称 步骤描述 预期结果
    STC-001 售票流程 启动系统
    准备测试数据和环境
    Step 1 完成-取消 1、客户向航空公司打电话预定机票
    2、取消该机票 1、此时机票信息处于“完成”状态
    2、订票信息处于“已被取消”状态
    Step 2 完成-支付-取消 。。。。。 。。。。。
    Step 3 。。。。。 。。。。。
    Step 4 。。。。。 。。。。。
    那些软件适合状态迁移
    淘宝买东西、QC需求、配置管理状态(normal、modified.;……)、缺陷状态(new、open……)
    QC需求状态(只考虑一次运行)

    5.2.缺陷跟踪

    流程分析
    使用ROSE中的活动图进行分析

    状态:吃饭中(有一个延续,使用ing)。
    活动:吃饭
    方法:
    (1)右键,新建状态图New -----activity Diagram。

    6.1.处理流程
    在某嵌入式系统中,将待发送的数据打包成符合CAN协议的帧格式后,便可写入发送缓站区,并自动发送。该发送子程序的流程为:
    1、首先进入发送子程序
    2、系统判断是否有空闲发送缓冲区,如果没有则返回启动发送失败消息。
    3、如果有空闲缓冲区,将数据包写入空闲发送缓冲区
    4、系统判断是否写入成功,如果不成功则返回启动发送失败消息
    5、如果写入成功,则启动发送命令
    6、返回启动发送成功消息
    1、绘制流程(活动)图

    2、生成测试用例------ 路径覆盖
    1、(A) (B) (C) (D) (E) (F) 基本流
    2、(A) (B) (G) 备选流
    3、(A) (B) (C) (D) (G) 备选流

    6.2.系统登录

    C/S程序。
    先判断是否为空,再去判断是否合法,涉及到效率问题。
    把判断时间短的放前边。

    用例:6个(路径)
    单个测试用户名考虑:空、最大值、特殊符号、匹配、不匹配
    6.3.字母判断

    用例:
    基本流: (1) (2) (3)
    (1A) (2) (3) 6列
    (1B) (2) (3) 4列
    备选流1:(1) (4) 1、2列
    备选流2:(1) (2) (5)
    (1A) (2) (5) 5列
    (1B) (2) (5) 3列

    	1	2	3	4	5	6	7	8
    

    条件 第一列是A 0 0 0 0 1 1 1 1
    第一列是B 0 0 1 1 0 0 1 1
    第二列是数字 0 1 0 1 0 1 0 1
    结果 修改文件 X X
    提示L X X
    提示M X X
    实际输入 CC T7 B@ B5 AF A6 无效 无效

    合并判定表
    1 2 3 4 5
    1、2 3 4 5 6
    条件 第一列是A 0 0 0 1 1
    第一列是B 0 1 1 0 0
    第二列是数字 ---- 0 1 0 1
    结果 修改文件 X X
    提示L X
    提示M X X
    实际输入 CC B@ B5 AF A6
    使用流程图和判定表
    都可以,使用流程图前提要保证流程图正确
    6.4.组合查询
    库存管理–库存查询代码实现:
    //
    nowkeyword–输入在查询关键字
    nowku-------输入在仓库名对应在id
    nowbigclass—输入的大类对应的id
    nowsmallclass—输入的小类对应的id
    &—+加在之前sql语句后边

    语句覆盖100%:1个用例;
    分支覆盖100%:2个用例;
    路径覆盖100%:16个用例。
    可以使用独立路径(每个路径只走一次):A-----、AB------、AC------、AD------、AE------(非法用例,不选大类不能选小类,使用ADE)。可以再找一个全选ABCDE。共6个用例。

    用例:
    1、 (A) (F) 独立路径
    2、 (A) (B) (F) 独立路径
    3、 (A) (C) (F) 独立路径
    4、 (A) (D) (F) 独立路径
    5、 (A) (D) (E) (F) 独立路径
    6、 (A) (B) (C) (D) (E) (F) 补充
    补充1关于where中1=1的问题:

    两个查询是一样的。为什么要加上1=1呢??因为每个select查询语句调教中只能加一个where,可以加多个and;如果在这句中不加1=1,之后的sql语句需要判断之前是否加过where,再做处理,影响查询效率。
    查询效率高。
    如果查询的是两个表,两个表查询就不用写了,两个表关联时就把where语句占用了。
    补充2取仓库ID,而不是仓库名称:
    代码实现:

    下拉列表由2部分组成,分别为value和库名。

    课前复习
    单个输入------- 等价类边界值
    多条件组合------判定表(全排列组合,组合个数2n(n代表条件个数)条件是布尔类型,如果不是布尔类型,参考数据库笛卡尔积,条件取值个数相乘)。
    ------因果图(帮助描述中间处理过程,去除判定表中的无效组合,3种约束:E、I、O)
    ------正交试验(两两组合)
    每个条件取值不规范,使用allpairs工具。
    处理流程问题------状态迁移(强调状态属性,用状态来描述流程)
    -----流程分析(活动图活流程图)
    生成用例原则:单元测试的路径覆盖。路径太多可以取独立路径或分支覆盖。

    正交试验
    7.1.环境搭建
    假设一个WEB站点,该站点有大量的服务器和操作系统,并且有许多具有各种插件的浏览器浏览:

    环境配置 Web浏览器 浏览器插件 操作系统 服务器
    配置选项 Netscape RealPlayer WinXP IIS
    IE Flash Win2000 Tomcat
    Firefox PDF Reader Win2003 Weblogic

    1、测试需求分析,找出条件和取值
    条件:4个
    取值:每个条件有3个取值

    2、选择正交表: L9_3_4
    9:代表最终生成用例的个数
    4:因素(因数),代表条件的个数
    3:水平,代表每个条件取值的个数

    3、生成用例
    因素 Web浏览器 浏览器插件 操作系统 服务器
    实验1 Netscape RealPlayer WinXP IIS
    实验2 Netscape Flash Win2000 Tomcat
    实验3 Netscape PDF Reader Win2003 Weblogic
    实验4 IE RealPlayer Win2000 Weblogic
    实验5 IE Flash Win2003 IIS
    实验6 IE PDF Reader WinXP Tomcat
    实验7 Firefox RealPlayer Win2003 Tomcat
    实验8 Firefox Flash WinXP Weblogic
    实验9 Firefox PDF Reader Win2000 IIS

    正交表的特点:
        1、任意一列,每个取值出现的次数一致(均匀)(本题出现3次)
        2、任意两列,任何两个值得组合出现的次数一致(均匀)(本题出现1次)
        3、任意一列,该列的每个值都和其他列的所有值成对组合过(均匀)(本题组合1次)
           正交表:充分的两两组合(9个用例)
           判定表:全排列组合(两两组合、三三、四四。。。。组合)(81个用例)
           
    使用原则:根据经验,如果充分的两两组合不出问题,那么多次组合出问题的可能性很小,基于成本、时间等因素,可以考虑正交试验方法生成测试用例
    

    7.2.Counter

    因素 代码行 注释行 空行 总行
    实验1 选 选 选 选
    实验2 选 选 选 不选
    实验3 选 不选 不选 选
    实验4 选 不选 不选 不选
    实验5 不选 选 不选 选
    实验6 不选 选 不选 不选
    实验7 不选 不选 选 选
    实验8 不选 不选 选 不选
    补充 不选 不选 不选 选
    补充 不选 不选 不选 不选

    7.3.组合
    题目:
    土壤的酸碱度:酸性、碱性、中性
    土壤的潮湿度:潮湿、干燥
    土壤的温度: 高温、低温
    提供标准正交表:
    因素 A B C
    实验1 0 0 0
    实验2 0 1 1
    实验3 1 0 1
    实验4 1 1 0

    答案:
    方法1)、正交试验方法:
    正交表:L4_2_3
    土壤的酸碱度:0(酸性)、1(碱性+中性)
    土壤的潮湿度:0(潮湿)、1(干燥)
    土壤的温度: 0(高温)、1(低温)

    因素 酸碱度 潮湿度 温度
    实验1 酸性 潮湿 高温
    实验2 酸性 干燥 低温
    实验3 碱性+中性 潮湿 低温
    实验4 碱性+中性 干燥 高温

    拆分正交表
    

    因素 酸碱度 潮湿度 温度
    实验1 酸性 潮湿 高温
    实验2 酸性 干燥 低温
    实验3 碱性 潮湿 低温
    实验4 中性 潮湿 低温
    实验5 碱性 干燥 高温
    实验6 中性 干燥 高温

    方法2)、判定表方法:
    绘制判定表
    1 2 3 4 5 6 7 8
    条件 酸碱度 0 0 0 0 1 1 1 1
    潮湿度 0 0 1 1 0 0 1 1
    温度 0 1 0 1 0 1 0 1

    带入判定表
    1 2 3 4 5 6 7 8
    条件 酸碱度 酸性 酸性 酸性 酸性 碱性+中性 碱性+中性 碱性+中性 碱性+中性
    潮湿度 潮湿 潮湿 干燥 干燥 潮湿 潮湿 干燥 干燥
    温度 高温 低温 高温 低温 高温 低温 高温 低温

    拆分判定表
    1 2 3 4 5 6 7 8 9 10 11 12
    条件 酸碱度 酸性 酸性 酸性 酸性 碱性 中性 碱性 中性 碱性 中性 碱性 中性
    潮湿度 潮湿 潮湿 干燥 干燥 潮湿 潮湿 潮湿 潮湿 干燥 干燥 干燥 干燥
    温度 高温 低温 高温 低温 高温 高温 低温 低温 高温 高温 低温 低温

    时间不充裕选择正交实验法,否则选择判定法(充分)

    方法3)、Allpairs工具实现
    使用allpairs工具:
    Cmd-----进入allpairs目录下 cd C:\Documents and Settings\51testing\桌面\allpairs----
    新建空白excl文件,将条件复制到excl中,

    TEST CASES
    case 土壤酸碱度 土壤潮湿度 土壤温度
    1 酸性 潮湿 高温
    2 酸性 干燥 低温
    3 碱性 潮湿 低温
    4 碱性 干燥 高温
    5 中性 潮湿 高温
    6 中性 干燥 低温

    7.4.环境搭建
    假设一个WEB站点,该站点有大量的服务器和操作系统,并且有许多具有各种插件的浏览器浏览:

    环境配置 Web浏览器 浏览器插件 操作系统 服务器
    配置选项 IE RealPlayer WinXP IIS
    Firefox Flash Win2000 Tomcat
    PDF Reader Win2003 Weblogic
    Baidu Win 7
    XunLei

    练习:进销存

    条件:
    仓库:所有、具体
    大类和小类:所有-所有、具体-所有、具体-具体
    关键词:不填、货号(模糊)、产品名称(模糊)

    其他
    输入域
    寻找输入中的特殊值
    如:注册页面输入用户名:hujintao、admin、administrator…….
    如:结构化输入(相互制约)要考虑组合:日期(年月日)、国家—城市,进销存权限复选控制(库存查询、删除)
    【上下级关系的选项】
    员工权限
    Bug:不选库存查询可以选择修改和删除。
    输出域
    找输出或者设计的等价类和边界值----根据结果的边界反推出输入
    如:数据库涉及时间的查询(首尾时间参考数据的第一条和最后一条记录的时间)
    如:QC需求,同级最大的需求数量:263
    最多的子集层数:255/3 = 85
    如:QC中的日志最大行数、
    如:QC中添加字段最多可以添加24个字段(可以通过查看数据库中的表得到)。

    异常分析
    可靠特性:容错、恢复
    如:SQL Server的导入功能(在源数据上构造错误数据,看异常处理功能的代码是否正确)
    如:进销存的数据还原

    错误猜测
    凭经验
    如:数字输入框(非数字字符的输入控制,小数点的个数)
    数据库的设计(约束关系)

    作业:
    三角形问题:

    成立条件:两边之和大于第三边。
    1、等价类
    2、判定表
    3、流程分析。
    密码修改问题:
    1、判定表
    流程分析

    展开全文
  • Python_精灵精灵

    2021-09-08 09:44:04
    1. 基本概念 2. 自定义精灵子类需求分析 3. 派生精灵子类代码实现 4. 创建敌机并且实现敌机动画
  • 按键精灵初接触

    千次阅读 2018-09-05 11:03:38
    目前按键精灵类似软件很多,比较火的如按键精灵叉叉助手之类的。 按键精灵主要面向大众,完全是自己的语言(汉字的哟),一套逻辑去开发。 叉叉助手是面向手机端多适配的,适配ios和android双系统的,利用lua...
  • 搜索优化之四树算法(三)

    千次阅读 2018-04-24 21:14:24
    上节内容讲解了如何使用递归方式创建四树,并附上了具体的实现代码,递归式一种很优美的编码方式,自然,简洁,方便理解 本节内容我们会将显示对象绑定到节点上,并实现动态四树更新显示对象的节点位置,何为...
  • 以下是当网络出现黄时,可能会使用到的几钟解决方式。 1.获取IP地址。 1.1 运行快捷键 Window + R,输入cmd,输入 ipconfig,显示界面如下。 1.2 此时可能会出现一种情况,无法执行ipconfig命令,且出现...
  • CSS精灵移动 CSS精灵生成器。 从图像目录中生成精灵和适当的css文件。 支持视网膜精灵。 可以内嵌base64编码的精灵。 来自CSS Sprite的fork 要求 从版本0.9开始css-sprite没有任何外部依赖 安装 用安装 npm ...
  • 【步兵 cocos2dx】四树碰撞算法 by EOS.四树碰撞网上例子不少,自己也观摩了一下,然后自己写了一个。 并不是想证明自己写的比别人好,不自己写一遍,总感觉自己不认识它。 写过之后感觉,深入了解,并且自己...
  • 解决电脑右下角小喇叭一个红色叉叉。 小办法就不说了。上大招。 首先下载驱动精灵。然后更新驱动,这里就不详细了 如果驱动是旧的,那么会提示你更新驱动, 更新完后重启电脑, 但是还会 小喇叭有红色叉叉 ...
  • 指南针的视网膜精灵 公告-已描述 我不再在项目中积极使用Sprite,因此我将不再维护它。 Pivital Tracker有一个不错的前叉,它更快,电流更大。 我建议继续使用此功能! 在建立Tagit网站时,我遇到了在普通和视网膜...
  • 先从第一个简单问题说起,比如两个面板之间显示一个粒子效果,粒子特效本身是用“点精灵”渲染的,每个粒子就是一个点精灵,可以看做一个片模型,而片模型就可以通过设置 Sorting Order 属性来修改显示层级。 ...
  • * 多边形碰撞器: 该方法是指给精灵(Sprite)添加一个多边形碰撞器(Rolygon Collider)组件,利用该组件来标记精灵的边界,这样通过比较鼠标位置和边界可以判断点击是否发生在精灵内部。这种方法的详细说明可以参考宣雨...
  • 宠物小精灵Quest Pokedex(网络应用) 该项目使用最少的构建工具,以使其分叉尽可能简单。 现在,出于这个原因,我也选择不缩小代码。 dest/中的文件是纯html,css和js,可以这样进行编辑。 将dest文件夹拆分为gh-...
  • 楚留香自动采矿--按键精灵

    千次阅读 2019-07-31 00:06:31
    按键精灵: Do While True Delay 3000 nowH = Hour(Now) nowM = Minute(Now) mnowH = nowH mod 6 If mnowH = 0 and nowM = 1 Then //确认 TracePrint “确认体力” TracePrint nowM TracePrint mnowH Delay 2000 ...
  • 小喇叭上面有个叉号,一般为未启动音频服务,或设备被禁用,或驱动损坏等,检修方法如下。 方法一:启动音频服务 1,开始->运行->输入services.msc...3,如果没有备份与驱动光盘,用驱动精灵软件自动更新。 倪震
  •  实现效果 三.CSS精灵图技术 图标的获取来源于CSS精灵图技术, 并把宽高缩小为原图大小的一半, 这里就需要用到background-size属性: .wrap .list li > a > i{ display: block; background-image: url("ctrip.png");...
  • 冰点还原精灵如何关闭?

    千次阅读 2018-10-11 16:10:00
    为了保护电脑系统,所以会在电脑上安装系统还原软件,但是要在安装了冰点还原的计算机上安装并使用新的软件,那就必须先关闭冰点精灵,不然就白装了,因为冰点软件会自行将其系统还原到安装新软件之前的状态。...
  • 沃通代码签名精灵(WoSignCode)是沃通自主研发的可视化代码签名工具,全球独家支持SHA1、SHA2双证书签名,同时支持批量签名,支持多种可执行文件、打包文件签名,提供便捷、可视化的操作界面,让代码签名变得更加简单...
  • 精灵模块介绍(Sprite Module Introduction) Author: Pete Shinners Contact: pete@shinners.org         Pygame 1.3版带有一个新模块pygame.sprite。该模块是用Python编写的,包含一些用于...
  • 宠物小精灵 :rocket: 介绍 使用pokeApi的Web应用程序 二手的Api :man::laptop: 使用语言 Vue.js 引导程序 :thinking_face: 如何贡献 分叉此存储库; 使用您的功能创建分支: git checkout -b minha-feature ...
  • 《太空站13》是一款充满偏执狂的回合角色扮演游戏,背景是伪装成太空站的荒谬的金属死亡陷阱,其迷人的精灵图案旨在代表科幻场景及其危险的底色。玩得开心,生存下去! 开发流程图 资料下载 :red_exclamation_mark...
  • 大疆精灵4航测输出正摄影和三维模型教程

    万次阅读 多人点赞 2019-03-15 12:04:39
    01影像数据的获取 近年来消费级无人机使用...今天以大疆精灵系列无人机为例,主要介绍使用Pix4dCapture和Altizure软件进行无人机正射和倾斜三维影像数据获取,后续文章再单独介绍无人机影像数据处理。 大疆...
  • 树瓦片集合类QuadTileSet是影像瓦片渲染的主要类。使用地形管理器来为3D地形渲染查询高程值。依赖于用来刷新基于经度、纬度、视角范围瓦片的更新线程。该类继承自可渲染对象类RenderableObject。该类的类图如下...
  • 按键精灵对VBS的支持

    2015-09-04 17:02:00
    如果没有引号,按键精灵将首先试图把参数当作一个表达式(包括变量)去解析,只有解析不成功的时候,才会把参数当成固定的字符串。 就是说,如果写 MessageBox abc 当有一个变量叫 abc 的时候,弹出对话框的内容将...
  • 远程主机的“服务”程序通常被昵称为“精灵”,它平时不声不响地守候在远程主机上,一接到本地主机的请求,就会立马活跃起来,并完成以下功能: 通知本地主机,远程主机已经准备好了。 等候本地主机输入命令...
  • 小冰与小娜:命运交叉的美少女AI

    千次阅读 2020-07-15 11:29:38
    多才多艺“冰” 正当小娜在国内沉寂无声、在国外节节败退的时候,中国市场却早已经容不下小冰这个鬼精灵了。 2015年8月7日,微软小冰向海外市场迈出了第一步——微软与LINE联合宣布上线与小冰采用相同底层技术的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,162
精华内容 864
关键字:

叉叉精灵