Robot Framework + Selenium 框架,关键字封装,知识点记录

目录

框架概述:

通用关键字:

等待类关键字:

通用组件 等待 元素:

通用组件 获取 元素居中滚动像素:

通用组件 页面滚动 :

通用组件 等待包含文字:

通用组件 自动切换frame :

通用组件 选择上次frame: 

通用组件 循环选择frame: 

通用组件 尝试获取页面弹窗消息: 

操作类关键字: 

通用组件 等待并输入文本:

通用组件 等待并获取文本:

通用组件 等待并点击元素: 

通用组件 等待并双击元素: 

通用组件 等待并鼠标点击元素:

通用组件 AutoIt上传 chrome版:

通用组件 关闭所有浏览器: 

切换 窗口:

数据处理类关键字:

通用组件 获取excel内容:

通用组件 账号脱敏展示处理:

通用组件 生成统一社会信用代码:

通用组件 随机获取身份证号码:

通用组件 随机生成手机号码:

通用组件 生成日期时间:

资源处理类关键字:

通用组件 循环删除30秒前的图片:

通用组件 执行次数计数:

截图:

通用组件 删除特定名称文件:

通用组件 删除包含关键字文件名文件:

通用组件 循环判断固定路径下是否存在文件:


框架概述:

框架工具 — Robot Framework
操作库 — SeleniumLibrary,AutoItLibrary(少量使用)
并发工具 — Selenium Grid
操作环境 — windows


基本框架思路:

使用Selenium对页面元素进行操作,进行功能,流程的校验。


封装思路:

每条用例单独封装一个关键字,方便重试机制的使用。
基于操作对象的PO进行封装,比如下拉框+下拉框项的组合,封装成一个KW。


扩展用法:

通过JS获取页面元素的样式,可以测试兼容性和样式。

通用关键字:

等待类关键字:

通用组件 等待 元素:

注意:如果操作对象会因滚屏而消失,比如下拉菜单展开后的操作,或者鼠标悬浮后的操作,请修改默认的“是否滚屏”参数为“否”!

关键字主要实现功能:

  1. 通过比对当前URL,来判断当前系统是否有Frame,如果有Frame,就使用自动切换Frame的KW进行切换。
  2. 获取元素对象的背景色,并在操作前通过js修改背景色为荧光绿,截图后恢复其原始背景色,方便观察操作对象。
  3. 根据是否滚屏的参数来控制是否需要滚屏操作,把操作对象元素尽量放置到屏幕的水平正中间。
  4. 等待页面包含元素,等待页面不包含请稍等,等待页面元素可见。
通用组件 等待 元素
    [Arguments]    ${页面元素定位}    ${最大等待时间}=${默认等待时间}    ${是否滚屏}=是
    [Documentation]    通过检测页面元素是否存在,页面元素是否可用,再根据元素的卷轴高度和浏览器高度,计算需要滚屏多少才能尽量把元素放到web页面正中间,并且滚屏
    ...
    ...    注意:如果页面元素会因为滚屏而消失(比如下拉框),请不要使用这个关键字
    Repeat Keyword    10x    Unselect Frame  #如果使用了iframe,这里可以直接退出10层iframe,如果没有使用iframe,不会有报错
    ${is-css}    Run Keyword And Return Status    Should Contain    ${页面元素定位}    css=  #由于css必须指定css=,所以用这个来判断当前元素定位方式是xpath还是css
    ${emp}    Replace String    ${页面元素定位}    css=    ${EMPTY}  #在js中,不需要css=,这里其实算是删除css=
    ${fin}    Replace String    ${emp}    "    '  #再把双引号全部替换为单引号,因为js需要统一单双引号
    ${style}    Set Variable If    ${is-css}    document.querySelector("${fin}").style.backgroundColor    document.evaluate("${fin}", document).iterateNext().style.backgroundColor  #根据是否是css选择使用适配css或者xpath的js,获取元素的样式
    ${当前页面url}    Get Location  #获取当前url
    FOR    ${需要使用Frame自动切换的服务器}    IN    @{需要使用iframe的服务器地址}  #根据当前url中是否包含有目标地址,来判断是否需要使用frame自动切换功能
        ${使用Frame自动切换}    Set Variable IF    "${需要使用Frame自动切换的服务器}" in "${当前页面url}"    True    False
        Exit For Loop If    ${使用Frame自动切换}
    END
    run keyword if    not ${使用Frame自动切换}    等待 直到页面包含元素    ${页面元素定位}    ${最大等待时间}  #不使用frame切换的路线
    run keyword if    ${使用Frame自动切换}    通用组件 自动切换frame    ${页面元素定位}    ${最大等待时间}  #使用frame切换的路线
    run keyword if    '${是否滚屏}'=='是'    Wait Until Keyword Succeeds    10x    1s    通用组件 获取 元素居中滚动像素    ${页面元素定位}  #这里有10次机会是有可能因为页面未加载完全造成获取不到像素的卷轴高度
    ${滚动值}    Set Variable If    '${是否滚屏}'=='是'    ${滚动值}    -1  #不需要滚动的情况下,也给滚动值赋值-1,统一处理
    run keyword if    ${滚动值} >= 0    通用组件 页面滚动    ${滚动值}  #只有大于0的滚动才有意义
    等待 直到页面元素可见    ${页面元素定位}    ${最大等待时间}
    ${org-bg}    Execute Javascript    return ${style}  #获取元素原始背景色
    等待 直到页面不包含请稍后    60s
    run keyword if    "style" not in "${fin}"    Execute Javascript    ${style}='#B9EF0B'  #更改操作的元素的背景色为荧光绿色
    截图
    run keyword if    "style" not in "${fin}"    Execute Javascript    ${style}='${org-bg}'  #更改操作的元素的背景色为原始背景色

通用组件 获取 元素居中滚动像素:

关键字主要实现功能:

  1. 根据web页面高度和元素的卷轴高度,来计算如果从web顶端把元素置于页面水平中央,需要滚动的像素值。
通用组件 获取 元素居中滚动像素
    [Arguments]    ${页面元素定位}
    通用组件 页面滚动    0    #滚动到web顶端
    ${宽度}    ${高度}    获取 web页面大小
    ${卷轴高度}    获取 元素距离web顶端的卷轴高度    ${页面元素定位}
    log    ${卷轴高度}
    ${滚动值}=    Evaluate    ${卷轴高度}-(${高度}/2)  #使用卷轴高度和半屏高度,刚好能把元素置于屏幕水平中央
    log    ${滚动值}
    Set Test Variable    ${滚动值}  #设置test级变量,方便取用

通用组件 页面滚动 :

关键字主要实现功能:

  1. 通过js进行页面滚动,部分页面可能不支持,需要修改滚动方法。
通用组件 页面滚动
    [Arguments]    ${页面滚动值}
    [Documentation]    正值向下滚动,负值向上滚动
    Execute Javascript    var q=document.documentElement.scrollTop=${页面滚动值}

通用组件 等待包含文字:

注意:如果操作对象会因滚屏而消失,比如下拉菜单展开后的操作,或者鼠标悬浮后的操作,请修改默认的“是否滚屏”参数为“否”!

关键字主要实现功能:

  1. 使用这种方式进行文字等待的原因是为了兼容有Frame的页面。
  2. 延迟截图时间存在的意义是为了一些有延迟的的弹窗,可以灵活设置。
通用组件 等待包含文字
    [Arguments]    ${文字}    ${延迟截图时间}=1s    ${最大等待时间}=${默认等待时间}    ${是否滚屏}=是
    sleep    ${延迟截图时间}
    通用组件 等待 元素    //*[contains(text(),'${文字}')]    ${最大等待时间}    ${是否滚屏}
    截图
    sleep    1

通用组件 自动切换frame :

关键字主要实现功能:

  1. 判断直接使用上次Frame的webelement,是否可以直接定位到元素。
  2. 如果步骤1失败,退出到根Frame,使用递归循环的方法尝试进入可用的Frame。
通用组件 自动切换frame
    [Arguments]    ${页面元素定位}    ${最大等待时间}=${默认等待时间}
    [Documentation]    通过循环使用正确的iframe
    等待 直到页面不包含请稍后    60s
    ${使用上一次Frame成功}    Run Keyword And Return Status    Wait Until Keyword Succeeds    1s    0.001s    通用组件 选择上次frame    ${页面元素定位}
    Run Keyword If    not ${使用上一次Frame成功}    Repeat Keyword    10x    Unselect Frame
    Run Keyword If    not ${使用上一次Frame成功}    Wait Until Keyword Succeeds    ${最大等待时间}    0.001s    通用组件 循环选择frame    ${页面元素定位}

通用组件 选择上次frame: 

关键字主要实现功能:

  1. 根据上次可用的Frame的Webelement,来直接切换到对应的Frame中,并检查是否能找到元素。
  2. 注意:这里的Frame对象由于是Webelement,不用一层一层进入Frame,可以一步到位。
通用组件 选择上次frame
    [Arguments]    ${页面元素定位}
    [Documentation]    使用上次的frame选择并查看是否能在frame中找到目标元素
    Repeat Keyword    10x    Unselect Frame
    等待 直到页面不包含请稍后    60s
    FOR    ${Frame}    IN    ${Frame List}
        ${元素在Frame外}    Run Keyword And Return Status    等待 直到页面包含元素    ${页面元素定位}    0.001s
        Exit For Loop If    ${元素在Frame外}
        Select Frame    ${Frame}
    END
    等待 直到页面包含元素    ${页面元素定位}    0.001s

通用组件 循环选择frame: 

关键字主要实现功能:

  1. 实现了通过递归来寻找包含元素的Frame的方法
通用组件 循环选择frame
    [Arguments]    ${页面元素定位}
    [Documentation]    通过循环获取frame数量并查看是否能在frame中找到目标元素
    等待 直到页面不包含请稍后    60s
    ${Frame List}    Create List
    Set Test Variable    ${Frame List}
    ${number list}    Create List
    ${noframe}    Create List    noframe
    ${所有的frame}    Get WebElements    //div[contains(@style,'display: block')]//iframe  #这里定位是为了过滤掉无用的Frame,要根据项目修改
    ${所有的frame}    Set Variable If    'selenium' in '${所有的frame}'    ${所有的frame}    ${noframe}  #这里是为了判断Webelement列表中是否存在Frame,适配没有Frame的情况,否则后面循环会报错
    ${frame长度}    Get Length    ${所有的frame}  #经过以上处理,这里最小长度也是1
    log    ${frame长度}
    FOR    ${i}    IN RANGE    0    ${frame长度}  #根据Frame中元素的长度,获取自然数有序列表
        Append To List    ${number list}    ${i}
    END
    ${Random number list}    Evaluate    random.sample(${number list}, len(${number list}))    modules=random  #把上面的自然数列表进行随机乱序,目标是在下面的Frame切入时是乱序的
    log    ${Random number list}
    FOR    ${i}    IN    @{Random number list}
        ${不使用frame}    Run Keyword And Return Status    等待 直到页面包含元素    ${页面元素定位}    0.001s
        Exit For Loop If    ${不使用frame}  #如果值是预设的,直接退出循环
        Select Frame    ${所有的frame}[${i}]  #根据乱序的自然数列表取值,进入Frame
        ${是这个frame}    Run Keyword And Return Status    等待 直到页面包含元素    ${页面元素定位}    0.001s
        Run Keyword If    ${是这个frame}    Append To List    ${Frame List}    ${所有的frame}[${i}]  #如果是目标Frame,就将其Webelement写入列表(其实这里只会写入正确的)
        log    ${Frame List}
        Exit For Loop If    ${是这个frame}  #如果已经找到目标的循环退出条件
        ${二层循环结果}    Run Keyword And Return Status    通用组件 循环选择frame    ${页面元素定位}  #递归入口,会到下层Frame继续循环
        Exit For Loop If    ${二层循环结果}  #如果已经找到目标的上层循环退出条件
        Unselect Frame
    END
    等待 直到页面包含元素    ${页面元素定位}    0.001s  #给整个关键字退出的条件

通用组件 尝试获取页面弹窗消息: 

关键字主要实现功能:

  1. 尝试获取页面弹窗消息,在失败的时候可以直接打印。
通用组件 尝试获取页面弹窗消息
    log    *********尝试获取页面弹窗消息*********
    ${当前页面url}    Get Location
    FOR    ${有Frame的服务器地址}    IN    @{需要使用iframe的服务器地址}
        ${有Frame}    Set Variable If    "${有Frame的服务器地址}" in "${当前页面url}"    True    False
        Exit For Loop If    ${有Frame}
    END
    FOR    ${i}    IN RANGE    1
        Run Keyword If    ${有Frame}    Repeat Keyword    10x    Unselect Frame
        Run Keyword If    ${有Frame}    Select Frame    //iframe[@id='MERCH1.002.006.001']|//iframe[@id='wEdit_iframe']
        ${无弹窗}    Run Keyword And Return Status    Page Should Not Contain Element    //div[contains(@class,'messager-body')]/div[2]
        ${无弹窗}    Run Keyword And Return Status    Page Should Not Contain Element    //*[@class="msgbox-info"]
        Exit For Loop If    ${无弹窗}
        ${弹窗消息}    获取 弹窗消息
        Run Keyword If    '${弹窗消息}'!='' and '${弹窗消息}'!='None'    Set Tags    页面弹窗:${弹窗消息}
    END

操作类关键字: 

通用组件 等待并输入文本:

注意:如果操作对象会因滚屏而消失,比如下拉菜单展开后的操作,或者鼠标悬浮后的操作,请修改默认的“是否滚屏”参数为“否”!

关键字主要实现功能:

  1. 通用等待功能,可以控制是否滚屏。
  2. 输入文本前,对输入框内容进行清除,提供两种方式,一种是Selenium自带的,一种是使用“全选”+“剪切”的方式。
  3. 带校验功能的输入文本。
通用组件 等待并输入文本
    [Arguments]    ${页面元素定位}    ${文本}    ${最大等待时间}=${默认等待时间}    ${Selenium自带清除文本}=是    ${是否滚屏}=是
    通用组件 等待 元素    ${页面元素定位}    ${最大等待时间}    ${是否滚屏}
    Run Keyword If    '${Selenium自带清除文本}' == '否'    Click Element    ${页面元素定位}
    Run Keyword If    '${Selenium自带清除文本}' == '否'    Press Keys    None    CTRL+a
    Run Keyword If    '${Selenium自带清除文本}' == '否'    Press Keys    None    CTRL+x
    输入 文本    ${页面元素定位}    ${文本}    ${Selenium自带清除文本}
输入 文本
    [Arguments]    ${页面元素定位}    ${文本}    ${是否需要清除文本}=是    ${循环次数}=5
    log    ${是否需要清除文本}
    FOR    ${i}    IN RANGE    0    ${循环次数}
        sleep    ${i}
        Run Keyword If    '${是否需要清除文本}' == '是'    Clear Element Text    ${页面元素定位}
        input text    ${页面元素定位}    ${文本}
        ${实际填入的值}    Get Value    ${页面元素定位}
        截图
        Exit For Loop If    '${实际填入的值}'=='${文本}'
    END

通用组件 等待并获取文本:

注意:如果操作对象会因滚屏而消失,比如下拉菜单展开后的操作,或者鼠标悬浮后的操作,请修改默认的“是否滚屏”参数为“否”!

关键字主要实现功能:

  1. 通用等待功能,可以控制是否滚屏。
  2. 获取元素文本可兼容对象是text和value两种情况。
通用组件 等待并获取文本
    [Arguments]    ${页面元素定位}    ${最大等待时间}=${默认等待时间}    ${是否滚屏}=是
    通用组件 等待 元素    ${页面元素定位}    ${最大等待时间}    ${是否滚屏}
    ${文本}    获取 元素文本    ${页面元素定位}
    [Return]    ${文本}
获取 元素文本
    [Arguments]    ${页面元素定位}
    ${文本}    Get Text    ${页面元素定位}
    ${取值}    Get Value    ${页面元素定位}
    ${文本}    Set Variable If    '${文本}'==''    ${取值}    ${文本}
    [Return]    ${文本}

通用组件 等待并点击元素: 

注意:如果操作对象会因滚屏而消失,比如下拉菜单展开后的操作,或者鼠标悬浮后的操作,请修改默认的“是否滚屏”参数为“否”!

关键字主要实现功能:

  1. 通用等待功能,可以控制是否滚屏。
  2. 点击操作会判断对象是否聚焦或者消失,没有的话会重试
通用组件 等待并点击元素
    [Arguments]    ${页面元素定位}    ${最大等待时间}=${默认等待时间}    ${是否滚屏}=是
    [Documentation]    点击操作
    通用组件 等待 元素    ${页面元素定位}    ${最大等待时间}    ${是否滚屏}
    点击 元素    ${页面元素定位}
点击 元素
    [Arguments]    ${页面元素定位}
    FOR    ${i}    IN RANGE    0    5
        click element    ${页面元素定位}
        ${是否已经点中}    Run Keyword And Return Status    Element Should Be Focused    ${页面元素定位}
        Exit For Loop If    '${是否已经点中}'=='True'
        ${是否已经消失}    Run Keyword And Return Status    Wait Until Element Is Not Visible    20s
        Exit For Loop If    '${是否已经消失}'=='True'
    END

通用组件 等待并双击元素: 

注意:如果操作对象会因滚屏而消失,比如下拉菜单展开后的操作,或者鼠标悬浮后的操作,请修改默认的“是否滚屏”参数为“否”!

关键字主要实现功能:

  1. 通用等待功能,可以控制是否滚屏。
  2. 双击操作会判断对象是否聚焦或者消失,没有的话会重试。
通用组件 等待并双击元素
    [Arguments]    ${页面元素定位}    ${最大等待时间}=${默认等待时间}    ${是否滚屏}=是
    [Documentation]    点击操作
    通用组件 等待 元素    ${页面元素定位}    ${最大等待时间}    ${是否滚屏}
    双击 元素    ${页面元素定位}
双击 元素
    [Arguments]    ${页面元素定位}
    FOR    ${i}    IN RANGE    0    5
        Double Click Element    ${页面元素定位}
        ${是否已经点中}    Run Keyword And Return Status    Element Should Be Focused    ${页面元素定位}
        Exit For Loop If    '${是否已经点中}'=='True'
        ${是否已经消失}    Run Keyword And Return Status    Wait Until Element Is Not Visible    20s
        Exit For Loop If    '${是否已经消失}'=='True'
    END

通用组件 等待并鼠标点击元素:

注意:如果操作对象会因滚屏而消失,比如下拉菜单展开后的操作,或者鼠标悬浮后的操作,请修改默认的“是否滚屏”参数为“否”!

关键字主要实现功能:

  1. 通用等待功能,可以控制是否滚屏。
  2. 鼠标点击和单击的区别在于:单击=鼠标悬浮+鼠标左键按下+鼠标左键松开;鼠标点击=鼠标左键按下+鼠标左键松开
  3. 如果鼠标悬浮会影响dom结构变化而导致元素定位变化,请使用本KW
通用组件 等待并鼠标点击元素
    [Arguments]    ${页面元素定位}    ${最大等待时间}=${默认等待时间}    ${是否滚屏}=是
    通用组件 等待 元素    ${页面元素定位}    ${最大等待时间}    ${是否滚屏}
    鼠标 左键按下    ${页面元素定位}
    鼠标 左键松开    ${页面元素定位}

通用组件 AutoIt上传 chrome版:

关键字主要实现功能:

  1. 用于非标准HTML的上传(未使用input的type为file),在chrome下可以通用。
  2. 在这里才引用AutoItLibrary是因为AutoItLibrary和Selenium有不少重复的关键字。
通用组件 AutoIt上传 chrome版
    [Arguments]    ${上传文件路径}
    Import Library    AutoItLibrary  #在这里才导入是因为AutoITLibrary和SeleniumLibrary有很多关键字重复
    sleep    2s
    Control Set Text    打开    \    Edit1    ${上传文件路径}
    Control Click    \    \    Button1
    sleep    2s

通用组件 关闭所有浏览器: 

关键字主要实现功能:

  1. 关闭所有在本条用例中已经打开的浏览器,释放资源。
  2. 获取失败时的弹窗消息,方便分析。
  3. 获取cookie,url,方便分析。
  4. 如果失败的话,删除失败前打的“重试x次通过”的tag。
  5. 如果一次性通过,就删除所有截图,释放资源。
  6. 触发上传调试结果到CTP(一个用例管理平台)。
  7. 触发上传脚本维护记录到CTP(一个用例管理平台)。
  8. 如果不是一次通过,删除30秒前的截图。
  9. 触发新增CTP(一个用例管理平台)脚本并关联用例。
通用组件 关闭所有浏览器
    ${is passed}    Run Keyword And Return Status    Run Keyword If Test Failed    这里使用不存在的关键字,如果因为失败而调用这个关键字,会赋值False
    Run Keyword And Ignore Error    Run Keyword If Test Failed    通用组件 尝试获取页面弹窗消息
    Run Keyword And Ignore Error    截图
    Run Keyword And Ignore Error    获取 cookie
    Run Keyword And Ignore Error    获取 url
    Run Keyword And Ignore Error    关闭 所有浏览器
    Comment    ${is pabot}    Run Keyword And Return Status    Should Exist    pabot_results
    Run Keyword And Ignore Error    Run Keyword If Test Failed    Remove Tags    重试通过    重试1次通过    重试2次通过
    Run Keyword And Ignore Error    Run Keyword If    ${已执行次数}==1 and '${is passed}'=='True'    remove files    pabot_results\\*\\*${TEST_NAME}*.png    *${TEST_NAME}*.png
    Run Keyword And Ignore Error    Run Keyword If Test Failed    通用组件 上传本条调试结果到CTP
    Run Keyword And Ignore Error    Run Keyword If Test Passed    通用组件 上传本条调试结果到CTP
    Run Keyword And Ignore Error    Run Keyword If Test Failed    通用组件 上传脚本维护记录到CTP
    Run Keyword And Ignore Error    Run Keyword If Test Passed    通用组件 上传脚本维护记录到CTP
    Run Keyword And Ignore Error    通用组件 循环删除30秒前的图片
    Run Keyword If    ${是否新增脚本}    通用组件 新增CTP脚本并关联用例    # ${是否新增脚本}全局变量 0 不上传,1 上传

切换 窗口:

关键字主要实现功能:

  1. 入参如果是main,会返回主窗口,并且关闭当前窗口。
  2. 入参如果是非main,会切换到非main窗口。
切换 窗口
    [Arguments]    ${窗口}=main
    sleep    3s
    run keyword if    '${窗口}'=='main'    Close Window
    Switch Window    ${窗口}

数据处理类关键字:

通用组件 获取excel内容:

注意:本关键字只支持xls等老版本的excel文件,需要支持新版的xlsx,请使用其它关键字。

关键字主要实现功能:

  1. 获取某xls指定sheet页下的内容,会忽略连续空值的单元格。
  2. 路径也可以使用/
  3. 获取的数据是按照列排序,如果需要按照行,需要使用其它方法循环读取。
通用组件 获取excel内容
    [Arguments]    ${excel路径}    ${sheet名称}
    [Documentation]    获取excel非空内容,可以通过二维下标获取值
    Open Excel    ${excel路径}    #C:\\Users\\86181\\Downloads\\自动化创建的模板-mvvh.xls
    ${excel内容-通用组件专用}    Get Sheet Values    ${sheet名称}    False
    log    ${excel内容-通用组件专用}
    Set Test Variable    ${excel内容-通用组件专用}
    [Return]    ${excel内容-通用组件专用}

通用组件 账号脱敏展示处理:

关键字主要实现功能:

  1. 获取账号的脱敏展示格式。
通用组件 账号脱敏展示处理
    [Arguments]    ${账号}
    [Documentation] 
    ...    关键字功能:把账号进行脱敏处理
    ...    输入参数:${账号}
    ...    输出参数:${账号脱敏展示}
    ...    例如:输入:2704010101201010192805
    ...    \ \ \ \ 输出:2704 **** ***** 2805
    ${头4个字符}    Get Substring    ${账号}    0    4
    ${尾4个字符}    Get Substring    ${账号}    -4
    [Return]    ${头4个字符} **** **** ${尾4个字符}

通用组件 生成统一社会信用代码:

关键字主要实现功能:

  1. 获取随机的统一社会信用代码。
通用组件 生成统一社会信用代码
    ${Organization Code}    Create Organization Code
    ${Social Credit Check Code}    Get Social Credit Check Code    91110108${Organization Code}
    log    91110108${Organization Code}${Social Credit Check Code}
    [Return]    91110108${Organization Code}${Social Credit Check Code}

调用的python代码(CreateSocialCreditCode.py):

# -*- coding: utf-8 -*-
import random

SOCIAL_CREDIT_CHECK_CODE_DICT = {
    '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9,
    'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15, 'G': 16, 'H': 17, 'J': 18, 'K': 19, 'L': 20, 'M': 21, 'N': 22,
    'P': 23, 'Q': 24,
    'R': 25, 'T': 26, 'U': 27, 'W': 28, 'X': 29, 'Y': 30}
weighting_factor = [1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28]

# 本体代码
def get_social_credit_check_code(code):
    # check_code = code[17]
    # 计算校验码公式:
    #     C9 = 31-mod(sum(Ci*Wi),31),其中Ci为组织机构代码的第i位字符,Wi为第i位置的加权因子,C9为校验码
    # 第i位置上的加权因子
    ontology_code = code[0:17]
    # 计算校验码
    tmp_check_code = gen_check_code(weighting_factor, ontology_code, 31, SOCIAL_CREDIT_CHECK_CODE_DICT)
    print('code is:' + tmp_check_code)
    return tmp_check_code


def gen_check_code(weighting_factor, ontology_code, modulus, check_code_dict):
    #     @param weighting_factor: 加权因子
    #     @param ontology_code:本体代码
    #     @param modulus:  模数
    #     @param check_code_dict: 字符字典
    total = 0
    for i in range(len(ontology_code)):
        if ontology_code[i].isdigit():
            total += int(ontology_code[i]) * weighting_factor[i]
        else:
            total += check_code_dict[ontology_code[i]] * weighting_factor[i]
    # 当MOD函数值为0时,校验码用0表示
    if modulus - total % modulus == 31:
        return list(check_code_dict.keys())[list(check_code_dict.values()).index(0)]
    else:
        diff = modulus - total % modulus
        print(diff)
        return list(check_code_dict.keys())[list(check_code_dict.values()).index(diff)]


def create_Organization_code():
    ww = [3, 7, 9, 10, 5, 8, 4, 2]  # suan fa yin zi
    cc = []
    dd = 0

    for i in range(8):  # gei CC fu zhi
        cc.append(random.randint(1, 9))
        dd = dd + cc[i] * ww[i]
    for i in range(len(cc)):
        cc[i] = str(cc[i])
    C9 = 11 - dd % 11
    if C9 == 10:
        C9 = 'X'
    else:
        if C9 == 11:
            C9 = '0'
        else:
            C9 = str(C9)
    cc.append('' + C9)
    return "".join(cc)

通用组件 随机获取身份证号码:

关键字主要实现功能:

  1. 获取随机的身份证号码。
通用组件 随机获取身份证号码
    Import Library    FakerLibrary    zh-CN
    ${身份证号码}    ssn
    log    ${身份证号码}
    [Return]    ${身份证号码}

通用组件 随机生成手机号码:

关键字主要实现功能:

  1. 获取随机的手机号码。
通用组件 随机生成手机号码
    Import Library    FakerLibrary    zh-CN
    ${手机号码}    Phone Number
    log    ${手机号码}
    [Return]    ${手机号码}

通用组件 生成日期时间:

关键字主要实现功能:

  1. 根据中文拼音的“年年年年月月日日时时分分秒秒”来自定义获取日期时间格式。
  2. 根据需要加减的日期来获取当前时间前后的时间。
通用组件 生成日期时间
    [Arguments]    ${日期预期格式}    ${需要加减的日期}=0    # 加减的日期支持正负的天(d)小时(h)分钟(m)秒(s)
    [Documentation]    年年年年月月日日时时分分秒秒
    ...    NNNNYYRRSSFFMM
    ${日期预期格式}    Replace String    ${日期预期格式}    YY    %m  #这里更换替换顺序是防止出现“YYY”的情况
    ${日期预期格式}    Replace String    ${日期预期格式}    NNNN    %Y
    ${日期预期格式}    Replace String    ${日期预期格式}    NN    %y
    ${日期预期格式}    Replace String    ${日期预期格式}    RR    %d
    ${日期预期格式}    Replace String    ${日期预期格式}    SS    %H  #这里更换替换顺序是防止出现“MMM”的情况
    ${日期预期格式}    Replace String    ${日期预期格式}    MM    %S
    ${日期预期格式}    Replace String    ${日期预期格式}    FF    %M
    ${当前日期时间}    Get Current Date
    ${计算后的日期时间}    Add Time To Date    ${当前日期时间}    ${需要加减的日期}    result_format=${日期预期格式}
    log    ${计算后的日期时间}
    [Return]    ${计算后的日期时间}

资源处理类关键字:

通用组件 循环删除30秒前的图片:

关键字主要实现功能:

  1. 循环删除(本重试轮次)中30秒以前的图片,减少Jenkins上无效图片数量,增加Jenkins任务log生成速度。
  2. 需要配合其它关键字一起使用(执行次数计数,截图)。
通用组件 循环删除30秒前的图片
    [Arguments]    ${需要保留图片的秒数}=30
    ${delete sec}    Evaluate    ${sectime}-${需要保留图片的秒数}  #计时从打开浏览器开始
    FOR    ${要删除的秒数}    IN RANGE    0    ${delete sec}
        remove files    pabot_results\\*\\${要删除的秒数}_*_${TEST_NAME}_Round${已执行次数}.png    ${要删除的秒数}_*_${TEST_NAME}_Round${已执行次数}.png  #这里兼容了robot和pabot两种情况
    END

通用组件 执行次数计数:

关键字主要实现功能:

  1. 在每轮执行前关闭所有浏览器(删除上一轮30秒以前的图片)。
  2. 执行次数计数,并根据执行次数打tag,方便统计有多少用例重试。
  3. 获取当前时间,从此时开始计数,计算绝对时间(30秒删除图片的时间起点)
通用组件 执行次数计数
    [Documentation]    编写人:张迪 2021-05-28
    Run Keyword And Ignore Error    通用组件 关闭所有浏览器
    ${已执行次数}    Evaluate    ${已执行次数}+1
    Set Test Variable    ${已执行次数}
    Run Keyword If    ${已执行次数}==2    Set Tags    重试通过    重试1次通过
    Run Keyword If    ${已执行次数}==2    通用组件 获取本条用例现在产生的图片数量
    Run Keyword If    ${已执行次数}==2    Set Suite Variable    ${第一次执行完成时的截图数量}    ${图片数量}
    Run Keyword If    ${已执行次数}==3    run keywords    Set Tags    重试2次通过
    ...    AND    Remove Tags    重试1次通过
    Run Keyword If    ${已执行次数}==4    run keywords    Set Tags    重试3次通过
    ...    AND    Remove Tags    重试2次通过
    log    该案例已执行:${已执行次数}次
    ${now-time}    Get Current Date
    Set Test Variable    ${now-time}

截图:

关键字主要实现功能:

  1. 通过相对时间+测试用例名称+轮次来标记图片,方便后面根据策略删除不需要的图片。
截图
    ${now}    Get Current Date
    ${sectime}    Subtract date From date    ${now}    ${now-time}  #计算本轮开始到现在的相对时间
    ${sectime}    Evaluate    int(${sectime})
    log    ${sectime}
    Set Test Variable    ${sectime}  #这里设置test级别变量,是因为最后处理图片资源需要这个时间
    Capture Page Screenshot    ${sectime}_{index}_${TEST_NAME}_Round${已执行次数}.png  #{index}是为了防止同一秒截取多张图片

通用组件 删除特定名称文件:

关键字主要实现功能:

  1. 获取测试套根目录绝对地址。
  2. 组合测试套根目录地址和目标文件相对地址。
  3. 删除指定的文件。
通用组件 删除特定名称文件
    [Arguments]    ${文件名称}
    ${当前项目绝对路径}    通用组件 获取当前测试套根目录
    ${文件绝对路径}    通用组件 生成上传文件的绝对路径    ${文件名称}
    Run Keyword And Ignore Error    Remove Files    ${文件绝对路径}
 
通用组件 获取当前测试套根目录
    Comment    ${测试套根目录}    Set Variable    ${CURDIR}
    ${测试套根目录}    Set Variable    ${项目根目录}
    [Return]    ${测试套根目录}
 
通用组件 生成上传文件的绝对路径
    [Arguments]    ${文件名称}    # 在项目路径后面拼接的文件名称
    [Documentation]    eg: \\上传文件\\test.xls
    ${当前项目绝对路径}    通用组件 获取当前测试套根目录
    ${上传文件的绝对路径}    Set Variable    ${当前项目绝对路径}\\上传文件\\${文件名称}
    log    ${上传文件的绝对路径}
    [Return]    ${上传文件的绝对路径}

通用组件 删除包含关键字文件名文件:

关键字主要实现功能:

  1. 删除包含关键字文件名文件。
通用组件 删除包含关键字文件名文件
    [Arguments]    ${关键字文件名}    ${文件夹路径}
    ${所有文件}    List Files In Directory    ${文件夹路径}
    FOR    ${文件}    IN    @{所有文件}
        log    ${文件}
        ${是否包含}    Run Keyword And Return Status    Should Contain    ${文件}    ${关键字文件名}
        Run Keyword If    ${是否包含}    Remove File    ${文件夹路径}\\${文件}
    END

通用组件 循环判断固定路径下是否存在文件:

关键字主要实现功能:

  1. 循环判断固定路径下是否存在文件。
通用组件 循环判断固定路径下是否存在文件
    [Arguments]    ${关键字文件名}    ${文件夹路径}
    ${所有文件}    List Files In Directory    ${文件夹路径}
    FOR    ${文件}    IN    @{所有文件}
        log    ${文件}
        ${是否存在}    Run Keyword And Return Status    Should Contain    ${文件}    ${关键字文件名}
        Exit For Loop If    ${是否存在}
    END
    [Return]    ${是否存在}    ${文件}


版权声明:本文为qq_27534003原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。