新增一个用例2
初始化清除工作,包括关键字的实现 在RF资源文件中实现
我们要求和以前的用例放在不同的测试套件目录中:
一个是‘课程管理’目录,一个是‘老师管理’目录
用例1:添加课程功能
前置条件:系统中没有课程,
步骤 1: 添加课程,输入课程名、详情描述、展示次序为2,点击创建
预期结果:创建的课程正确显示在下面的表中。
step 2: 再添加一门课程,输入课程名、详情描述、展示次序为1,点击创建
预期结果:创建的课程正确显示在下面的表中,并且按照展示次序排列。
用例2:添加老师功能
前置条件:系统中没有老师,已经有课程 ‘初中语文’,‘初中数学’
step 1: 添加老师,输入老师姓名、登录名、描述、展示次序为2,选择课程 ‘初中语文’
预期结果:创建的老师正确显示在下面的表中。
step 2: 再添加一个老师,展示次序为1,选择课程 ‘初中数学’
预期结果:创建的老师正确显示在下面的表中,并且按照展示次序排列。
第一个用例我们已经做过了,现在我们看第二个用例。上面的章节中我们已经实现了前面的用例,我们看下它的代码结构

我们看下 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
。

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

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

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

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

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

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

下面来进行我们的初始化操作
*** 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 类

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

根据 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>
网友评论