小言_互联网的博客

Robot Framework Selenium UI自动化测试 --- 进阶篇

1943人阅读  评论(0)

回顾:
         如果您对Robot Framework Selenium(以下简称RFS)没有基础概念和使用经验,请先阅读入门篇,入门篇对RFS有基础的介绍和使用教程。


展望:
         本篇主要讲述了如何工程化的使用RFS,并穿插介绍各种常用关键字和使用技巧,希望能给大家带来帮助。

写在正片开始之前----论元素定位的重要性       
 

web页面的元素定位是UI自动化的基石,我在工作中见过无数同事使用工具获取xpath的方式进行元素定位,这样做有以下缺点:

1. 工具获取的元素定位多为从web树状结构的根节点开始,比如这样的:/html/body/div[4]/div[5]/div[2]/div[4]/div[4]/ul[5]/li[2]/ul/a
这样的定位,页面结构略有变化就会找不到这个超链接,导致后面的维护工作量巨大。(正确的定位方法请看本文中的示例)

2. 由于不是自己分析页面结构,就无法提炼出公共的元素定位方法,无法参数化,反而效率会低。并且如果web框架进行整改,由于以上事情没有做,UI自动化的元素定位可能会大面积报错,只能一个一个去修改。

3. 不能更好的理解前端开发设计页面的习惯,无法为之后前端开发植入可测试性代码提出针对性建议。
 

工程化

起因

(接上篇)------以下以华为云VPC的UI自动化为例

        测试猿小明自从掌握了RFS的基本用法,感觉UI自动化也就这样了,就是来回点点,输点文字,按下确定键,判断预期是否正确。
        公司最近开始准备缩短版本交付周期,要求他写一套UI自动化,用来保障产品功能可用。他迅速的写了30+用例,在本地跑没有问题,就放倒jenkins上(本篇不讨论如何使用jenkins跑RFS,如果有需要,再另起一篇),设置每天凌晨3点定时跑一轮,这样第二天早上就能看到结果了。
        第二天,小明傻眼了,测试用例除了头两条,后面的全部失败了,一大片红色的失败图标特别扎眼。
        通过仔细的查看log,发现第三条用例创建产品失败了,之后的操作都在这个产品创建成功的基础上进行的。由于找不到指定的实例,之后所有用例全部执行失败了。
        小明修改了无法创建产品的bug(查明是环境原因造成的),重新上传了新的自动化用例,并直接开启新一轮测试。结果这次还是失败了,原因是登录时,由于浏览器没有完全加载完,导致登录按钮没有找到,用例执行全军覆没。
        小明继续修复了这个问题,再次执行(xN)…..
        一天过去了,仅有一次非常幸运的跑完了全部用例,小明也搞的头昏眼花。

乐高积木

        第三天,小明看着用例执行报告中一大片红色,已经没那么大干劲了,觉得这简直是无法解决的问题。只好求助公司的老测试Aino。
        Aino查看了小明写的测试用例,指着各个测试用例说:“你这测试用例都是一条流水线,中间任何一环失败,后面的测试用例都无法执行,自动化用例不能这么写。”
        小明:“那应该怎么办?”
        Aino:“这个项目你时间还充裕吧,我这有一套乐高积木,刚好明天是周末,回去和小小明好好玩玩。”

启迪

        周一,小明把乐高积木还给Aino。
        Aino笑咪咪的问他:“怎么样,好玩么?”
        小明:“好玩,一开始随意组装,能逗的儿子哈哈大笑。后来儿子想搞个大的,要组合个小汽车出来。经过我们不断的组合,拆除,计划后重新组合,终于做出了像样的小汽车。”
        Aino:“总结下造这个汽车的经验吧~”。
        小明:
        1. 首先,要分析下小汽车的形状,把汽车拆分成底盘,车身,轮子等等。(分析测试对象)
        2. 其次,要知道手头的乐高积木有哪些形状,形状之间如何组合。(分析自己有什么)
        3. 设计底盘,车身和轮子的大小,并分别组装好,预留最后组装用的接口。(模块化)
        4. 组合整体(中间还出现各种一开始没有考虑到的组装先后问题)。(组合)
        Aino拍了拍小明的肩膀:“你已经掌握了工程化最基本的思路,现在,我给你讲讲这个UI自动化项目该怎么做吧。”

工程化---分析被测对象----VPC简介

我们先看一下被测对象---华为云---VPC。(简单的说,就是云上机房)

访问地址(需注册)https://console.huaweicloud.com/vpc/

虚拟私有云(Virtual Private Cloud,以下简称VPC),为弹性云服务器构建隔离的、用户自主配置和管理的虚拟网络环境,提升用户云中资源的安全性,简化用户的网络部署。

您可以在VPC中定义安全组、VPNIP地址段、带宽等网络特性。用户可以通过VPC方便地管理、配置内部网络,进行安全、快捷的网络变更。同时,用户可以自定义安全组内与组间弹性云服务器的访问规则,加强弹性云服务器的安全保护。

 

根据这个图,我大概讲一下VPC各个成员(不用完全理解):

1. VPC可以理解为云上的局域网。

2. 这个局域网可以划分若干个子网。(广播范围)

3. 子网内的设备ECS(云主机)上绑定了安全组规则。

4. 子网和外界通讯可以绑定ACL(防火墙)规则。

5. ECS和互联网通讯,可以单独绑定EIP(弹性公网IP)直接和外网通讯。

6. 子网内所有ECS也可以通过子网绑定的NAT(网络地址转换)网关和外界通讯

7. VPC有两种连接方式,VPN(虚拟局域网)和云专线(直接给你拉条网线/光纤)

工程化---分析被测对象----增删改查

【重要理论】对于绝大部分的自动化(无论是UI还是接口),都是完成了增删改查功能。

        所以,我们的自动化也要围绕着增删改查来进行,对测试用例细粒度把控,也要能细化到具体项的增删改查功能。

        大多数情况下,自动化测试由于牵扯到资源释放的问题,都会遵循增---------------查的顺序进行。这样在一个正常的情况下,创建出来的资源都在正确执行后被删除。一套无法恢复环境到执行前状态的自动化是不合格的。

工程化---分析被测对象----前置条件

        我们写测试用例,里面就有一项“前置条件”,里面基本是对测试环境的描述。

        在自动化中,前置条件可以认为是对资源状态的控制,这个控制可以是显性的(比如设置在setup中),也可以是隐性的(之前执行的测试用例)。

        前置条件有问题,是导致测试用例大面积失败的主要原因。小明之前编写的测试用例,创建一个VPC就是作为其他用例执行的大前提,所以如果VPC创建失败,所有的用例都会失败。

        那怎样避免这种情况发生?

        答案是无法避免,但是可以尽量缩小因失败影响的范围。

        比如以上例子,我们的VPC修改,可以放到一个已经创建好的VPC上去进行,这样即使目前VPC的创建自动化用例失败了,我们一样也可以测试VPC的修改功能。

        这样,就牵扯到我们的另一个话题:预置资源。

工程化---分析被测对象----预置资源

        预置资源,就是我们在测试对象中创建好的资源,比如各个模块的实例。

        可是,这样有什么用?

        这可不是为你节省了创建资源的时间:)

        我们不希望自动化测试是在一个不稳定或者什么都没有的环境下进行,因为如果那样做,不稳定性会大大增加,任何一个微小的错误都会被无限放大。

        如果所有的模块之间都是继承关系(很遗憾,实际大部分情况都是如此),比如有A才有B,有B才有C,有C才有D这样的调用链,我们写了分别创建ABCD的自动化用例,如果A创建失败,会造成BCD全部失败。B失败,会造成CD全部失败。

        即使非常幸运的ABCD都创建成功了,我们又有另一个问题:删除。

        因为调用链的关系,删除一般都得反着来,即删除的顺序为DCBA,同样的,删除调用链上的任何一个环节的失败,也会影响到后面用例的执行。

        那怎么办呢?

        当然是创建预置资源了J

        我们创建预置资源abc,(分别对应ABC)(资源创建一般都是一条调用链上的,因为这样节省资源),然后就成了这样(自己思考下这样有什么好处):

A资源凭空造,然后测试增删改查。(最后A资源被自动删除)

a资源下创建B资源,然后测试增删改查。(最后B资源被自动删除)

b资源下创建C资源,然后测试增删改查。(最后C资源被自动删除)

c资源下创建D资源,然后测试增删改查。(最后D资源被自动删除)

----------------------------------------思考时间------------------------------------------------

        想好了么?(有时候,思考的过程比你得到的结果更宝贵)

        这样做最大的好处,就像把整个调用链上的各个节点放了checkpoint,如果本小结失败了,可以从下个小结从头(checkpoint)开始,因为资源已经创建好了。

        如果以后完成了自动化用例,创作者能很清晰的指出“这几个是一个循环”,“这里使用了我预置好的资源”。

        细心的小明又指出了另一个问题:“那我如何判断我该创建多少这样的资源?”

        这里,就牵扯到预置资源创建的细粒度问题。

        根据Aino的个人经验,如果自动化测试调用链上游的资源会影响8-10条以上的用例,就应该为这组自动化用例创建一个预置资源。因为我们能承受的自动化失败浪费的时间,就在这个范围内

        预置资源还有一个好处,一些我们测试的前提条件,可能是外部的,这些外部的资源创建,不在我们的考虑范围内。比如ECS(云主机)的创建,是需要消耗大量时间的,那我们就可以提前创建好它。

工程化---分析被测对象----重试机制

        是自动化测试就会存在失败,失败一般有以下几种可能:

        1. 自动化用例本身的问题,比如UI测试的元素定位不唯一,接口测试的传参错误等等。(这种就是我们需要人工维护的部分了)

        2. 执行的前置条件未满足。(这条我们已经使用预置资源尽量避免)

        3. 环境不稳定,比如UI测试的页面加载不出来(服务器卡了),接口测试的响应超时等等。

        其实第三种是很常见的情况。自动化从某种层面上来讲,是很“僵硬”的。

        这里我们可以学习TCP/IP,对失败的部分进行重试。

        重试的原理也很简单,就是对结果进行判断,如果不是想要的结果,就再试试。

        这个“重试”也可大可小,可以是自动化中的某一个步骤,也可以是整条自动化用例,甚至是某个模块全部的自动化用例。

        根据在实际操作中的经验,重试机制会大大提高自动化测试的成功率,并且排除了很多因为环境不稳定造成的失败。

工程化---分析被测对象----抽象

        IT行业有个很明显的特点,就是复用率特别高。或者通俗点说,大家的代码可能都很像:)。一块代码逻辑,处处使用,是很正常的。

        所以后面就有了框架,有了组件,大家统一抄。

        既然这样,就知道开发同学一定会遵循框架,使用组件。我们在做自动化之前,需要分析下框架和组件,从中抽象出共通的部分。

        抽取出的公共部分,会很好的指导我们进行自动化用例的参数化。

        比如:

        1. 抽象出所有的创建资源的按钮的元素定位。

        2. 抽象出搜索框的一系列操作,并做成一个关键字(函数)。

        3. 抽象出需要更改的配置信息,并参数化。

        4. 抽象出浏览器分辨率和显示按钮的关系,并在某个地方判断,选择。

        5. 抽象出调用链的出入参关系。

        这里只列举了几个,只要你觉得对你的工作有意义,就可以找出规律并使用它。

        如果你研究多了,你可以给开发提建议:“伙计,在这给我加个ID如何~”。

工程化---分析自己有什么----主界面

        工欲善其事,必先利其器。先看看我们有什么样的武器。(以下截图中使用seleniumLibary,实际应该使用Selenium2Library)

工程化---分析自己有什么----资源文件和套件设置

工程化---分析自己有什么----UI自动化最常用关键字介绍

点击和输入:

Click Element   

        页面操作使用最多的关键字,点击元素,可以不用点击的特别“具体”,比如某个div下只有一个a链接,那么点击div也可以。但是,如果元素定位不唯一或者点击对象的覆盖范围有其它可点击元素,会报错---“其它元素收到了点击”。

        此外,可用的点击关键字还有Click Element At Coordinates,用于无法确认元素的情况,比如复杂控件中的点击。一般不使用,因为X轴和Y轴的绝对位置可能会因为环境的变化而变化。

        在某些情况下,也会使用Double Click Element,唯一的差别是这个关键字是双击。

Input Text

        输入文字的关键字,一般来说,对象都是一个input或者textarea。要注意的是,至今为止Selenium2Library中这个操作都有个bug,当连续在多个元素上输入文字的时候,中间如果不加sleep,概率有输入错乱的情况发生。

        还有个关键字,在这里要特别指出,那就是Input Password,因为这个和Input Test唯一的区别是,在log中不打印,以防别人通过log就知道密码,所以这个关键字可不仅仅是能在输入密码的时候使用:)。

Wait Until---智能等待系列:

        作为一位资深点点点,大家都懂,如果页面没加载出来按钮,我们不会去点按钮的。但是程序就是这么傻,咋办,先等待元素状态稳定再操作呗。

        在RFS中,智能等待主要分为三种:

1. 判断页面元素状态的智能等待:

Wait Until Page Contains Element

        判断页面是否包含元素,唯一要注意的是,如果页面包含多个符合定位条件的元素,此关键字只要其中一个满足条件,即为成功。

        对应的反向关键字为Wait Until Page Does Not Contain Element,这里和上面相反,页面不能有任何一个元素符合定位条件,才为成功。

Wait Until Element Is Enabled

        在这里的Enabled是指的元素的Enbale/Disable属性,当元素属性为Disabled时,元素是不可操作的,有时候,在页面加载的元素之间有逻辑判断,比如a的状态为1时,b的元素才会从Disabled变成Enabled(页面由于加载顺序的问题,这种情况经常发生),所以我们要确认目标元素的状态为Enabled,然后再对元素进行操作。

Wait Until Element Is Visible

        原理同上,有时页面的元素虽然已经加载了,但是不是Visible状态,实际页面是不显示的,这样的情况下,对元素的操作也是无效的。

        对应的反向关键字为Wait Until Element Is Not Visible,不过一般这条和上面的Wait Until Page Does Not Contain Element一样,大多数情况下是作为断言用的。

用户自定义关键字---元素等待:

        以上三个关键字,我喜欢一起使用,因为一般操作的元素一定是页面包含,并且可用,可见的,这里,我们引入了用户自定义关键字

        用户自定义关键字就是编程中封装,可以把相对应的一组操作放到一起,并且抽取其中可能的变量([Arguments])(也可以不抽取):


  
  1. wait element
  2. [Arguments] ${element locator}
  3. comment 这里的文字可以在 log中看到,本用户自定义关键字检察元素是否被包含,可用,可见,以下依次判断:
  4. Wait Until Page Contains Element ${element locator} 20s
  5. Wait Until Element Is Enabled ${element locator} 20s
  6. Wait Until Element Is Visible ${element locator} 20s
  7. sleep 1

        上面代码中的${wait time}是在资源文件中已定义的变量,sleep    1 的作用是降低运行速度,增加容错率。

2. 断言用的智能等待:

【Tips】断言在这里是指对某个操作结果的判断。

Wait Until Page Contains

        强烈推荐,不用元素定位,全页面等待某个文本,出现即为断言结果为True,在超时时间过了不出现即为False,适用于关键操作有页面提示的框架。

        相对应的反向关键字为Wait Until Page Does Not Contain,适用于在业务状态变化后,页面某文字消失的情况,不是特殊情况,不建议使用,因为大部分情况下,某文字的消失,并不能说明业务一定成功了。

Wait Until Page Contains Element

        在页面上等待符合定位的某元素出现,即为判断结果为True,在超时时间过了不出现即为False,某些情况下比较好用。

        相对应的反向关键字为Wait Until Page Does Not Contain Element,使用方法和上面一样,这里就不再描述。

Wait Until Element Contains

        判断元素包含的文本,其实这个有3个需要注意的地方:

                1. 元素先被找到,如果页面未包含元素,直接报错。

                3. 文本是“包含”,比如目标文本内容为"123",我们断言的内容为"23",也会判断为True。

                2. 如果定位有多个符合的元素,就会依次查找。

        所以这个关键字是判断某一瞬页面是中某元素是否包含某文本,如果文本在这一瞬没有出现,就会判断为False。

        相对应的反向关键字为Wait Until Element Does Not Contain,使用方法和上面一样,这里就不再描述。

用户自定义关键字---断言:

        由于华为云在关键操作后(一般是提交表单),都会有后台响应的页面提示,会显示5秒,为了方便定位,我们在提交表单3秒后,可以先做一次截屏(Capture Page Screenshot),这样通过截图能分析失败原因,然后再断言:


  
  1. wait contains
  2. [Arguments] ${ wait text}
  3. comment 先sleep3秒等待响应出现并截图,之后再断言我们需要断言的内容
  4. sleep 3
  5. Capture Page Screenshot
  6. wait until page contains ${ wait text} 20 s
  7. sleep 1

         这里sleep    1 的作用是降低运行速度,增加容错率。

3. 重试用的智能等待:

        记得我们上面说的“重试机制”么,大部分情况下的重试,都使用这个关键字来完成。

Wait Until Keyword Succeeds

        这个关键字很重要,这个关键字很重要,这个关键字很重要

        我们做手工测试,如果看到某个按钮没有加载出来,或者点击无反应,我们会稍等下再点点看。

        默认情况下,自动化脚本如果点击失败,直接就会报错,然后本条自动化直接失败。这个是造成自动化稳定性的罪魁祸首。

        使用这个关键字,可以在失败的情况下重试。

        使用方法如下:

        Wait Until Keyword Succeeds    3x    5s    click element    css=#123

        其中,3x代表重试次数,5s代表每次重试间隔时间,后面就是关键字和其参数了,这里是点击ID为123的元素。

        这样,就做到了如果点击ID为123的元素,如果成功,继续往下走;如果失败,隔5秒后重新点击试试。成功了继续,失败了再来,直到三次都失败为止。

        这样,我们就可以这样封装点击和输入的操作了:


  
  1. wait click
  2. [Arguments] ${element locator}
  3. comment 这里使用了上面已经建立好的 wait element用户自定义关键字
  4. wait element ${element locator}
  5. comment 使用focus可以聚焦元素
  6. focus ${element locator}
  7. comment 尝试点击元素,成功继续,失败5秒后重试,3次失败后本行失败
  8. Wait Until Keyword Succeeds 3x 5s click element ${element locator}
  9. wait input
  10. [Arguments] ${element locator} ${input text}
  11. comment 这里使用了上面已经建立好的 wait element用户自定义关键字
  12. wait element ${element locator}
  13. comment 使用focus可以聚焦元素
  14. focus ${element locator}
  15. comment 尝试输入文字,成功继续,失败5秒后重试,3次失败后本行失败
  16. Wait Until Keyword Succeeds 3x 5s input text ${element locator} ${input text}

        扩展下,以上关键字click element也可以是某个用户自定义关键字,比如登录,这样可以做到登录失败,就可以再次登录,比如以下写法:


  
  1. loginHEC
  2. comment 使用google chrome浏览器打开网址
  3. comment 网址后面使用 get参数直达我们想要到的页面
  4. Open Browser https://console.huaweicloud.com/vpc/?region=cn-east -2&locale=zh-cn #/vpc/vpcmanager/dashboard gc
  5. comment 由于默认打开的浏览器是小窗口,这里设置浏览器的大小为 1920 1080
  6. Set Window Size 1920 1080
  7. comment 最大化浏览器,最大化后,会根据windows系统桌面的分辨率重置浏览器分辨率,有可能会导致上面设置 1080p分辨率失效
  8. Maximize Browser Window
  9. comment 尝试登录系统,如果其中任意一步失败,则重试
  10. Wait Until Keyword Succeeds 3x 5s login_retry
  11. login_retry
  12. comment go to是在当前浏览器中跳转到 url,这里使用 go to是因为使用这个可以重置浏览器到输入用户名和密码的界面,方便retry
  13. go to https://console.huaweicloud.com/vpc/?region=cn-east -2&locale=zh-cn #/vpc/vpcmanager/dashboard
  14. comment 输入用户名和密码,并点击确定
  15. wait input css= #userNameId username
  16. wait input css= #pwdId password
  17. wait click css= #btn_submit
  18. comment 断言是否页面上有“快速指南”,如果有,登陆成功
  19. Wait Contains 快速指南

       看到这里,小明提出一个问题,要是在Open Browser就失败了,后面岂不是没有重试了?

       所以我们也要把loginHEC的关键字通过这种方式,放到test suite的setup中去:

        这样就做到了打开浏览器重试3次 乘以 登录重试3次,不是特殊中的特殊情况,这样足够了。

      以上就是我们能处理90%以上UI自动化用到的关键字了,是不是很少 :)

      后面我会在实际例子中穿插介绍其它常用的关键字,但是在这之前,我们还有个很重要的事要做,那就是:

提取并参数化公共参数:

      参数化一般有两个用处:

          1. 使用比较多的参数,我们如果需要更改,就得手动去每个脚本中修改,其实我们可以把这个值提取到变量中,这样就能做到全局修改,比如最典型的超时等待时间的参数化。

          2. 一条用例使用多个参数进行测试的情况,比如下拉列表的遍历,边界值的测试等等。

      比如综合上面所有一定义的关键字,可以把所有的超时时间20s修改为参数${wait time},失败重试的次数参数化为${retry times},用户名和密码修改为${username}和${password},并参数化访问的网址为${VPC Dashboard URL},替换后,资源文件就变成了这样:


  
  1. *** Settings ***
  2. Library Selenium2Library
  3. Library Collections
  4. *** Variables ***
  5. ${wait time} 20s
  6. ${retry times} 3x
  7. ${username} 你申请的用户名
  8. ${password} 你设置的密码
  9. ${VPC Dashboard URL} https://console.huaweicloud.com/vpc/?region=cn-east-2&locale=zh-cn #/vpc/vpcmanager/dashboard
  10. *** Keywords ***
  11. wait element
  12. [Arguments] ${element locator}
  13. comment 这里的文字可以在 log中看到,本用户自定义关键字检察元素是否被包含,可用,可见,以下依次判断:
  14. Wait Until Page Contains Element ${element locator} ${wait time}
  15. Wait Until Element Is Enabled ${element locator} ${wait time}
  16. Wait Until Element Is Visible ${element locator} ${wait time}
  17. sleep 1
  18. wait click
  19. [Arguments] ${element locator}
  20. comment 这里使用了上面已经建立好的 wait element用户自定义关键字
  21. wait element ${element locator}
  22. comment 使用focus可以聚焦元素
  23. focus ${element locator}
  24. comment 尝试点击元素,成功继续,失败5秒后重试, ${retry times}次失败后本行失败
  25. Wait Until Keyword Succeeds ${retry times} 5s click element ${element locator}
  26. wait input
  27. [Arguments] ${element locator} ${input text}
  28. comment 这里使用了上面已经建立好的 wait element用户自定义关键字
  29. wait element ${element locator}
  30. comment 使用focus可以聚焦元素
  31. focus ${element locator}
  32. comment 尝试输入文字,成功继续,失败5秒后重试, ${retry times}次失败后本行失败
  33. Wait Until Keyword Succeeds ${retry times} 5s input text ${element locator} ${input text}
  34. wait contains
  35. [Arguments] ${wait text}
  36. comment 先sleep3秒等待响应出现并截图,之后再断言我们需要断言的内容
  37. sleep 3
  38. Capture Page Screenshot
  39. wait until page contains ${wait text} ${wait time}
  40. sleep 1
  41. loginHEC
  42. comment 使用google chrome浏览器打开网址
  43. Open Browser ${VPC Dashboard URL} gc
  44. comment 由于默认打开的浏览器是小窗口,这里设置浏览器的大小为1920 1080
  45. Set Window Size 1920 1080
  46. comment 最大化浏览器,最大化后,会根据windows系统桌面的分辨率重置浏览器分辨率,有可能会导致上面设置1080p分辨率失效
  47. Maximize Browser Window
  48. comment 尝试登录系统,如果其中任意一步失败,则重试
  49. Wait Until Keyword Succeeds ${retry times} 5s login_retry
  50. login_retry
  51. comment go to是在当前浏览器中跳转到url,这里使用go to是因为使用这个可以重置浏览器到输入用户名和密码的界面,方便retry
  52. go to ${VPC Dashboard URL}
  53. comment 输入用户名和密码,并点击确定
  54. wait input css= #userNameId ${username}
  55. wait input css= #pwdId ${password}
  56. wait click css= #btn_submit
  57. comment 断言是否页面上有“快速指南”,如果有,登陆成功
  58. Wait Contains 快速指南

准备工作就做好了,这样我们就可以创建我们本文第一条自动化测试用例。

模块化----第一条测试用例

【Tips】由于本文要示例元素定位的方法,所以元素定位均未参数化,而使用comment对操作进行说明。元素定位使用chrome开发者模式。

      在这里,我建议测试用例封装成一个关键字,因为只有这样,才方便测试用例进行整体重试。

      我们准备写一条创建VPC的测试用例,主要操作步骤如下图所示:

      (Chrome浏览器)右键点要操作的对象(此处是“虚拟私有云”),选择“检察(N)”

      当把鼠标放在阴影部分(<span class...)时,Web页面会展示此元素的作用域,并且我们观察到这个span中没有什么属性是唯一的。

      在Selenium中,对元素的操作要求不是那么严格,我们可以把鼠标从span依次往上移,看看父元素和周边元素的作用域。只要这个作用域还在我们鼠标可点击的范围内,均可以作为点击的对象来操作。

      向上移动后,我们发现父元素的div中有一个属性id="_vpc" ,并且它的作用域也是在我们要点击的范围内:

      由此,我们可以使用css选择器来定位元素,在css中,#_vpc可以理解为"选择所有id为_vpc的元素":

      分析出的定位结果为: #_vpc

      验证的方法很简单,点击开发控制台元素页面任意元素,按Ctrl+F出现元素搜索框(注意不要点到Web页面上了)

      输入我们分析出的css选择器结果:

      被选择器选中的元素会标记为黄色,可以把鼠标放到上面,看看是Web页面上显示的作用域是不是我们的预期结果。

      同时有个很关键的点,在搜索框的最后有个“1 of 1”,如果选择器查到的结果有多个,可能会对操作有影响,一般我们要确保此处是“1 of 1”。如果有多个,可以使用后面紧跟的上下箭头来切换标黄被选中的元素。

      有了元素定位,我们的用例就有了第一条脚本:


  
  1. create VPC
  2. comment 点击dashboard的“虚拟私有云”按钮,进入虚拟私有云页面
  3. wait click css= #_vpc

      进入虚拟私有云页面,我们要点击“创建虚拟私有云”按钮进入创建虚拟私有云的页面,定位如下:

      这里有唯一的class属性可以定位到按钮,和id有简写一样,class可以用"."来简写,所以定位结果为:

      .cti-btn-label

      更新到测试脚本中:


  
  1. create VPC
  2. comment 点击dashboard的“虚拟私有云”按钮,进入虚拟私有云页面
  3. wait click css= #_vpc
  4. comment 点击拟私有云页面中右上角的创建虚拟私有云按钮,进入虚拟私有云创建页面
  5. wait click css=.cti-btn-label

      进入创建页面后,需要输入新创建的VPC的名字,输入框一般在html中有两种,一种叫input,一种叫textarea,下图中的input框中有个属性是唯一的,我们可以通过它来对这个input框进行定位:

      元素类型[属性名称和其对应值]也可以作为选择器来使用,所以这个输入框的定位结果为:

      input[meta-data-uba="www_v1_vpc.click.vpc_createVpcList_name_input"]

      更新到测试脚本中:


  
  1. create VPC
  2. comment 点击dashboard的“虚拟私有云”按钮,进入虚拟私有云页面
  3. wait click css= #_vpc
  4. comment 点击拟私有云页面中右上角的创建虚拟私有云按钮,进入虚拟私有云创建页面
  5. wait click css=.cti-btn-label
  6. comment 输入新的虚拟私有云名字:vpc-temp
  7. wait input css= input[meta- data-uba= "www_v1_vpc.click.vpc_createVpcList_name_input"] vpc-temp

        同理,子网的名字输入也可以定位出来:

      更新到测试脚本中:


  
  1. create VPC
  2. comment 点击dashboard的“虚拟私有云”按钮,进入虚拟私有云页面
  3. wait click css= #_vpc
  4. comment 点击拟私有云页面中右上角的创建虚拟私有云按钮,进入虚拟私有云创建页面
  5. wait click css=.cti-btn-label
  6. comment 输入新的虚拟私有云名字:vpc-temp
  7. wait input css= input[meta- data-uba= "www_v1_vpc.click.vpc_createVpcList_name_input"] vpc-temp
  8. comment 输入新的子网名字:Subnet-temp
  9. wait input css= input[meta- data-uba= "www_v1_vpc.click.vpc_createVpcList_portal_input"] subnet-temp

    最后点击创建按钮:

                                                                                               


  
  1. create VPC
  2. comment 点击dashboard的“虚拟私有云”按钮,进入虚拟私有云页面
  3. wait click css= #_vpc
  4. comment 点击拟私有云页面中右上角的创建虚拟私有云按钮,进入虚拟私有云创建页面
  5. wait click css=.cti-btn-label
  6. comment 输入新的虚拟私有云名字:vpc-temp
  7. wait input css= input[meta- data-uba= "www_v1_vpc.click.vpc_createVpcList_name_input"] vpc-temp
  8. comment 输入新的子网名字:Subnet-temp
  9. wait input css= input[meta- data-uba= "www_v1_vpc.click.vpc_createVpcList_portal_input"] subnet-temp
  10. comment 点击创建按钮创建VPC
  11. wait click css=.cti-btn-label

      创建成功后,会显示如下页面,我们可以判断页面中是否出现红框的文字,从而判断创建虚拟私有云是否成功:


  
  1. create VPC
  2. comment 点击dashboard的“虚拟私有云”按钮,进入虚拟私有云页面
  3. wait click css= #_vpc
  4. comment 点击拟私有云页面中右上角的创建虚拟私有云按钮,进入虚拟私有云创建页面
  5. wait click css=.cti-btn-label
  6. comment 输入新的虚拟私有云名字:vpc-temp
  7. wait input css= input[meta- data-uba= "www_v1_vpc.click.vpc_createVpcList_name_input"] vpc-temp
  8. comment 输入新的子网名字:Subnet-temp
  9. wait input css= input[meta- data-uba= "www_v1_vpc.click.vpc_createVpcList_portal_input"] subnet-temp
  10. comment 点击创建按钮创建VPC
  11. wait click css=.cti-btn-label
  12. comment 判断页面上是否出现“任务提交成功!”来判断提交是否成功
  13. wait contains 任务提交成功!

      整个用例就完成了,在测试用例中调用这个关键字,就能自动化执行创建一个虚拟私有云:


  
  1. *** Settings ***
  2. Suite Setup Wait Until Keyword Succeeds ${retry times} 5s loginHEC
  3. Suite Teardown Close All Browsers
  4. Resource Resource.txt
  5. *** Test Cases ***
  6. VPC Create vpc-temp
  7. create vpc

      等等,如果这么做,失败了就没有重试了,根据我们之前讲的,是可以通过关键字重试的:


  
  1. *** Settings ***
  2. Suite Setup Wait Until Keyword Succeeds ${retry times} 5s loginHEC
  3. Suite Teardown Close All Browsers
  4. Resource Resource.txt
  5. *** Test Cases ***
  6. VPC Create vpc-temp
  7. Wait Until Keyword Succeeds ${retry times} 5s create vpc

      仔细观察创建VPC的关键字,如果真的在过程中失败了,重试也是无效的,因为我们创建的过程中,失败可能在任何界面

      所以,我们需要在这条用例的关键字的最前面加一个重置,即无论在哪失败,测试用例都能回到用例最初的页面。

      最常用的方法有两个:

          1. 使用go to关键字强制跳转到web页面(可参考login retry的用法)

          2. 使用Open Browser打开一个新的浏览器,并访问web页面

      绝大多数情况下,使用方法1,因为开新的浏览器会消耗执行机资源。

      又因为这个重置在我们测试”虚拟私有云“这个模块时会用的比较多,所以我们把这个动作封装成一个关键字,叫"Enter VPC Board"

      修改后的完美结果为:

      


  
  1. Enter VPC Board
  2. comment 通过 go to打开VPC dashboard
  3. go to ${VPC Dashboard URL}
  4. comment 点击dashboard的“虚拟私有云”按钮,进入虚拟私有云页面
  5. wait click css= #_vpc
  6. create VPC
  7. Enter VPC Board
  8. comment 点击拟私有云页面中右上角的创建虚拟私有云按钮,进入虚拟私有云创建页面
  9. wait click css=.cti-btn-label
  10. comment 输入新的虚拟私有云名字:vpc-temp
  11. wait input css= input[meta- data-uba= "www_v1_vpc.click.vpc_createVpcList_name_input"] vpc-temp
  12. comment 输入新的子网名字:Subnet-temp
  13. wait input css= input[meta- data-uba= "www_v1_vpc.click.vpc_createVpcList_portal_input"] subnet-temp
  14. comment 点击创建按钮创建VPC
  15. wait click css=.cti-btn-label
  16. comment 判断页面上是否出现“任务提交成功!”来判断提交是否成功
  17. wait contains 任务提交成功!

      这样,即使在任务中任意地方失败,用例都会从头重试整个创建过程。

      观察下我们已经创建的VPC。可以看到对新的VPC,有修改和删除操作:

      在进行修改和删除操作之前,我们观察到有组件提供的搜索实例功能,为了能唯一确定我们的操作对象,可以使用这个功能先搜索出我们要操作的对象,并把这个动作封装成一个关键字:

      我们可以看到上图中,其实是有两个可以使用的属性,但是这里选择了下面的,因为下面的属性是所有搜索框输入都能使用的属性,我们可以根据它创建整个自动化中都适用的搜索用户自定义关键字,后面的定位方法略,最后关键字内容为:


  
  1. Search
  2. [Arguments] ${Search Text}
  3. comment 输入搜索对象
  4. wait input css=.ti-searchbox-input ${Search Text}
  5. comment 点击搜索按钮
  6. wait click css=.ti-searchbox-search
  7. sleep 1

      以后我们遇到搜索框,就可以使用这个关键字,使要操作的实例唯一。

      创建完成后,自然是要进行修改了,这里有个小技巧,修改这个功能,可以修改内容后再修改回来,万一修改功能不可用,我们后面对这条实例的其它操作也不会受影响。

      先定位下“修改”的位置,这里使用Xpath的text()进行定位,当然,也可以使用jquery进行定位,后面再演示:

      然后是修改名字输入框,修改CIDR输入框和提交修改的按钮的元素定位:

      提交成功后,再次操作,把修改的内容全部修改回来,注意,这里搜索时使用新的vpc名字,最后完成的脚本为:


  
  1. modify VPC
  2. comment 先通过 go to URL的方式重置本用例,进入VPC模块页面
  3. Enter VPC Board
  4. comment 通过用户自定义搜索关键字,唯一要操作的实例对象
  5. Search vpc-temp
  6. comment 点击修改按钮(这里其实是个链接)
  7. wait click xpath=//a[ text()= '修改']
  8. comment 修改vpc的名字和cidr
  9. wait input css= input[meta- data-uba= "www_v1_vpc.click.vpc_detail_editVpcModel_name_input"] vpc- modify-temp
  10. wait input css= input[meta- data-uba= "www_v1_vpc.click.vpc_detail_editVpcModel_cidrMask_input"] 17
  11. comment 点击确定按钮提交修改
  12. wait click css=button[ng-click= "clickOK()"]
  13. comment 判断页面上是否出现“成功”来判断提交是否成功
  14. wait contains 成功
  15. comment 通过用户自定义搜索关键字,唯一要操作的实例对象
  16. Search vpc- modify-temp
  17. comment 点击修改按钮(这里其实是个链接)
  18. wait click xpath=//a[ text()= '修改']
  19. comment 修改vpc的名字和cidr
  20. wait input css= input[meta- data-uba= "www_v1_vpc.click.vpc_detail_editVpcModel_name_input"] vpc-temp
  21. wait input css= input[meta- data-uba= "www_v1_vpc.click.vpc_detail_editVpcModel_cidrMask_input"] 16
  22. comment 点击确定按钮提交修改
  23. wait click css=button[ng-click= "clickOK()"]
  24. comment 判断页面上是否出现“成功”来判断提交是否成功
  25. wait contains 成功

      尝试进行删除操作,但是这里无法直接删除:

      要进入VPC去删除里面的子网,才能进行进一步的VPC删除,所以我们先进行子网的删除(由于定位没有难点,此处省略):


  
  1. delete subnet
  2. comment 先通过 go to URL的方式重置本用例,进入VPC模块页面
  3. Enter VPC Board
  4. comment 通过用户自定义搜索关键字,唯一要操作的实例对象
  5. Search vpc-temp
  6. comment 点击VPC详情链接
  7. wait click css=a[meta- data-uba= "www_v1_vpc.click.vpcList_vpc_detail"]
  8. comment 通过用户自定义搜索关键字,唯一要操作的实例对象
  9. search subnet-temp
  10. comment 点击subnet后面的删除按钮
  11. wait click xpath=//a[ text()= '删除']
  12. comment 点击确认删除按钮
  13. wait click css=button[ng-click= "clickOK()"]
  14. comment 判断页面上是否出现“成功”来判断提交是否成功
  15. wait contains 成功

    这次可以对VPC进行删除操作了:


  
  1. delete VPC
  2. comment 先通过 go to URL的方式重置本用例,进入VPC模块页面
  3. Enter VPC Board
  4. comment 通过用户自定义搜索关键字,唯一要操作的实例对象
  5. Search vpc-temp
  6. comment 点击删除按钮(这里其实是个链接)
  7. wait click xpath=//a[ text()= '删除']
  8. comment 点击确认删除按钮
  9. wait click css=button[ng-click= "clickOK()"]
  10. comment 判断页面上是否出现“成功”来判断提交是否成功
  11. wait contains 成功

      把以上的创建---修改---删除放在一起,连跑下,一个最小的循环体就完成了:

    如果所有的用例不出错,创建-修改-删除,最后资源会恢复到最初的状态。由于目前这个小循环体只牵扯4条用例,我们不需要添加预置资源。如果后面做自动化用例设计,创建的资源要被数十条用例使用,就可以事先创建好这个资源。

    当然,事先创建资源也有不好的地方,主要体现在以下两个方面:

        1. 某些新创建资源和以前创建的资源(预置资源)有差别,比如创建时加入了新的属性。

        2. 用例有失败,复杂的预置资源会影响自动化环境手动恢复的时间。

    所以,可以根据业务的不同,有节制的使用预置资源,如果自动化创建的资源,和后面多条用例都有耦合,我们可以这么做:

    此资源创建完成后,判断资源是否完全创建成功,并把这个结果传给一个变量,并把这个变量设置为全局变量。和此资源耦合的用例,先判断这个变量的值,符合条件再跑。这样,有耦合的这些用例就不会傻傻的跑很久。

    我们还是用上面VPC的创建-修改-删除来做个例子。需要做的是:

        1. 新增一个判断VPC创建状态并返回这个状态值的用户关键字:


  
  1. check VPC
  2. comment 初始化一个套件内使用的公共变量,并赋值为uncreated,用来记录VPC创建是否完成的状态
  3. Set Suite Variable ${vpc created status} uncreated
  4. comment 先通过 go to URL的方式重置本用例,进入VPC模块页面
  5. Enter VPC Board
  6. comment 直接检查页面上是否存在刚才创建的VPC
  7. wait contains vpc-temp
  8. comment 由于RF会在失败后停止执行,如果上面的检查成功了,才能执行以下这条,并赋新值
  9. Set Suite Variable ${vpc created status} created

        2. 在第一个使用刚才创建VPC的资源的用例之前执行这个用户关键字,并在后面所有要使用这个资源的前面先判断资源状态,如果有资源就执行,否者直接跳过:


  
  1. *** Settings ***
  2. Suite Setup Wait Until Keyword Succeeds ${ retry times} 5s loginHEC
  3. Suite Teardown Close All Browsers
  4. Resource Resource.txt
  5. *** Test Cases ***
  6. VPC Create vpc-temp
  7. Wait Until Keyword Succeeds ${ retry times} 5s create vpc
  8. check VPC Resource
  9. Wait Until Keyword Succeeds ${ retry times} 5s check vpc
  10. modify VPC vpc-temp
  11. Run keyword if '${vpc created status}'== 'created' Wait Until Keyword Succeeds ${ retry times} 5s modify vpc
  12. delete subnet subnet-temp
  13. Run keyword if '${vpc created status}'== 'created' Wait Until Keyword Succeeds ${ retry times} 5s delete subnet
  14. delete VPC vpc-temp
  15. Run keyword if '${vpc created status}'== 'created' Wait Until Keyword Succeeds ${ retry times} 5s delete vpc

    小明马上跳出来问:为什么不把这个资源判断放在setup中执行?

    其实也可以放在modify vpc vpc-temp的setup中,但是由于RF的限制,setup中不太方便使用wait until keyword succeeds,除非再封装一层。而且把这条放在外面,在分析的时候,能一眼看到是资源文件没有创建成功。

——————————————————追加部分 自动滚屏————————————————

    至此,只要按照上面的方法,绝大部分的UI自动化问题都能解决。但是对绝大部分Selenium使用者来说,还有一个让很多人头大的问题,那就是需要操作必须滚动后才能看见的元素。

    网上有很多办法,一般来说简单的有以下三种方法:

        1. 使用focus,可以聚焦元素后,自动滚屏过去。

        2. 使用Scroll Element Into View (Selenium2Library3.0)自动滚到元素可见。

        3. 直接用scroll down这个关键字滚屏,但是我们不知道需要滚屏多少,很多时候都是估算。

    其中1和2的方法,有时候能生效,有时候有莫名其妙的失败。3的方法每次滚屏都可以成功,但是有可能因为版本的变更,自动化执行机分辨率的变化等等造成滚过了或者没滚到。

    然后,笔者自己写了一个用户关键字,改造了我们上文提到的用户关键字wait element,使用了3的方法,但是可以智能的获取滚动高度,大家可以根据需要取用:


  
  1. scroll to
  2. [Arguments] ${scroll value}
  3. comment 由于部分Selenium2Library不支持Scroll Down,故自己写一个用js滚屏的关键字
  4. Execute Javascript var q=document.documentElement.scrollTop= ${scroll value}
  5. wait element
  6. [Arguments] ${Element_LOCATOR}
  7. wait until page contains element ${Element_LOCATOR} ${wait time}
  8. Wait Until Element Is Enabled ${Element_LOCATOR} ${wait time}
  9. comment 这里重试是因为有小概率会发生因为页面加载不完全导致的获取滚动高度有问题的情况
  10. Wait Until Keyword Succeeds 4x 5s get scroll height ${Element_LOCATOR}
  11. comment 当被操作额元素在屏幕一半以上时,会出现计算的滚屏高度为负值的情况,故先判断下
  12. run keyword if ${scroll} >= 0 scroll to ${scroll}
  13. Wait Until Element Is Visible ${Element_LOCATOR} ${wait time}
  14. Capture Page Screenshot
  15. sleep 2
  16. get scroll height
  17. [Arguments] ${Element_LOCATOR}
  18. comment 先滚动屏幕到最上方,这样获取的垂直高度才是正确的
  19. scroll to 0
  20. comment 获取当前屏幕的高度(因为可能有变化)
  21. ${window-width} ${window-height}= get window size
  22. comment 获取目标元素距离浏览器顶端的滚屏垂直高度,有兴趣的可以看源码如何实现
  23. ${Vertical Position} Get Vertical Position ${Element_LOCATOR}
  24. log ${Vertical Position}
  25. comment 计算从web顶端需要滚屏多少像素才能(尽量)把元素放在屏幕水平中间
  26. ${scroll}= Evaluate ${Vertical Position}-( ${window-height}/2)
  27. comment 设置这个变量为suite内均可使用,这样才能跨关键字使用
  28. Set Suite Variable ${scroll}

——————————————————追加部分 常用元素定位—————————————

    剩下的部分,我又要唠叨回到我们文章最早强调的:元素定位

    目前,要解决元素定位不稳定的问题,有两个方面:

        1. 给操作的元素增加id

        2. 使用更优的元素定位写法

    这两个不冲突,但是1是一种可测试性的植入,需要开发配合(除非你被允许改开发的代码)。2就是我们需要自己提高的部分了。

    我目前使用的元素定位,主要使用css选择器和xpath选择器,这两个基本可以搞定绝大部分元素定位的工作。

    我在这可以放置一些常用的语法,方便各位取用:

    CSS部分:

css=span.icon-cloud-action-add        ---------根据class属性值寻找元素 

css=input[tester="JustTest"]        ----------根据非class属性值寻找元素

css=#PRcx tbody tr>td:first-child>a       ----------父元素ID+子元素层级+多平级元素选第一个

    Xpath部分:

xpath=//span[text()='提交']        -----------根据文字寻找元素

xpath=//span[contains(text(),'提交')]        -----------根据部分文字寻找元素

xpath=//span[@class="resourceGroupText ng-binding"]        ----------根据class属性寻找元素

xpath=//span[contains(@class,'resourceGroupText')]        ----------根据部分class属性寻找元素

xpath=//li//span[text()="Stop"]/parent::*/parent::*//span[text()='Start']        -----------根据某唯一元素,反向找到其父元素,再重新向下找

xpath=//li//span[text()="Stop"]//following-sibling::*//span[text()='Start']         -----------根据某唯一元素,找到其后的兄弟元素

xpath=//li//span[text()="Stop"]//preceding-sibling::*//span[text()='Start']         -----------根据某唯一元素,找到其前的兄弟元素

xpath=//div[@id="menu"]/div[last()]         ---------某div的下级div的最后一个

xpath=//div[@id="menu"]/div[last()-1]         ---------某div的下级div的倒数第二个

xpath=//span[string-length(text())=10]         ----------根据对象的某个值的长度寻找元素

——————————————————追加部分 循环语句的使用————————————

    我们有很多情况会使用到循环,比如循环遍历某下拉菜单,或者需要循环删除一些资源,甚至更为复杂的循环场景。要实现这些,其实只要掌握两点:

        1. 一个最基本的循环实现。

        2. 如何实现二层及二层以上的循环。

    我们先看一下最基本的循环,以下是一个最基本的循环的关键字用法,是一个实际(目前)可用的RF用例:


  
  1. clean order
  2. comment 打开浏览器并登录
  3. Login_HEC
  4. comment 通过 go to直接跳转到华为云订单管理页面
  5. go to https://account.huaweicloud.com/usercenter/?region=cn-southwest -2_pankerong&locale=en-us #/userindex/myOrder
  6. comment 设置循环的次数为 2000,注意以下的写法,循环将会从 0开始,到 1999结束(如果没有满足退出条件的话)
  7. : FOR ${i} IN RANGE 2000
  8. comment 使用run keyword and return status返回后面等待元素的结果,元素定位为本页订单第一行的删除按钮
  9. \ ${ status}= run keyword and return status wait element css= #row_0_1
  10. comment 打印这个结果
  11. \ log ${ status}
  12. comment 给出循环跳出条件,这里是第一行不存在(如果全部 order都删完了,第一行自然没有了)
  13. \ run keyword if '${status}'== 'False' Exit For Loop
  14. comment 这里能执行,其实是因为 '${status}'== 'True',因为只有两个可能,所以省略
  15. \ wait click element css= #row_0_1
  16. \ wait click element css= #cancle_msg_ok_btn

    如果是二层或者二层以上的循环,在RF中不能用我们平常写代码的方式实现,只能把第二层的循环封装到关键字中,在第一层循环中调用,这部分我就不给大家举例子了,自己试试比较好。

————————————追加部分 获取符合条件的实例个数——————

    很多情况下,我们需要获取当前页面一些符合条件的实例的个数,比如下图:

    我想获取子网个数为1个的虚拟私有云的个数,应该如何做?

    其实很简单,我们先找出要找出共同点,这几行的共同点就是它们都有一个span的文字内容是‘一个’,我们用xpath定位如下:

    在页面上符合我们定位结果的是5个,这个也是目前实际确实只有1个子网的VPC的个数,RF提供了一个关键字,我们可以直接把这个5提取出来:


  
  1. get number we need
  2. comment 首先要等页面加载数据完成,因为获取是“一瞬完成”
  3. wait element xpath=//span[ text()= '1 个']
  4. comment 获取符合条件的xpath筛选结果的个数,注意,这里限定只能是xpath,所以后面不要用xpath=
  5. ${ count number} Get Matching Xpath Count //span[ text()= '1 个']
  6. comment 打印这个值
  7. log ${ count number}

    当然,如果你已经知道结果是5个,只是想判断是不是5个,可以用这个方法:


  
  1. must 5 res
  2. comment 先等待
  3. wait element xpath=xpath=//span[ text()= '1 个']
  4. comment 注意不用加xpath=
  5. Xpath Should Match X Times //span[ text()= '1 个'] 5

——————追加部分 如何处理指引这种只出现一次的弹窗—————————

    有很多弹窗,会判断你的cookie,如果cookie没有打开记录,就会在进入页面时显示。

    我们的webdiriver打开浏览器时,一定是个全新的浏览器,所以一般都会有这个弹窗,我们可以直接关掉,但是如果之后再到这个页面,就不会有弹窗,如果我们的脚本中还要去关,就会失败。

    针对这种情况,我们有两种解决方法,各有利弊:

        1. 使用 Run Keyword And Ignore Error这个关键字去关掉弹窗,如果下次弹窗没有出现,也会继续执行用例且不报错。缺点是如果你使用智能等待,就必须等满时间,比如20秒。

        2. 使用Reload Page来刷新当前页,由于刷新前已经记录打开页面的cookie,弹窗会直接消失。缺点是适用场景比较苛刻。

————追加部分 如何使用RFS来检查元素字体,字号,颜色等信息—————

    在Selenium2Library库中,有一个关键字大大扩展了我们能做的事,那就是Execute Javascript,用它能执行JS脚本,而通过JS脚本我们可以做很多事,比如下面的例子:


  
  1. link color check
  2. Login_HEC
  3. comment 获取创建VPC的帮助链接颜色并比较
  4. wait element xpath=//a[ text()= 'Creating a VPC']
  5. comment 通过JS获取帮助链接的颜色
  6. ${link_normal_color} Execute Javascript return window.getComputedStyle(document.evaluate( "//a[text()='Creating a VPC']", document).iterateNext()).color
  7. comment 直接和目的颜色比对
  8. should be true '${link_normal_color}'== 'rgb(0, 115, 159)'
  9. comment 获取创建VPC的帮助链接hover颜色并比较
  10. wait element xpath=//a[ text()= 'Creating a VPC']
  11. mouse over xpath=//a[ text()= 'Creating a VPC']
  12. sleep 1
  13. ${link_hover_color} Execute Javascript return window.getComputedStyle(document.evaluate( "//a[text()='Creating a VPC']", document).iterateNext()).color
  14. should be true '${link_hover_color}'== 'rgb(0, 101, 140)'

    以上只是一个简单的例子,提供一个思路,能使用的场景太多,需要各位自行探索。

——————追加部分 几个常用的扩展库———————

    除了系统自带的库BuiltIn和我们必须使用的Selenium2Library库以外,还有几个库,很多时候都能用得上:

        1. BuiltIn    ----不用引入即可使用的库,RF中控制的语句,基本都来自这里

        2. Selenium2Library    ----控制web上的操作,只能靠它

        3. AutoItLibrary    ----windows下自动化的库,可以直接控制窗口和发送动作,最常见的使用场景是上传文件或下载文件,关闭Alarm,或者我在修改了Cookie后,发送^F5来强制刷新资源等等

        4. Collections    ----这个库包括了python对数据处理的各种方法,比如Append To List或者Count Values In List等等

        5. String    ----字符串处理,你一定需要这个库

 —————追加部分 多线程执行RFS——————

    UI自动化,执行的效率不是很高,接口自动化执行100条,UI可能一条都没有执行完。为了提高执行效率,我们最常用的方法有:

        1. 尽量减少sleep的使用

        2. 减少setup和teardown的使用,资源使用要巧妙

        3. 使用多线程来跑UI自动化

    前两个是我们要不断磨练,在实战中逐渐优化的,第三个是可以立竿见影的方法

    目前在RFS上,能支持多线程的工具叫pabot,用它替换我们默认使用的pybot,可以轻易的实现UI自动化多线程,具体操作如下:

        1. 去下一个pabot:https://pypi.org/project/robotframework-pabot/   或者直接安装个:pip install robotframework-pabot

        2. 在命令行直接使用pabot --help查看支持的参数,其实常用的是以下几个:

                   --verbose     控制台输出更多信息,一般最好打开

                   --processes      并发线程数设置,也可以用这个参数,不适用的情况下,会根据你的CPU核心数调整,比如你是4核的,会开4个线程

                   --pabotlib    如果你有远程的执行机,你需要这个参数

                   --suitesfrom    每个线程去执行一个suite,所以这里给的是你存放suite的文件夹,pabot会分别装载suite并执行

                   --argumentfile    如果你的用例有需要读取的参数,通过这个可以实现

        3. 其实pabot还有个功能,在执行suite的时候,会优先加载上次有失败的,如果上次执行均成功,会按照上次执行时常的顺序加载

        4. 如果需要使用pabot,就需要解耦suite,每个suite不能互相干扰,主要两方面需要注意:资源抢占和登录

 

————————————更新实际脚本------------------------------------------

以下是华为云上我编写的脚本,可以作为参考学习,这里由于用例相对简单,所以没有做POM封装,但是基本的思路已经都有了。

代码分4个testcase的suite和一个resource,可以复制到本地试试,但是由于华为云在不断更新,可能少部分在更新后需要修改:

4个testcase的suite:


  
  1. *** Settings ***
  2. Test Teardown stopall
  3. Resource ../resource/resource.txt
  4. *** Test Cases ***
  5. TC_01_ECSUI_ECS_Create_Temp
  6. [Tags] HEC
  7. ${Fatal Error} Set Variable True
  8. Set Suite Variable ${Fatal Error}
  9. log ${Fatal Error}
  10. Wait Until Keyword Succeeds ${retry times} ${retry interval time} Create ECS Temp3
  11. Set Suite Variable ${Fatal Error} False
  12. log ${Fatal Error}
  13. [Teardown] run keyword if '${Fatal Error}'== 'True' Fatal Error Exit
  14. TC_02_ECSUI_ECS_Delete
  15. [Tags] HEC
  16. Wait Until Keyword Succeeds ${retry times} ${retry interval time} ECS Delete3

 


  
  1. *** Settings ***
  2. Test Teardown stopall
  3. Resource ../resource/resource.txt
  4. *** Test Cases ***
  5. TC_01_ECSUI_Keypair_Create
  6. [Tags] HEC
  7. Wait Until Keyword Succeeds ${retry times} ${retry interval time} Keypair Create
  8. TC_02_ECSUI_Keypair_Query
  9. [Tags] HEC
  10. Wait Until Keyword Succeeds ${retry times} ${retry interval time} Keypair Query
  11. TC_03_ECSUI_Keypair_DeleteCreate
  12. [Tags] HEC
  13. Wait Until Keyword Succeeds ${retry times} ${retry interval time} Keypair DeleteCreate
  14. TC_04_ECSUI_Keypair_Import
  15. [Tags] HEC
  16. Wait Until Keyword Succeeds ${retry times} ${retry interval time} Keypair Import
  17. TC_05_ECSUI_Keypair_DeleteImport
  18. [Tags] HEC
  19. Wait Until Keyword Succeeds ${retry times} ${retry interval time} Keypair DeleteImport
  20. TC_06_ECSUI_ECsGroup_Create
  21. [Tags] HEC
  22. Wait Until Keyword Succeeds ${retry times} ${retry interval time} ECS Group Create
  23. TC_07_ECSUI_ECsGroup_Query
  24. [Tags] HEC
  25. Wait Until Keyword Succeeds ${retry times} ${retry interval time} ECS Group Query
  26. TC_08_ECSUI_ECsGroup_Delete
  27. [Tags] HEC
  28. Wait Until Keyword Succeeds ${retry times} ${retry interval time} ECS Group Delete

 


  
  1. *** Settings ***
  2. Test Teardown stopall
  3. Resource ../resource/resource.txt
  4. *** Test Cases ***
  5. TC_08_ECSUI_ECS_Create_Temp
  6. [Tags] HEC
  7. Wait Until Keyword Succeeds ${retry times} ${retry interval time} Create ECS Temp
  8. TC_00_ECSUI_VNC_Check
  9. [Tags] HEC
  10. Wait Until Keyword Succeeds ${retry times} ${retry interval time} ECS VNC Check
  11. TC_01_ECSUI_Restart
  12. [Tags] HEC
  13. Wait Until Keyword Succeeds ${retry times} ${retry interval time} ECS Restart
  14. TC_02_ECSUI_Stop
  15. [Tags] HEC
  16. Wait Until Keyword Succeeds ${retry times} ${retry interval time} ECS Stop
  17. TC_03_ECSUI_Start
  18. [Tags] HEC
  19. Wait Until Keyword Succeeds ${retry times} ${retry interval time} ECS Start
  20. TC_04_ECSUI_Stop2
  21. [Tags] HEC
  22. Wait Until Keyword Succeeds ${retry times} ${retry interval time} ECS Stop
  23. TC_05_ECSUI_ResetPassword
  24. [Tags] HEC
  25. Wait Until Keyword Succeeds ${retry times} ${retry interval time} ECS Reset Password
  26. TC_06_ECSUI_AddTag
  27. [Tags] HEC
  28. Wait Until Keyword Succeeds ${retry times} ${retry interval time} ECS Add Tag
  29. TC_07_ECSUI_ECS_Delete
  30. [Tags] HEC
  31. Wait Until Keyword Succeeds ${retry times} ${retry interval time} ECS Delete

 


  
  1. *** Settings ***
  2. Test Teardown stopall
  3. Resource ../resource/resource.txt
  4. *** Test Cases ***
  5. TC_05_ECSUI_ECS_Create_Temp
  6. [Tags] HEC
  7. Wait Until Keyword Succeeds ${retry times} ${retry interval time} Create ECS Temp2
  8. TC_01_ECSUI_Modify Spcifications
  9. [Tags] HEC
  10. Wait Until Keyword Succeeds ${retry times} ${retry interval time} ECS Modify Specifications
  11. TC_02_ECSUI_Reinstall OS
  12. [Tags] HEC
  13. Wait Until Keyword Succeeds ${retry times} ${retry interval time} ECS Reinstall OS
  14. TC_03_ECSUI_Change OS
  15. [Tags] HEC
  16. [Setup]
  17. Wait Until Keyword Succeeds ${retry times} ${retry interval time} ECS Change OS
  18. TC_04_ECSUI_ECS_Delete
  19. [Tags] HEC
  20. Wait Until Keyword Succeeds ${retry times} ${retry interval time} ECS Delete2

一个resource:


  
  1. *** Settings ***
  2. Library Selenium2Library
  3. Library String
  4. Library DateTime
  5. *** Variables ***
  6. ${retry times} 3x
  7. ${retry interval time} 5s
  8. ${wait time} 20s
  9. ${ECS_DASHBOARD_URL} https://console.huaweicloud.com/ecm/?locale=en-us&region=cn-east -2 #/ecs/manager/dashboard
  10. ${KeypairAndEcsGroup Test Timeout} 10 minutes
  11. ${LifeCycle Test Timeout} 20 minutes
  12. ${LifeCycle2 Test Timeout} 20 minutes
  13. ${LinkCheck Test Timeout} 10 minutes
  14. ${PageCheck Test Timeout} 10 minutes
  15. ${Login Test Timeout} 5 minutes
  16. ${ECSCreateDelete Test Timeout} 40 minutes
  17. ${ is Keypair Enabled} True
  18. ${ is DEHS Enabled} True
  19. *** Keywords ***
  20. Login_HEC
  21. open browser ${ECS_DASHBOARD_URL} gc
  22. Set Window Size 1920 1080
  23. Reload Page
  24. maximize browser window
  25. ${windowsize}= get window size
  26. log ${windowsize}
  27. wait click element css= #subUserLogin
  28. wait input element xpath=//span[@id= "IAMAccountInputId"]//input|//input[contains(@placeholder, 'account')] username
  29. wait input element xpath=//span[@id= "IAMUsernameInputId"]//input|//input[contains(@placeholder, 'user name')] accountname
  30. input password xpath=//span[@id= "IAMPasswordInputId"]//input|//input[contains(@placeholder, 'password')] password
  31. wait click element id=btn_submit
  32. wait contains Quick Start Guide
  33. log url cookie
  34. stopall
  35. Run Keyword And Ignore Error log url cookie
  36. Run Keyword And Ignore Error go to https://console.huaweicloud.com/ecm/logout
  37. sleep 5s
  38. Run Keyword And Ignore Error Capture Page Screenshot
  39. Run Keyword And Ignore Error close all browsers
  40. wait element
  41. [Arguments] ${Element_LOCATOR}
  42. wait until page contains element ${Element_LOCATOR} ${wait time}
  43. Wait Until Element Is Enabled ${Element_LOCATOR} ${wait time}
  44. Wait Until Keyword Succeeds 4x 5s get scroll height ${Element_LOCATOR}
  45. run keyword if ${scroll} >= 0 scroll to ${scroll}
  46. Wait Until Element Is Visible ${Element_LOCATOR} ${wait time}
  47. #Capture Page Screenshot
  48. sleep 2
  49. get scroll height
  50. [Arguments] ${Element_LOCATOR}
  51. scroll to 0
  52. ${window-width} ${window-height}= get window size
  53. ${Vertical Position} Get Vertical Position ${Element_LOCATOR}
  54. log ${Vertical Position}
  55. ${scroll}= Evaluate ${Vertical Position}-(${window-height}/ 2)
  56. Set Suite Variable ${scroll}
  57. scroll to
  58. [Arguments] ${scroll value}
  59. Execute Javascript var q=document.documentElement.scrollTop=${scroll value}
  60. wait input element
  61. [Arguments] ${Element_LOCATOR} ${input_text}
  62. wait element ${Element_LOCATOR}
  63. input text ${Element_LOCATOR} ${input_text}
  64. wait click element
  65. [Arguments] ${Element_LOCATOR}
  66. wait element ${Element_LOCATOR}
  67. Wait Until Keyword Succeeds 3 1s click element ${Element_LOCATOR}
  68. wait mouse down up element
  69. [Arguments] ${Element_LOCATOR}
  70. wait element ${Element_LOCATOR}
  71. Selenium2Library.Mouse Down ${Element_LOCATOR}
  72. Selenium2Library.Mouse Up ${Element_LOCATOR}
  73. wait input element no scroll
  74. [Arguments] ${Element_LOCATOR} ${input_text}
  75. wait until page contains element ${Element_LOCATOR} ${wait time}
  76. Wait Until Element Is Visible ${Element_LOCATOR} ${wait time}
  77. Wait Until Element Is Enabled ${Element_LOCATOR} ${wait time}
  78. sleep 1
  79. input text ${Element_LOCATOR} ${input_text}
  80. Capture Page Screenshot
  81. wait click element no scroll
  82. [Arguments] ${Element_LOCATOR}
  83. wait until page contains element ${Element_LOCATOR} ${wait time}
  84. Wait Until Element Is Visible ${Element_LOCATOR} ${wait time}
  85. Wait Until Element Is Enabled ${Element_LOCATOR} ${wait time}
  86. sleep 1
  87. Wait Until Keyword Succeeds 3 1s click element ${Element_LOCATOR}
  88. Capture Page Screenshot
  89. wait mouse down up element no scroll
  90. [Arguments] ${Element_LOCATOR}
  91. wait until page contains element ${Element_LOCATOR} ${wait time}
  92. Wait Until Element Is Enabled ${Element_LOCATOR} ${wait time}
  93. Wait Until Element Is Visible ${Element_LOCATOR} ${wait time}
  94. Selenium2Library.Mouse Down ${Element_LOCATOR}
  95. Capture Page Screenshot
  96. Selenium2Library.Mouse Up ${Element_LOCATOR}
  97. wait contains
  98. [Arguments] ${PAGE_CONTAINS}
  99. sleep 3
  100. Capture Page Screenshot
  101. Wait Until Page Contains ${PAGE_CONTAINS} ${wait time}
  102. sleep 1
  103. Search_Common
  104. [Arguments] ${Peering_value}
  105. Wait Until Keyword Succeeds 3x 1s Search_Common_retry ${Peering_value}
  106. Search_Common_retry
  107. [Arguments] ${Peering_value}
  108. ${ is common search} Run Keyword And Return Status Wait Until Element Is Visible css=.ti-searchbox-input 5s
  109. run keyword if '${is common search}'== 'True' Common_Search ${Peering_value}
  110. run keyword if '${is common search}'!= 'True' Search_ECS_By_Name ${Peering_value}
  111. Capture Page Screenshot
  112. Search_ECS_By_Name
  113. [Arguments] ${Peering_value}
  114. wait click element css= #ecsListSearchbox
  115. wait mouse down up element no scroll xpath=//div[@id= "ecsListSearchbox_prop"]//li/span[text()= 'Name']
  116. wait input element css= #ecsListSearchbox_input ${Peering_value} #等待并输入搜索内容
  117. wait click element no scroll css= #ecsListSearchbox_search #点击搜索按钮
  118. sleep 2 #降速用,防止运行过快,也给资源搜索后的加载预留时间
  119. Common_Search
  120. [Arguments] ${Peering_value}
  121. wait input element css=.ti-searchbox-input ${Peering_value} #等待并输入搜索内容
  122. wait click element css=.ti-searchbox-search #点击搜索按钮
  123. sleep 2 #降速用,防止运行过快,也给资源搜索后的加载预留时间
  124. log url cookie
  125. ${cookies} get cookies
  126. ${url} Get Location
  127. log ${cookies}
  128. log ${url}
  129. select default EnterpriseProject
  130. wait click element css=div[select= "childrenScope.enterpriseProjectModel.select"]
  131. wait click element no scroll xpath=//li/span[text()= 'default']
  132. sleep 1
  133. close security verification
  134. comment 点击去掉二次认证
  135. Comment wait click element xpath=//label[text()= "Enable later"]
  136. Comment wait click element css=button[ng-click= "alertTipModel.okBtn.click()"]
  137. sleep 0.1
  138. verify link text
  139. [Arguments] ${verify text}
  140. wait and select new window
  141. wait contains ${verify text}
  142. Close Window
  143. select window
  144. Enter ECS Board
  145. Run Keyword And Ignore Error close all browsers
  146. Login_HEC
  147. wait click element xpath=//span[text()= 'ECSs']
  148. wait contains Operation
  149. wait contains Buy ECS
  150. Create ECS Temp
  151. Run Keyword And Ignore Error close all browsers
  152. is nearly day pass
  153. run keyword if '${is nearly day pass}'== 'True' Pass Execution is nearly day passs
  154. Create ECS Temp use Arguments ym autoui-temp1-
  155. ECS Restart
  156. Run Keyword And Ignore Error close all browsers
  157. run keyword if '${is nearly day pass}'== 'True' Pass Execution is nearly day passs
  158. Enter ECS Board
  159. comment 使用搜索唯一化ECS,点击More里的Restart重启ECS
  160. search common ${New ECS Name}
  161. wait contains Running
  162. ${Monitoring} Run Keyword And Return Status wait contains Monitoring
  163. Wait Until Keyword Succeeds 3x 1s More Restart Action
  164. Run Keyword And Ignore Error close security verification
  165. Run Keyword And Ignore Error wait until page contains element css=span.ecs_reStart 20s
  166. Wait Until Keyword Succeeds 10x 1s Check ECS Status css=span.icon-cloud-action-state-run 20s
  167. More Restart Action
  168. wait click element css=span.ti-menu-toggle-menu
  169. wait mouse down up element no scroll xpath=//li//span[text()= "Stop"]/parent::*/parent::*//span[text()= 'Restart']
  170. : FOR ${i} IN RANGE 0 3
  171. \ wait click element xpath=//span[text()= 'Yes']
  172. \ ${status}= run keyword and return status wait contains right
  173. \ log ${status}
  174. \ run keyword if '${status}' == 'True' Exit For Loop
  175. ECS Stop
  176. Run Keyword And Ignore Error close all browsers
  177. run keyword if '${is nearly day pass}'== 'True' Pass Execution is nearly day passs
  178. ECS Stop use Arguments ${New ECS Name}
  179. ECS Start
  180. Run Keyword And Ignore Error close all browsers
  181. run keyword if '${is nearly day pass}'== 'True' Pass Execution is nearly day passs
  182. Enter ECS Board
  183. comment 使用搜索唯一化ECS,点击More里的Start启动ECS
  184. search common ${New ECS Name}
  185. wait contains CentOS
  186. ${Status} get text css=td span.icon-action-state-txt
  187. log ${Status}
  188. run keyword if '${Status}'== 'Running' Capture Page Screenshot
  189. run keyword if '${Status}'== 'Stopped' Wait Until Keyword Succeeds 3x 1s More Start Action
  190. run keyword if '${Status}'== 'Stopped' Run Keyword And Ignore Error close security verification
  191. run keyword if '${Status}'== 'Stopped' Wait Until Keyword Succeeds 10x 1s Check ECS Status css=span.icon-cloud-action-state-run
  192. ... 20s
  193. More Start Action
  194. wait click element css=span.ti-menu-toggle-menu
  195. wait mouse down up element no scroll xpath=//li//span[text()= "Stop"]/parent::*/parent::*//span[text()= 'Start']
  196. : FOR ${i} IN RANGE 0 3
  197. \ wait click element xpath=//span[text()= 'Yes']
  198. \ ${status}= run keyword and return status wait contains right
  199. \ log ${status}
  200. \ run keyword if '${status}' == 'True' Exit For Loop
  201. ECS Reset Password
  202. Run Keyword And Ignore Error close all browsers
  203. run keyword if '${is nearly day pass}'== 'True' Pass Execution is nearly day passs
  204. Enter ECS Board
  205. comment 使用搜索唯一化ECS,点击More里的Reset Password更改ECS登录密码
  206. search common ${New ECS Name}
  207. wait contains Stopped
  208. Wait Until Keyword Succeeds 3x 1s More Reset Password Action
  209. wait input element css=input[meta-data-uba= "www_v1_ecs.click.ecs_list_resetPassword_confirmPassword_input"] Huawei@ 4321
  210. wait click element css=div[meta-data-uba= "www_v1_ecs.click.ecs_list_resetPassword_confirm_button"]
  211. Run Keyword And Ignore Error close security verification
  212. wait contains right
  213. More Reset Password Action
  214. wait click element css=span.ti-menu-toggle-menu
  215. wait mouse down up element no scroll xpath=//li//span[text()= "Stop"]/parent::*/parent::*//span[text()= 'Reset Password']
  216. wait input element css=input[meta-data-uba= "www_v1_ecs.click.ecs_list_resetPassword_password_input"] Huawei@ 4321
  217. ECS Add Tag
  218. Run Keyword And Ignore Error close all browsers
  219. run keyword if '${is nearly day pass}'== 'True' Pass Execution is nearly day passs
  220. Enter ECS Board
  221. Comment 使用搜索唯一化ECS,点击ECS详情后点击Tags页签,增加一个tags
  222. search common ${New ECS Name}
  223. Run Keyword And Ignore Error wait click element css=a[meta-data-uba= "www_v1_ecs.click.ecs_list_go_ecsDetail"]
  224. Run Keyword And Ignore Error wait click element css=a[meta-data-uba= "www_v1_ecs.click.ecs_list_go_new_ecsDetail"]
  225. sleep 60s
  226. wait click element xpath=//ti-tab-head[text()= 'Tags']
  227. wait click element css=div[meta-data-uba= "www_v1_ecs.click.ecs_detail_tagtable_addTag_button"]
  228. wait input element css=input[meta-data-uba= "www_v1_ecs.click.ecs_detail_addTag_key_input"] 1234
  229. wait input element css=input[placeholder= "Empty value"] 4321
  230. wait click element css=div[meta-data-uba= "www_v1_ecs.click.ecs_detail_addTag_confirm_button"]
  231. wait contains right
  232. ECS Delete
  233. Run Keyword And Ignore Error close all browsers
  234. run keyword if '${is nearly day pass}'== 'True' Pass Execution is nearly day passs
  235. ECS Delete use Arguments ym autoui-temp1
  236. Enter Key Pairs Board
  237. Run Keyword And Ignore Error close all browsers
  238. Login_HEC
  239. ${ is KMS} Run Keyword And Return Status Wait Until Page Does Not Contain Element xpath=//div[@ class="cti-res-card-title"]/span[text()='Key Pairs'] 5s
  240. run keyword if '${is KMS}'=='True' Pass Execution use KMS
  241. wait click element xpath=//div[@class="cti-res-card-title"]/span[text()='Key Pairs']
  242. wait contains Operation
  243. wait contains Create Key Pair
  244. Keypair Create
  245. Run Keyword And Ignore Error close all browsers
  246. Enter Key Pairs Board
  247. comment 点击创建key pairs按钮,创建名为KeyPair-temp,提交
  248. wait click element xpath=//span[text()='Create Key Pair']
  249. ${Random string} Generate Random String 4
  250. ${New Keypair Name} Evaluate 'KeyPair-create-temp-' + '${Random string}'
  251. Set Suite Variable ${New Keypair Name}
  252. wait input element css=input[meta-data-uba="www_v1_keypair.click.keypair_createKeypairName_button"] ${New Keypair Name}
  253. wait click element css=button[meta-data-uba="www_v1_keypair.click.keypair_createKeypair_confirm_button"]
  254. wait contains successfully
  255. Keypair Query
  256. Run Keyword And Ignore Error close all browsers
  257. Enter Key Pairs Board
  258. wait contains ${New Keypair Name}
  259. Keypair Import
  260. Run Keyword And Ignore Error close all browsers
  261. Enter Key Pairs Board
  262. comment 点击创建key pairs按钮,创建名为KeyPair-temp,提交
  263. wait click element xpath=//span[text()='Import Key Pair']
  264. ${Random string} Generate Random String 4
  265. ${New Keypair Name} Evaluate 'KeyPair-import-temp-' + '${Random string}'
  266. Set Suite Variable ${New Keypair Name}
  267. wait input element css=input[meta-data-uba="www_v1_keypair.click.keypair_importKeyPair_name_input"] ${New Keypair Name}
  268. wait input element css=textarea[meta-data-uba="www_v1_keypair.click.keypair_importKeyPair_publicKey_content"] ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDV9luoG0IvjlGbMZs8I6pVSe0HvirOiNdB8rf5moZnEp3EIuPGeewqRiCQAnRoclr1FVmxbiN6gQuznmp37GYNHdpuXIzTT4rzo+ODxFDa3d1d7jyYP5thS3oj6hCv4+6doXQ4NUQitgl0RUt9u/dRzcc0yu8BEHAbVhactBMvvWysvuOd1Urin7EA2kNTc7ez+2CzJjiTmUIXkQaDQlwj+V6EQrbfrCF6Ng1HbKVf4qcW0JvhNcikW4LVjI1yU6SnpK7VFqvqkoSL/r+yu14IWPdpDoYhFh554vlLPzO3JGdEn4zY6ych+Fk5+3j+IppONuXhipR8bEYxdig17zeZ root@13B08932-1DD2-11B2-B852-000000821800
  269. wait click element css=button[meta-data-uba="www_v1_keypair.click.keypair_importKeyPair_confirm_button"]
  270. wait contains right
  271. Keypair Delete
  272. [Arguments] ${KeyPair Name}
  273. Enter Key Pairs Board
  274. wait input element xpath=//input[@placeholder="Enter a name."] ${KeyPair Name}
  275. wait click element css=.ti-icon-search
  276. sleep 3
  277. : FOR ${i} IN RANGE 1 11
  278. \ ${Delete Status} Run Keyword And Return Status Wait Until Page Contains Element xpath=//div[@displayed-data= "$root.keypairsTable.display"]//tbody/tr[ 1]//a[text()= 'Delete'] 10s
  279. \ Run Keyword If '${Delete Status}'== 'False' Exit For Loop
  280. \ wait click element xpath=//div[@displayed-data= "$root.keypairsTable.display"]//tbody/tr[ 1]//a[text()= 'Delete']
  281. \ wait click element css=button[meta-data-uba= "www_v1_keypair.click.keypair_deleteKeypair_confirm_button"]
  282. \ wait contains right
  283. Keypair DeleteCreate
  284. Run Keyword And Ignore Error close all browsers
  285. Keypair Delete KeyPair-create-temp
  286. Keypair DeleteImport
  287. Run Keyword And Ignore Error close all browsers
  288. Keypair Delete KeyPair- import-temp
  289. Enter ECS Groups Board
  290. Run Keyword And Ignore Error close all browsers
  291. Login_HEC
  292. wait click element xpath=//span[text()= 'ECS Groups']
  293. wait contains Operation
  294. wait contains Create ECS Group
  295. ECS Group Create
  296. Run Keyword And Ignore Error close all browsers
  297. Enter ECS Groups Board
  298. comment 点击创建ECS Group按钮,创建名为KeyPair-temp,提交
  299. wait click element xpath=//span[text()= 'Create ECS Group']
  300. ${Random string} Generate Random String 4
  301. ${New Ecs Group Name} Evaluate 'SvrGrp-temp-' + '${Random string}'
  302. Set Suite Variable ${New Ecs Group Name}
  303. wait input element css=input[meta-data-uba= "www_v1_groups.click.groups_create_name_input"] ${New Ecs Group Name}
  304. ${Policy select} Run Keyword And Return Status Wait Until Page Contains Element xpath=//div[@id= "$ctrl.policyModel.elementId"] 5s
  305. run keyword if '${Policy select}'== 'True' wait click element xpath=//div[@id= "$ctrl.policyModel.elementId"]
  306. run keyword if '${Policy select}'== 'True' wait click element no scroll xpath=//li/span[contains(text(), 'Anti')]
  307. wait click element css=button[meta-data-uba= "www_v1_groups.click.groups_create_confirm_button"]
  308. wait contains right
  309. ECS Group Query
  310. Run Keyword And Ignore Error close all browsers
  311. Enter ECS Groups Board
  312. wait contains ${New Ecs Group Name}
  313. ECS Group Delete
  314. Run Keyword And Ignore Error close all browsers
  315. Enter ECS Groups Board
  316. : FOR ${i} IN RANGE 1 11
  317. \ wait input element css=.ti-searchbox-input SvrGrp-temp
  318. \ wait click element css=.ti-icon-search
  319. \ sleep 3
  320. \ ${Delete Status} Run Keyword And Return Status Wait Until Page Contains Element xpath=//tbody/tr[ 1]//a[text()= 'Delete'] 10s
  321. \ Run Keyword If '${Delete Status}'== 'False' Exit For Loop
  322. \ wait click element xpath=//tbody/tr[ 1]//a[text()= 'Delete']
  323. \ wait click element css=button[meta-data-uba= "www_v1_groups.click.groups_delete_confirm_button"]
  324. \ wait contains right
  325. Enter Create Vm Page
  326. Run Keyword And Ignore Error close all browsers
  327. Enter ECS Board
  328. wait click element xpath=//span[text()= 'Buy ECS']
  329. wait contains vCPUs
  330. Enter Dedicated Host Page
  331. Run Keyword And Ignore Error close all browsers
  332. Login_HEC
  333. ${ is KMS} Run Keyword And Return Status Wait Until Page Does Not Contain Element xpath=//div[@ class="cti-res-card-title"]/span[text()='DeHs'] 5s
  334. run keyword if '${is KMS}'=='True' Pass Execution No DEHs
  335. wait click element xpath=//div[@class="cti-res-card-title"]/span[text()='DeHs']
  336. wait contains Buy DeH
  337. Enter ECS Detail Page
  338. Enter ECS Board
  339. search common ecs-autoui-preset
  340. wait click element css=a[meta-data-uba="www_v1_ecs.click.ecs_list_go_new_ecsDetail"]
  341. wait contains ECS Information
  342. Dashbord Creating an ECS
  343. Run Keyword And Ignore Error close all browsers
  344. Login_HEC
  345. wait click element xpath=//a[text()='Creating an ECS']
  346. verify link text ECS
  347. Dashbord Creating a Disk
  348. Run Keyword And Ignore Error close all browsers
  349. Login_HEC
  350. wait click element xpath=//a[text()='Creating a Disk']
  351. verify link text Disk
  352. Dashbord Assigning an EIP
  353. Run Keyword And Ignore Error close all browsers
  354. Login_HEC
  355. wait click element xpath=//a[text()='Assigning an EIP']
  356. verify link text EIP
  357. Dashbord Configuring a Key Pair
  358. Run Keyword And Ignore Error close all browsers
  359. Login_HEC
  360. wait click element xpath=//a[text()='Configuring a Key Pair']
  361. verify link text Key Pair
  362. Dashbord Learnmore
  363. Run Keyword And Ignore Error close all browsers
  364. Login_HEC
  365. wait click element xpath=//p/a[text()='Learn more']
  366. verify link text ECS
  367. Dashbord Here
  368. Run Keyword And Ignore Error close all browsers
  369. Login_HEC
  370. wait click element css=a[meta-data-uba="www_v1_dec.click.dashboard_cloudWatch_here_link"]
  371. verify link text Alarm
  372. Dashbord Outer Link
  373. Run Keyword And Ignore Error close all browsers
  374. Login_HEC
  375. wait contains Cloud Backup and Recovery
  376. wait contains Cloud Server Backup Service
  377. wait contains Volume Backup Service
  378. wait contains Elastic Load Balance
  379. wait contains Elastic IP
  380. wait contains Security Group
  381. ECS VNC Check
  382. Run Keyword And Ignore Error close all browsers
  383. run keyword if '${is nearly day pass}'=='True' Pass Execution is nearly day passs
  384. Enter ECS Board
  385. comment 使用搜索唯一化ECS,点击远程登录后检查css=canvas#noVNC_canvas是否出现
  386. search common ${New ECS Name}
  387. wait contains Running
  388. wait click element xpath=//a[text()='Remote Login']
  389. Run Keyword And Ignore Error wait click element css=*[meta-data-uba="www_v1_hecs.click.lightserver_list_hiShellLogin_linux_vnclogin"]
  390. wait and select new window
  391. sleep 10
  392. ${iframe} Get Matching Xpath Count //iframe
  393. run keyword if '${iframe}'!='0' select frame css=#vnc
  394. wait element css=#noVNC_screen
  395. ECS Modify Specifications
  396. Run Keyword And Ignore Error close all browsers
  397. ECS Stop2
  398. Enter ECS Board
  399. Search_common ${New ECS Name}
  400. Wait Until Keyword Succeeds 3x 1s More Modify Specifications Action
  401. sleep 10
  402. wait click element css=.cti-buyLayer-btns-item
  403. wait click element xpath=//input[@meta-data-uba="www_v1_ecs.click.ecs_list_modifySpec_confirm_protocol_checkbox"]/following-sibling::label/span/span
  404. wait click element xpath=//span[text()= 'Submit Application']
  405. wait until page contains element xpath=//div[@ class="cti-wizard-content ng-hide"] ${wait time}
  406. select window
  407. Reload page
  408. Search_common ${ New ECS Name}
  409. Run Keyword And Ignore Error Check ECS Status Resizing 20 s
  410. Wait Until Keyword Succeeds 10 x 1 s Check ECS Status css= span. ecs_shutOff 30 s
  411. More Modify Specifications Action
  412. wait click element css= span. ti- menu- toggle- menu
  413. wait mouse down up element no scroll xpath=// span[ text()=' Reset Password']/ parent::*/parent::*//span[text()= 'Modify Specifications']
  414. wait and select new window
  415. close new select old
  416. [Documentation] 关键字动作:
  417. ... 关闭新打开的窗口,返回主窗口
  418. ...
  419. ... 参数:
  420. ... 无
  421. ...
  422. ... 设计思路:
  423. ... 如果点击链接后打开新浏览器,操作完后需要返回主浏览器,即可使用此关键字
  424. close window #关闭当前浏览器窗口
  425. select window #选择主浏览器窗口
  426. ECS Stop2
  427. ECS Stop use Arguments ${New ECS Name}
  428. ECS Stop use Arguments
  429. [Arguments] ${ECS NAME}
  430. Enter ECS Board
  431. comment 使用搜索唯一化ECS,点击More里的Stop关闭ECS
  432. search common ${ECS NAME}
  433. wait contains CentOS
  434. ${Status} get text css=td span.icon-action-state-txt
  435. log ${Status}
  436. run keyword if '${Status}'== 'Stopped' Capture Page Screenshot
  437. run keyword if '${Status}'== 'Running' Wait Until Keyword Succeeds 3x 1s More Stop Action
  438. run keyword if '${Status}'== 'Running' Run Keyword And Ignore Error close security verification
  439. run keyword if '${Status}'== 'Running' Wait Until Keyword Succeeds 10x 1s Check ECS Status css=span.ecs_shutOff
  440. ... 20s
  441. More Stop Action
  442. wait click element css=span.ti-menu-toggle-menu
  443. wait mouse down up element no scroll xpath=//li//span[text()= "Stop"]/parent::*/parent::*//span[text()= 'Stop']
  444. : FOR ${i} IN RANGE 0 3
  445. \ wait click element xpath=//span[text()= 'Yes'] #要执行的循环操作
  446. \ ${status}= run keyword and return status wait contains right
  447. \ log ${status}
  448. \ run keyword if '${status}' == 'True' Exit For Loop
  449. ECS Reinstall OS
  450. Run Keyword And Ignore Error close all browsers
  451. ECS Stop2
  452. Enter ECS Board
  453. Search_common ${New ECS Name}
  454. Wait Until Keyword Succeeds 3x 1s More Reinstall OS Action
  455. wait input element css=input[meta-data-uba= "www_v1_ecs.click.ecs_list_reinstallOs_password_input"] Huawei@ 1234
  456. wait input element css=input[meta-data-uba= "www_v1_ecs.click.ecs_list_reinstallOs_confirmPassword_input"] Huawei@ 1234
  457. wait click element css=div[meta-data-uba= "www_v1_ecs.click.ecs_list_reinstallOS_confirm_button"]
  458. wait and select new window
  459. wait click element css=.ti-checkbox-inner
  460. wait click element css=.cti-buyLayer-btns-item
  461. wait until page contains element xpath=//div[@ class="cti-wizard-content ng-hide"] ${wait time}
  462. select window
  463. Wait Until Keyword Succeeds 10 x 1 s Check ECS Status css= span. icon- cloud- action- state- run 20 s
  464. More Reinstall OS Action
  465. wait click element css= span. ti- menu- toggle- menu
  466. Run Keyword And Ignore Error mouse over xpath=// span[ text()=' Manage Image/ Disk']
  467. wait mouse down up element no scroll xpath=// li/ span[ text()=' Modify Specifications']/ parent::*/parent::*//span[text()= 'Reinstall OS']
  468. wait click element xpath=//button[text()= 'Password']
  469. ECS Change OS
  470. Run Keyword And Ignore Error close all browsers
  471. ECS Stop2
  472. Enter ECS Board
  473. Search_common ${New ECS Name}
  474. Wait Until Keyword Succeeds 3x 1s More Change OS Action
  475. sleep 10
  476. ${Current Image OS}= get text css=span[ng-bind= "metadata.image_name"]
  477. wait click element css= #osPlatform
  478. wait click element no scroll xpath=//span[text()= 'CentOS']
  479. wait click element css= #osImageModel
  480. run keyword if '${Current Image OS}'== 'CentOS 7.5 64bit' wait click element no scroll xpath=//span[contains(text(), 'CentOS 7.4')]
  481. run keyword if '${Current Image OS}'!= 'CentOS 7.5 64bit' wait click element no scroll xpath=//span[contains(text(), 'CentOS 7.5')]
  482. wait click element xpath=//button[text()= 'Password']
  483. wait input element css=input[meta-data-uba= "www_v1_ecs.click.ecs_list_changeOS_password_input"] Huawei@ 1234
  484. wait input element css=input[meta-data-uba= "www_v1_ecs.click.ecs_list_changeOS_confirm_password_input"] Huawei@ 1234
  485. wait click element css=div[meta-data-uba= "www_v1_ecs.click.ecs_list_changeOS_confirm_button"]
  486. wait and select new window
  487. wait click element css=.ti-checkbox-inner
  488. wait click element css=.cti-buyLayer-btns-item
  489. wait until page contains element xpath=//div[@ class="cti-wizard-content ng-hide"] ${wait time}
  490. select window
  491. Wait Until Keyword Succeeds 10 x 1 s Check ECS Status css= span. icon- cloud- action- state- run 20 s
  492. More Change OS Action
  493. wait click element css= span. ti- menu- toggle- menu
  494. Run Keyword And Ignore Error mouse over xpath=// span[ text()=' Manage Image/ Disk']
  495. wait mouse down up element no scroll xpath=// li/ span[ text()=' Change OS']
  496. wait element css=# osPlatform
  497. Check ECS Status
  498. [ Arguments] ${ status Loc} ${ WaitTime}
  499. wait click element css= div[ meta- data- uba=" www_v1_ecs. click. ecs_list_refresh_ecs_button"]
  500. sleep 2
  501. wait until page contains element ${ status Loc} ${ WaitTime}
  502. Capture Page Screenshot
  503. ECS Delete use Arguments
  504. [ Arguments] ${ ECS Name}
  505. Enter ECS Board
  506. comment 使用搜索唯一化 ECS,点击 More里的 Delete删除 ECS
  507. Search_Common_Mulit ${ ECS Name}
  508. sleep 3 s
  509. wait click element xpath=// table/ thead/ tr// span[@ class=" ti- checkbox- inner"]
  510. wait click element xpath=// div[@ class=" ti- button- select- wrapper ng- scope ng- isolate- scope"]
  511. wait mouse down up element no scroll xpath=// span[ text()=' Modify Bandwidth']/ parent::*/parent::*//span[text()= 'Delete']
  512. wait click element xpath=//div[@ class="delete_all_confirm clearfix"]/div[1]//span/span
  513. wait click element xpath=// div[@ class=" delete_all_confirm clearfix"]/ div[2]// span/ span
  514. Capture Page Screenshot
  515. wait click element css= div[ meta- data- uba=" www_v1_ecs. click. ecs_list_delete_confirm_button"]
  516. wait contains right
  517. Capture Page Screenshot
  518. Wait Until Keyword Succeeds 10 x 1 s Check page not contains ${ New ECS Name} 10 s
  519. Check page not contains
  520. [ Arguments] ${ text} ${ WaitTime}
  521. wait click element css= div[ meta- data- uba=" www_v1_ecs. click. ecs_list_refresh_ecs_button"]
  522. sleep 2
  523. Wait Until Page Does Not Contain ${ text} ${ WaitTime}
  524. Capture Page Screenshot
  525. More Delete Action
  526. wait click element css= span. ti- menu- toggle- menu
  527. wait mouse down up element no scroll xpath=// li// span[ text()=" Stop"]/ parent::*/parent::*//span[text()= 'Delete']
  528. wait click element css=div[meta-data-uba= "www_v1_ecs.click.ecs_list_delete_confirm_button"]
  529. ECS Delete2
  530. Run Keyword And Ignore Error close all browsers
  531. ECS Delete use Arguments autoui-temp2
  532. Create ECS Temp use Arguments
  533. [Arguments] ${ECS Name}
  534. Enter ECS Board
  535. comment 点击创建ECS按钮
  536. wait click element xpath=//span[text()= 'Buy ECS']
  537. sleep 20
  538. comment 选择按需,系统和对应版本,并点击下一步
  539. wait click element xpath=//button[text()= 'Pay-per-use']
  540. wait click element css= #osPlatform
  541. sleep 10
  542. wait click element no scroll xpath=//span[text()= 'CentOS']
  543. wait click element css=div.secondGoldImageSelectEn
  544. wait click element no scroll xpath=//span[text()= 'CentOS 7.5 64bit(40GB)']
  545. wait click element css=.cti-btn-container
  546. comment 选择VPC(使用搜索进行筛选),选择不需要EIP,并点击下一步
  547. wait click element css=span[placeholder= "--Select VPC--"]
  548. Comment wait input element no scroll css=div[ class="ti-dropdown-container ng-isolate-scope ti-dropdown-container-down"] input vpc-ecs-preset-do-not-delete
  549. wait click element no scroll xpath=// span[ text()=' vpc- ecs- preset- do- not- delete( 192.168.0.0/16)']
  550. wait element xpath=// div/ span[ text()=' Automatically- assigned IP address']
  551. wait click element xpath=//*[ text()=' Not required']
  552. wait click element xpath=// span[ text()=' Next: Configure Advanced Settings ']
  553. comment 输入ECS名字和密码,并点击下一步
  554. ${Random string} Generate Random String 4
  555. ${New ECS Name} Evaluate '${ECS Name} ' + '${Random string} '
  556. Set Suite Variable ${New ECS Name}
  557. wait input element css=#ecsHostName input[type="text"] ${New ECS Name}
  558. wait click element xpath=//button[text()='Password ']
  559. wait input element css=input[meta-data-uba="www_v1_ecs.click.ecs_create_login_password_input"] Huawei@1234
  560. wait input element css=input[meta-data-uba="www_v1_ecs.click.ecs_create_login_confirmPassword_input"] Huawei@1234
  561. Run Keyword And Ignore Error wait click element xpath=//button[text()='Not required ']
  562. wait click element xpath=//span[text()='Next: Confirm ']
  563. comment 选择default企业项目,并提交,断言成功关键字,并点击返回VM列表,断言列表有创建的ECS
  564. Run Keyword And Ignore Error select default EnterpriseProject
  565. wait click element xpath=//*[contains(text(),'I have read and agree ')]/parent::*/label
  566. wait click element xpath=//span[text()='Next ']
  567. wait contains Request submitted successfully
  568. comment 点击返回ECS列表页,刷新寻找Running状态的新建ECS主机
  569. wait click element css=div[options="goEcsListBtn"]
  570. Search_common ${New ECS Name}
  571. Wait Until Keyword Succeeds 10x 1s Check ECS Status css=span.icon-cloud-action-state-run 20s
  572. Create ECS Temp2
  573. Run Keyword And Ignore Error close all browsers
  574. Create ECS Temp use Arguments autoui-temp2-
  575. Search_Common_Mulit
  576. [Arguments] ${Peering_value}
  577. ${is common search} Run Keyword And Return Status Wait Until Element Is Visible css=.ti-searchbox-input 5s
  578. run keyword if '${ is common search} '==' True ' Common_Search ${Peering_value}
  579. run keyword if '${ is common search} '!=' True ' Search_ECS_By_Name ${Peering_value}
  580. Capture Page Screenshot
  581. wait contains right
  582. sleep 3
  583. Capture Page Screenshot
  584. Wait Until Page Contains Element css=div[style="float:right;"] ${wait time}
  585. sleep 1
  586. wait and select new window
  587. sleep 3s
  588. select window new
  589. Create ECS Temp use Arguments ym
  590. [Arguments] ${ECS Name}
  591. Enter ECS Board
  592. comment 点击创建ECS按钮
  593. wait click element xpath=//span[text()='Buy ECS ']
  594. sleep 20
  595. comment 选择按需,系统和对应版本,并点击下一步
  596. wait click element xpath=//button[text()='Yearly/Monthly ']
  597. wait click element css=#osPlatform
  598. sleep 10
  599. wait click element no scroll xpath=//span[text()='CentOS ']
  600. wait click element css=div.secondGoldImageSelectEn
  601. wait click element no scroll xpath=//span[text()='CentOS 7.5 64bit( 40GB) ']
  602. wait click element css=.cti-btn-container
  603. comment 选择VPC(使用搜索进行筛选),选择不需要EIP,并点击下一步
  604. wait click element css=span[placeholder="--Select VPC--"]
  605. Comment wait input element no scroll css=div[class="ti-dropdown-container ng-isolate-scope ti-dropdown-container-down"] input vpc-ecs-preset-do-not-delete
  606. wait click element no scroll xpath=//span[text()='vpc-ecs-preset-do- not-delete( 192.168 .0 .0/ 16) ']
  607. wait element xpath=//div/span[text()='Automatically-assigned IP address ']
  608. wait click element xpath=//*[text()='Not required ']
  609. wait click element xpath=//span[text()='Next: Configure Advanced Settings ']
  610. comment 输入ECS名字和密码,并点击下一步
  611. ${Random string} Generate Random String 4
  612. ${New ECS Name} Evaluate '${ECS Name} ' + '${Random string} '
  613. Set Suite Variable ${New ECS Name}
  614. wait input element css=#ecsHostName input[type="text"] ${New ECS Name}
  615. wait click element xpath=//button[text()='Password ']
  616. wait input element css=input[meta-data-uba="www_v1_ecs.click.ecs_create_login_password_input"] Huawei@1234
  617. wait input element css=input[meta-data-uba="www_v1_ecs.click.ecs_create_login_confirmPassword_input"] Huawei@1234
  618. Run Keyword And Ignore Error wait click element xpath=//button[text()='Not required ']
  619. wait click element xpath=//span[text()='Next: Confirm ']
  620. comment 选择default企业项目,并提交,断言成功关键字,并点击返回VM列表,断言列表有创建的ECS
  621. Run Keyword And Ignore Error select default EnterpriseProject
  622. wait click element xpath=//*[contains(text(),'I have read and agree ')]/parent::*/label
  623. wait click element xpath=//span[text()='Next ']
  624. Wait Until Page Contains Element xpath=//*[@id='balance_totalpay ']|//*[@id='tab_monthend_balance_totalpay2 '] 200s
  625. wait click element xpath=//*[@id='monthEndConfirm ']|//*[@id='tabMonthEndConfirm ']
  626. wait contains Payment processed successfully
  627. comment 点击返回ECS列表页,刷新寻找Running状态的新建ECS主机
  628. go to ${ECS_DASHBOARD_URL}
  629. wait click element xpath=//span[text()='ECSs ']
  630. wait contains Operation
  631. wait contains Buy ECS
  632. Search_common ${New ECS Name}
  633. Wait Until Keyword Succeeds 10x 1s Check ECS Status css=span.icon-cloud-action-state-run 20s
  634. ECS Delete use Arguments ym
  635. [Arguments] ${ECS Name}
  636. Enter ECS Board
  637. comment 使用搜索唯一化ECS,点击More里的Delete删除ECS
  638. Search_Common_Mulit ${ECS Name}
  639. sleep 3s
  640. wait click element xpath=//table/thead/tr//span[@class="ti-checkbox-inner"]
  641. wait click element xpath=//div[@class="ti-button-select-wrapper ng-scope ng-isolate-scope"]
  642. wait mouse down up element no scroll xpath=//span[text()='Modify Bandwidth ']/parent::*/parent::*//span[text()='Unsubscribe ']
  643. wait click element css=button[meta-data-uba="www_v1_ecs.click.ecs_list_unsubscribe_confirm_button"]
  644. sleep 3s
  645. select window new
  646. sleep 20s
  647. wait click element //tr[@ng-if="isRetreatUsingRes"]//label[@class="ti-checkbox"]
  648. wait click element css=#retreat_btn
  649. wait click element css=#confirm_btn
  650. Capture Page Screenshot
  651. wait contains submitted
  652. Capture Page Screenshot
  653. select window
  654. Wait Until Keyword Succeeds 40x 10s Check page not contains ${New ECS Name} 20s
  655. is nearly day pass
  656. Set Suite Variable ${is nearly day pass} False
  657. log ${is nearly day pass}
  658. ${now date} Get Current Date
  659. log ${now date}
  660. ${20min later date} Add Time To Date ${now date} 20m
  661. log ${20min later date}
  662. ${now date converted} Convert Date ${now date} datetime
  663. ${20min later date converted} Convert Date ${20min later date} datetime
  664. log ${now date converted}
  665. log ${20min later date converted}
  666. log ${now date converted.day}
  667. log ${20min later date converted.day}
  668. run keyword if '${now date converted.day} '!='${ 20min later date converted.day} ' Set Suite Variable ${is nearly day pass} True
  669. log ${is nearly day pass}
  670. Fatal Error Exit
  671. stopall
  672. #Fatal Error
  673. ECS Delete3
  674. Run Keyword And Ignore Error close all browsers
  675. run keyword if '${ is nearly day pass} '==' True ' Pass Execution is nearly day passs
  676. ECS Delete use Arguments ym autoui-temp3
  677. Create ECS Temp3
  678. Run Keyword And Ignore Error close all browsers
  679. is nearly day pass
  680. run keyword if '${ is nearly day pass} '==' True ' Pass Execution is nearly day passs
  681. Create ECS Temp use Arguments ym autoui-temp3-

    ———————————结语————————————

    其实本文还可以继续扩展,比如参数化的使用,tag的使用,用例结构化等等,但是本文的目的是授之以渔,这些就让大家自己来解决吧。

    后面也许根据情况,我会编写高级篇,主要内容可能会是自定义Library的编写和使用,也许因为玩katalon导致没有高级篇。

    总之感谢各位能看完我这絮絮叨叨的文章。


转载:https://blog.csdn.net/qq_27534003/article/details/87524779
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场