美文网首页
Robot Framework 小练习目录结构

Robot Framework 小练习目录结构

作者: 自如_ | 来源:发表于2019-07-21 15:14 被阅读0次

新增一个用例2
初始化清除工作,包括关键字的实现 在RF资源文件中实现

我们要求和以前的用例放在不同的测试套件目录中:

一个是‘课程管理’目录,一个是‘老师管理’目录

用例1:添加课程功能

前置条件:系统中没有课程,

步骤 1: 添加课程,输入课程名、详情描述、展示次序为2,点击创建
预期结果:创建的课程正确显示在下面的表中。

step 2: 再添加一门课程,输入课程名、详情描述、展示次序为1,点击创建
预期结果:创建的课程正确显示在下面的表中,并且按照展示次序排列。

用例2:添加老师功能

前置条件:系统中没有老师,已经有课程 ‘初中语文’,‘初中数学’

step 1: 添加老师,输入老师姓名、登录名、描述、展示次序为2,选择课程 ‘初中语文’
预期结果:创建的老师正确显示在下面的表中。

step 2: 再添加一个老师,展示次序为1,选择课程 ‘初中数学’
预期结果:创建的老师正确显示在下面的表中,并且按照展示次序排列。

第一个用例我们已经做过了,现在我们看第二个用例。上面的章节中我们已经实现了前面的用例,我们看下它的代码结构

image.png

我们看下 task 的目录结构,我们通常是把用户关键字所存放的资源文件,放在一个单独的文件里。 python 的库关键字放在 python 的代码文件里面,我们写测试用例放在测试用例的代码文件里面。最开始时候最简单的项目就可以从这种方式开始,可能在项目的开发过程中有一些常见的配置数据,我们通常可以放在一些变量文件里。所谓变量文件就是 python 写的配置文件。

现在我们要做的是,在原来用例的基础上再增加用例2的自动化。我们先看它需要哪些数据环境。

  • 第一个系统中没有老师,要把系统中所有老师删掉

  • 删除系统中所有的课程

  • 添加课程 ‘初中语文’,‘初中数学’

那我们的初始化操作就有三个动作。我们 先把三个初始化的关键字去实现。这三个初始化的操作,删除所有课程和添加课程的关键字已经有了,我们只要把删除老师的关键字时间就可以了。

DeleteAllTeacher
    Login Web Site
    
    Click Element  css=a[href="#/teacher"]  
    sleep  1
    
    Set Selenium Implicit Wait    2

    :For   ${one}    IN RANGE   9999
     \    ${eles}=   Get WebElements   css=button[ng-click^='delOne']
     \    exit for loop if    $eles==[]
     \    Click Element     @{eles}[0]
     \    Click Element     css=button.btn-primary
     \    Sleep   1

    Set Selenium Implicit Wait    10

现在初始化的关键字都有了,现在我们就来实现用例。题目中要求我们和以前的用例放在不同的测试套件目录中,一个是‘课程管理’目录,一个是‘老师管理’目录。面临一个问题,我怎么安排目录的组织结构。

自动化项目的目录结构

已经接触到项目文件的种类:测试套件文件、目录RF资源文件测试库变量文件

这么多种类型的文件我们应该以什么样的目录结构来存放呢?现在我们全是堆在一个文件夹里,大家看一下这个task

image.png

现在我们文件还不多,但是在实际的项目中测试用例会有很多,说不定测试库也有很多,资源文件说不定也有很多,我们怎么安排它们比较好呢?每个人都有不同的方法,经过一些项目实战总结出来,用这种方式是比较好的,就是把它们分分类,比如:

image.png

比如说 task 是项目根目录,我们把 pylib 测试库,robot 的资源文件 rflib,测试用例 tc 把它分成三个目录存放,这样就不会搞乱,这是一种方式,不是说非要这样,根据项目经验这个安排是比较合理清晰的。还有配置文件 cfg.py 如果说整个项目小,配置文件就一个的话直接放一下就可以,如果说你的配置文件比较多,项目很大,不止一个配置文件你也可以创建一个目录叫 cfg。把它放进去。

image.png

现在我们的目录结构就变成这样了。现在目录结构有了就来实现添加老师的用例。我们之前都是放在一个项目根目录下面的,之前我们的用例里面像一些库和资源文件直接导入就可以,因为他们都在同一个目录下,导入的时候直接写就没关系,现在他们不在项目根目录上面了,所以我们应该路径都是相对于项目根目录的。

image.png

这个问题解决了我们接下来看初始化的操作,之前我们初始化清除比较简单,因为就是一个动作,现成的关键字删除所有的课程就行了,但是目前这个用例它有三个动作,我们分别在三个关键字里面实现的,前面讲了初始化的操作里面只能用一个关键字,现在有三个关键字要写,我们可以用 Robot 提供的一个关键字叫 Run keywords 方法实现初始化,它是 Builtion 库里面的关键字。

http://robotframework.org/robotframework/latest/libraries/BuiltIn.html#Run%20Keywords

image.png

Run keywords 本身就是一个关键字。可以把多个关键字当成参数写在里面。

image.png

顺序执行三个关键字,当成参数写在里面。如果这个关键字本身也有参数的话,中间用 AND 连接起来。要大写。

image.png

下面来进行我们的初始化操作

*** Settings ***
Library    SeleniumLibrary
Resource    rflib/rc.robot

Suite Setup     Setup WebTest
Suite Teardown  Teardown WebTest

*** Test Cases ***
测试1
    [Setup]  run keywords  DeleteAllTeacher
    ...  AND  DeleteAllCourse
    ...  AND  Add Course  初中语文  初中语文描述  1
    ...  AND  Add Course  初中数学  初中数学描述  2

这样我们的初始化操作就有了,接下来就是用例的主体部分。下一个动作是添加老师。发现添加老师的关键字还没有。加下来我们来实现。

addTeacher
    #${realname}真实姓名 ${username}登录名  ${desc}描述  ${idx}展示次序 ${courser}授课信息
    [Arguments]  ${realname}  ${username}  ${desc}  ${idx}  ${courser}

    Click Element  css=a[href="#/teacher"]
    sleep  1

    Click Element   css=button[ng-click^="showAddOne"]

    input text      css=input[ng-model="addEditData.realname"]    ${realname}
    input text      css=input[ng-model="addEditData.username"]    ${username}
    input text      css=textarea[ng-model="addEditData.desc"]   ${desc}
    input text      css=input[ng-model="addEditData.display_idx"]   ${idx}

    Select From List By Label  css=select[ng-model="$parent.courseSelected"]  ${courser}
    Click Element   css=button[ng-click="addEditData.addTeachCourse()"]

    Click Element   css=button[ng-click="addOne()"]
    sleep  2

这里主要注意一点授课信息,它是 select

image.png

如果我们直接写 python 代码的话可以直接找 select 类。我们现在使用的是 RobotSeleniumLibrary ,别人已经开发封装好专门给 Robot 用的,它里面有没有对应的关键字呢,我们去 selenium 的库里去找一下。

https://robotframework.org/SeleniumLibrary/SeleniumLibrary.html

image.png

根据 Select From List By Label 是最直接的,它是根据显示出来选项的名字。它的第一个参数 locator 就是要告诉它是哪个 Select ,可以根据 css 表达式找到它。

添加完老师我们还要做判断,老师的列表里有没有我们添加的老师。

Get teacher List

    Click Element  css=a[href="#/teacher"]
    sleep  1

    ${teachers}=   Create List
    ${eles}=   get webelements  css=tr>td:nth-child(2)
    :FOR   ${ele}   IN   @{eles}
    \      Append To List   ${teachers}    ${ele.text}

    [Return]   ${teachers}

这样我们就把用例所需要的关键字都实现了。接下来实现用例:

*** Settings ***
Library  SeleniumLibrary
Resource  rflib/rc.robot

Suite Setup  SetupWebTest
Suite Teardown  TeardownWebTest

*** Test Cases ***
测试1
    [Setup]   run keywords   DeleteAllTeacher
    ...  AND  deleteAllCourse
    ...  AND  addcourse  初中语文  初中语文描述  1
    ...  AND  addcourse  初中数学  初中数学描述  2



    addTeacher  庄子  zhuangzi  庄子老师  2  初中语文
    addTeacher  孔子  kongzi  孔子老师  1  初中数学

    ${teachers}=  getTeacherList
    should be true  $teachers==['孔子','庄子']
    [Teardown]     run keywords  deleteallteacher
    ...  AND  deleteAllCourse

下面是全部的代码实现:
rc.robot 代码

*** Settings ***
Library  SeleniumLibrary
Library  Collections
Variables  ../cfg.py

#*** Variables ***
#${MgrLoginUrl}    http://localhost/mgr/login/login.html
#&{adminuser}    name=auto  password=sdfsdfsdf


*** Keywords ***
SetupWebTest
    open browser  http://localhost  chrome
    set selenium implicit wait  10
TeardownWebTest
    close browser
loginwebsite
    GO TO    ${MgrLoginUrl}
    INPUT TEXT    id=username    &{adminuser}[name]
    INPUT TEXT    id=password    &{adminuser}[password]
    click element    tag=button

DeleteAllTeacher
    loginwebsite
    Click Element  css=a[href="#/teacher"]
    sleep  1

    Set Selenium Implicit Wait    2
    :For   ${one}    IN RANGE   9999
     \    ${eles}=   Get WebElements   css=button[ng-click^='delOne']
     \    exit for loop if    $eles==[]
     \    Click Element     @{eles}[0]
     \    Click Element     css=button.btn-primary
     \    Sleep   1

    Set Selenium Implicit Wait    10
deleteAllCourse
    loginwebsite
    set selenium implicit wait  1
    :FOR  ${one}  IN   RANG  99999
    \  ${eles}=  get webelements  css=tr>td>button:nth-child(2)
    \  exit for loop if   $eles == []
    \  click element  @{eles}[0]
    \  click element  css=.modal-footer .btn-primary
    \  sleep  1
    set selenium implicit wait  10


addcourse
    [Arguments]  ${name}  ${desc}  ${idx}
    click element    css=*[ng-click="showAddOne=true"]
    input text    css=*[ng-model="addData.name"]    ${name}
    input text    css=*[ng-model="addData.desc"]    ${desc}
    input text    css=*[ng-model="addData.display_idx"]    ${idx}
    click element    css=*[ng-click="addOne()"]
    sleep    1
addTeacher
    #${realname}真实姓名 ${username}登录名  ${desc}描述  ${idx}展示次序 ${courser}授课信息
    [Arguments]  ${realname}  ${username}  ${desc}  ${idx}  ${courser}

    Click Element  css=a[href="#/teacher"]
    sleep  1

    Click Element   css=button[ng-click^="showAddOne"]

    input text      css=input[ng-model="addEditData.realname"]    ${realname}
    input text      css=input[ng-model="addEditData.username"]    ${username}
    input text      css=textarea[ng-model="addEditData.desc"]   ${desc}
    input text      css=input[ng-model="addEditData.display_idx"]   ${idx}

    Select From List By Label  css=select[ng-model="$parent.courseSelected"]  ${courser}
    Click Element   css=button[ng-click="addEditData.addTeachCourse()"]

    Click Element   css=button[ng-click="addOne()"]
    sleep  2
getTeacherList
    Click Element  css=a[href="#/teacher"]
    sleep  1

    ${teachers}=   Create List
    ${eles}=   get webelements  css=tr>td:nth-child(2)
    :FOR  ${ele}  IN   @{eles}
    \  Append To List  ${teachers}  ${ele.text}
    [Return]   ${teachers}

getcourserlist
    ${lessons}=  create list
    ${eles}    get webelements      css=tr>td:nth-child(2)
    :FOR  ${ele}  IN  @{eles}
    \   log to console    课程名为:${ele.text}
    \   append to list    ${lessons}    ${ele.text}

    [Return]    ${lessons}



添加老师.robot

*** Settings ***
Library  SeleniumLibrary
Resource  rflib/rc.robot

Suite Setup  SetupWebTest
Suite Teardown  TeardownWebTest

*** Test Cases ***
测试1
    [Setup]   run keywords   DeleteAllTeacher
    ...  AND  deleteAllCourse
    ...  AND  addcourse  初中语文  初中语文描述  1
    ...  AND  addcourse  初中数学  初中数学描述  2



    addTeacher  庄子  zhuangzi  庄子老师  2  初中语文
    addTeacher  孔子  kongzi  孔子老师  1  初中数学

    ${teachers}=  getTeacherList
    should be true  $teachers==['孔子','庄子']
    [Teardown]     run keywords  deleteallteacher
    ...  AND  deleteAllCourse

添加课程.robot

*** Settings ***
Library    SeleniumLibrary
Resource    rflib/rc.robot

Suite Setup     Setup WebTest
Suite Teardown  Teardown WebTest

*** Test Cases ***
*** Settings ***
Library  SeleniumLibrary
Resource  rflib/rc.robot

Suite Setup  SetupWebTest
Suite Teardown  TeardownWebTest

*** Test Cases ***
测试1
    [Setup]     deleteAllCourse
    loginwebsite
    addcourse  初中化学  初中化学描述  1

    ${lessons}=  getcourserlist
    should be true    $lessons==["初中化学"]
    [Teardown]    deleteAllCourse
测试2
    [Setup]     deleteAllCourse
    loginwebsite

    addcourse  化  化描述  2

    ${lessons}=    getcourserlist
    should be true  $lessons==["化"]

    [Teardown]  deleteAllCourse

运行截图:


E:\tmp\rf\task>robot --pythonpath . tc
==============================================================================
Tc
==============================================================================
Tc.老师管理
==============================================================================
Tc.老师管理.添加老师
==============================================================================

DevTools listening on ws://127.0.0.1:60367/devtools/browser/090f8e03-face-460d-bf51-ebbec195dbcf
测试1                                                                 | PASS |
------------------------------------------------------------------------------
Tc.老师管理.添加老师                                                  | PASS |
1 critical test, 1 passed, 0 failed
1 test total, 1 passed, 0 failed
==============================================================================
Tc.老师管理                                                           | PASS |
1 critical test, 1 passed, 0 failed
1 test total, 1 passed, 0 failed
==============================================================================
Tc.课程管理
==============================================================================
Tc.课程管理.添加课程
==============================================================================

DevTools listening on ws://127.0.0.1:60415/devtools/browser/eeba6a33-7a50-42c2-861d-1a31fc68a2cd
测试1                                                                 | PASS |
------------------------------------------------------------------------------
测试2                                                                 | PASS |
------------------------------------------------------------------------------
Tc.课程管理.添加课程                                                  | PASS |
2 critical tests, 2 passed, 0 failed
2 tests total, 2 passed, 0 failed
==============================================================================
Tc.课程管理                                                           | PASS |
2 critical tests, 2 passed, 0 failed
2 tests total, 2 passed, 0 failed
==============================================================================
Tc                                                                    | PASS |
3 critical tests, 3 passed, 0 failed
3 tests total, 3 passed, 0 failed
==============================================================================
Output:  E:\tmp\rf\task\output.xml
Log:     E:\tmp\rf\task\log.html
Report:  E:\tmp\rf\task\report.html

E:\tmp\rf\task>

相关文章

网友评论

      本文标题:Robot Framework 小练习目录结构

      本文链接:https://www.haomeiwen.com/subject/lmumlctx.html