首先,介绍一下robotframework,oschina这么介绍:html
Robot Framework 是一个关键词驱动的自动测试框架。测试用例位于HTML或者TSV(以tab分隔值)文件,使用在测试库中实现的关键词来在测试中运行程序。由于 Robot Framework 是灵活和可扩展的,因此它很合适用于测试具备多种接口的复杂软件:用户接口,命令行,webservice,编程接口等。node
Robot Framework 和 Cumcumber http://www.oschina.net/p/cucumber 具备类似的能力,都属于BDD自动化测试工具。 可是Cumcumber只能顺序验证测试步骤,好比:python
Given 我在登陆页 When 我输入账号"zhangsan" And 我输入密码"123456" And 我点击登陆按钮 Then 我能看到个人昵称"张三"
上述的 "我在登陆页" 等步骤的定义,都在Cumcumber的step_definitions.rb中,用ruby语言定义。
若是对Cumcumber测试安卓手机APP感兴趣,能够参阅 使用calabash测试开源中国Android客户端mysql
Robot Framework在语义级别就提供了FOR循环和IF判断,自定义Keyword直接在.robot文件中,不须要写一句Python语句。linux
而后再去官网 http://robotframework.org/ ,到TestLibraries看看都提供了什么测试库:nginx
STANDARD库中包含OperatingSystem,String,Collections,提供了调用本地shell命令,字符串处理,和Python集合的处理能力。git
EXTERNAL库中有手机APP测试相关的测试库、网页测试相关、http测试相关、数据库相关、ssh相关。github
我最看中的就是其中SSHLibrary,它提供ssh登陆和执行远程命令的能力,并能用sftp上传下载文件。
SSHLibrary对python库paramiko进行了封装,因此他是Farbric的兄弟,Fabric经常使用于自动化运维,可是缺乏对运维结果的检测能力。web
因此,Robot Framework+SSHLibrary天生就适合作网站的自动化运维质量检测。sql
后面经过一个一个的小例子,来演示Robot Framework+SSHLibrary怎样达到自动化运维质量检测
Python默认已安装
pip: python环境下模块安装工具
sudo apt-get install python-pip
python-dev: 某些python模块安装须要Python.h,因此要安装python-dev
sudo apt-get install python-dev
robotframework: http://robotframework.org
sudo pip install robotframework
若是使用默认pip源很慢,能够指定豆瓣的pip源:
sudo pip install robotframework -i http://pypi.douban.com/simple
SSHLibrary: https://github.com/robotframework/SSHLibrary
pip install robotframework-sshlibrary
只要把Debian对应安装命令中的apt-get 改为yum, dev改为devel Python默认已安装
pip: python环境下模块安装工具
sudo yum install python-pip
python-devel: 某些python模块安装须要Python.h,因此要安装python-devel
sudo yum install python-devel
robotframework: http://robotframework.org
sudo pip install robotframework
SSHLibrary: https://github.com/robotframework/SSHLibrary
pip install robotframework-sshlibrary
示例来自: http://robotframework.org/SSHLibrary/
注意:
测试用例文件:
shen@debian:~/robotframework$ cat executing-commands.robot *** Settings *** Documentation This example demonstrates executing commands on a remote machine ... and getting their output and the return code. ... ... Notice how connections are handled as part of the suite setup and ... teardown. This saves some time when executing several test cases. Library SSHLibrary Suite Setup Open Connection And Log In Suite Teardown Close All Connections *** Variables *** ${HOST} localhost ${USERNAME} shen ${PASSWORD} 123456 *** Test Cases *** Execute Command And Verify Output [Documentation] Execute Command can be used to ran commands on the remote machine. ... The keyword returns the standard output by default. ${output}= Execute Command echo Hello SSHLibrary! Should Be Equal ${output} Hello SSHLibrary! Execute Command And Verify Return Code [Documentation] Often getting the return code of the command is enough. ... This behaviour can be adjusted as Execute Command arguments. ${rc}= Execute Command echo Success guaranteed. return_stdout=False return_rc=True Should Be Equal ${rc} ${0} Executing Commands In An Interactive Session [Documentation] Execute Command always executes the command in a new shell. ... This means that changes to the environment are not persisted ... between subsequent Execute Command keyword calls. ... Write and Read Until variants can be used to operate in the same shell. Write cd .. Write echo Hello from the parent directory! ${output}= Read Until directory! Should End With ${output} Hello from the parent directory! *** Keywords *** Open Connection And Log In Open Connection ${HOST} Login ${USERNAME} ${PASSWORD}
gedit打开executing-commands.robot的效果:
执行结果:
shen@debian:~/robotframework$ pybot executing-commands.robot ============================================================================== Executing Commands :: This example demonstrates executing commands on a rem... ============================================================================== Execute Command And Verify Output :: Execute Command can be used t... | PASS | ------------------------------------------------------------------------------ Execute Command And Verify Return Code :: Often getting the return... | PASS | ------------------------------------------------------------------------------ Executing Commands In An Interactive Session :: Execute Command al... | PASS | ------------------------------------------------------------------------------ Executing Commands :: This example demonstrates executing commands... | PASS | 3 critical tests, 3 passed, 0 failed 3 tests total, 3 passed, 0 failed ============================================================================== Output: /home/shen/robotframework/output.xml Log: /home/shen/robotframework/log.html Report: /home/shen/robotframework/report.html
为了能方便演示,每一个例子都有各编号如100,对应的代码目录~/robotframework/100 上述基本ssh例子先简化以下:
shen@debian:~/robotframework/100$ cat example-100.robot *** Settings *** Documentation ssh示例 Library SSHLibrary Suite Setup Open Connection And Log In Suite Teardown Close All Connections *** Variables *** ${HOST} localhost ${USERNAME} shen ${PASSWORD} 123456 *** Test Cases *** 远程执行命令并检验输出 ${output}= Execute Command echo Hello SSHLibrary! Should Be Equal ${output} Hello SSHLibrary! *** Keywords *** Open Connection And Log In Open Connection ${HOST} Login ${USERNAME} ${PASSWORD}
说明: 上述检验内容是ssh到localhost,执行shell命令: echo Hello SSHLibrary!
,
应该看到stdout为 Hello SSHLibrary!
下面用手工执行ssh来模拟上述检验:
在使用if判断变量output时,碰到了单引号和双引号的替换规则问题,并且bash的if-else-fi真心难写。
只有下面if中的单双引号使用是正确的:
if [ "$output" == 'Hello SSHLibrary!' ]; then echo -e "| \033[32mPASS\033[0m |"; else echo -e "| \033[31mFAIL\033[0m |"; fi
回到正题,我想在pybot命令行直接输入ssh密码,能够这样执行:
由于输入的是错误密码,因此提示: Authentication failed for user 'shen'.
规则1: pybot命令行中输入的变量值会覆盖robot文件中*** Variables ***
中定义的变量值
上面的example-100.robot运行时,屏幕上只打印了testcase名称和测试结果绿色PASS或红色FAIL。
在运行目录下生成了3个文件:output.xml, log.html, report.html,先分别打开看看:
我不习惯去看html文件,因此我想在运行时直接打印output变量的内容。
先去官网找到Log To Console的帮助信息: http://robotframework.org/robotframework/latest/libraries/BuiltIn.html#Log%20To%20Console
官网帮助中的robotframework测试用例格式都是表格,可是最实用的是txt格式,测试用例文件的后缀能够是.txt或.robot
表格格式的分隔方式就是一个一个格子,txt格式对应分隔符是两个以上空格或者一个以上Tab。
shen@debian:~/robotframework/110$ cat example-110.robot *** Settings *** Documentation ssh示例 Library SSHLibrary Suite Setup Open Connection And Log In Suite Teardown Close All Connections *** Variables *** ${HOST} localhost ${USERNAME} shen ${PASSWORD} 123456 *** Test Cases *** 远程执行命令并检验输出 ${output}= Execute Command echo Hello SSHLibrary! Log To Console \n\${output}的内容:"\x1b[1;33m${output}\x1b[0m" Should Be Equal ${output} Hello SSHLibrary! *** Keywords *** Open Connection And Log In Open Connection ${HOST} Login ${USERNAME} ${PASSWORD}
请注意新增行:
Log To Console \n\${output}的内容:"\x1b[1;33m${output}\x1b[0m"
执行测试结果:
说明: \x1b[1;33m${output}\x1b[0m 是以高亮黄色打印变量${output}的内容。\x1b与echo打印彩色时的\033是相同的。
可是robotframework测试用例文件的语法中不支持\0nn八进制,只支持\xnn 十六进制。 Log To Console右边必须先输入两个以上空格或1个以上Tab,再输入变量;两个变量之间也要如此分隔。
规则2: robotframework测试用例文件中字符$要用$转义,\xnn指定十六进制字符。
首先看一下pybot的-h帮助: 执行命令: pybot -h
,其中的-v参数能够指定一个变量的值,-V能够从一个文件中指定多个变量。
shen@debian:~/robotframework/120$ cat node-list.py SSH_SERVERS = ['node01', 'node02', 'node03'] NODE_IP_MAP = { 'node01':'localhost', 'node02':'127.0.0.1', 'node03':'192.168.0.107', } shen@debian:~/robotframework/120$ cat example-120.robot *** Settings *** Documentation ssh示例 Library Collections Library SSHLibrary Suite Teardown Close All Connections *** Variables *** *** Test Cases *** 远程执行命令并检验输出 :FOR ${node} IN @{SSH_SERVERS} \ ${node_ip}= Get From Dictionary ${NODE_IP_MAP} ${node} \ Log To Console \n正在登陆 ${node}(${node_ip}) ... \ Open Connection And Log In "${node_ip}" \ Log To Console \n正在${node}(${node_ip})执行命令: echo Hello SSHLibrary! \ ${output}= Execute Command echo Hello SSHLibrary! \ Log To Console \n\${output}的内容:"\x1b[1;33m${output}\x1b[0m" \ Should Be Equal ${output} Hello SSHLibrary! *** Keywords *** Open Connection And Log In "${node_ip}" Open Connection ${node_ip} Login ${USERNAME} ${PASSWORD}
请注意例子120的几处新内容:
shen@debian:~/robotframework/130$ cat node-list.py PYTHON_SERVERS = ['node01', 'node03'] SSH_SERVERS = ['node01', 'node02', 'node03'] NODE_IP_MAP = { 'node01':'localhost', 'node02':'127.0.0.1', 'node03':'192.168.0.107', } shen@debian:~/robotframework/130$ cat versions.py VERSIONS = { 'python':'2.7.3', 'gcc':'4.7.2', 'ssh':'OpenSSH_6.0p1', } shen@debian:~/robotframework/130$ cat example-130.robot *** Settings *** Documentation ssh示例 Library Collections Library SSHLibrary Suite Teardown Close All Connections *** Variables *** *** Test Cases *** 远程执行命令并检验输出 :FOR ${node} IN @{SSH_SERVERS} \ ${node_ip}= Get From Dictionary ${NODE_IP_MAP} ${node} \ Log To Console \n正在登陆 ${node}(${node_ip}) ... \ Open Connection And Log In "${node_ip}" \ Log To Console \n正在${node}(${node_ip})执行命令: echo Hello SSHLibrary! \ ${output}= Execute Command echo Hello SSHLibrary! \ Log To Console \n\${output}的内容:"\x1b[1;33m${output}\x1b[0m" \ Should Be Equal ${output} Hello SSHLibrary! 检查python版本 :FOR ${node} IN @{PYTHON_SERVERS} \ ${node_ip}= Get From Dictionary ${NODE_IP_MAP} ${node} \ Open Connection And Log In "${node_ip}" \ Log To Console \n正在${node}(${node_ip})执行命令: python --version 2>&1 | cut -d' ' -f 2 \ ${output}= Execute Command python --version 2>&1 | cut -d' ' -f 2 \ ${version}= Get From Dictionary ${VERSIONS} python \ Log To Console \npython版本${output} == 指望版本${version} ? \ Should Be Equal ${output} ${version} *** Keywords *** Open Connection And Log In "${node_ip}" Open Connection ${node_ip} Login ${USERNAME} ${PASSWORD}
执行测试命令:
pybot -v USERNAME:shen -v PASSWORD:123456 -V node-list.py -V versions.py example-130.robot
若是更改指望版本为2.6.6:
shen@debian:~/robotframework/130$ cat versions.py VERSIONS = { 'python':'2.6.6', 'gcc':'4.7.2', 'ssh':'OpenSSH_6.0p1', }
测试结果以下:
由于测试用例“检查python版本”中的第一个结点的python版本检查断言:Should Be Equal ${output} ${version}
失败,
因此robotframework直接退出本测试用例的执行,不会再去检查第二个结点的python版本。
shen@debian:~/robotframework/140$ cat example-140.robot *** Settings *** Documentation 交互式检查python版本 Library Collections Library SSHLibrary Suite Teardown Close All Connections *** Variables *** *** Test Cases *** 交互式检查python版本 :FOR ${node} IN @{PYTHON_SERVERS} \ ${node_ip}= Get From Dictionary ${NODE_IP_MAP} ${node} \ Open Connection And Log In "${node_ip}" \ Write python \ ${output}= Read Until >>> \ Log To Console \n${node}(${node_ip})执行命令python的输出:---\n${output}\n--- \ ${version}= Get From Dictionary ${VERSIONS} python \ Log To Console \n${node}(${node_ip})的python版本 == ${version} ? \ Should Contain ${output} ${version} *** Keywords *** Open Connection And Log In "${node_ip}" Open Connection ${node_ip} Login ${USERNAME} ${PASSWORD}
执行测试结果:
shen@debian:~/robotframework/150$ cat keywords.robot *** Settings *** Library Collections Library SSHLibrary *** Keywords *** Check Python Version "${servers}" "${version}" :FOR ${node} IN @{servers} \ ${node_ip}= Get From Dictionary ${NODE_IP_MAP} ${node} \ Open Connection ${node_ip} \ Login ${USERNAME} ${PASSWORD} \ Write python \ ${output}= Read Until >>> \ Log To Console \n${node}(${node_ip})执行命令python的输出:---\n${output}\n--- \ Log To Console \n${node}(${node_ip})的python版本 == ${version} ? \ Should Contain ${output} ${version} shen@debian:~/robotframework/150$ cat example-150.robot *** Settings *** Documentation 交互式检查python版本 Resource keywords.robot Suite Teardown Close All Connections *** Variables *** *** Test Cases *** 交互式检查python版本 ${version}= Get From Dictionary ${VERSIONS} python Check Python Version "${PYTHON_SERVERS}" "${version}" *** Keywords *** shen@debian:~/robotframework/150$ pybot -v USERNAME:shen -v PASSWORD:123456 -V node-list.py -V versions.py example-150.robot ============================================================================== Example-150 :: 交互式检查python版本 ============================================================================== 交互式检查python版本 . node01(localhost)执行命令python的输出:--- Python 2.7.3 (default, Mar 13 2014, 11:03:55) [GCC 4.7.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> --- node01(localhost)的python版本 == 2.7.3 ? node03(192.168.0.107)执行命令python的输出:--- Python 2.7.3 (default, Mar 13 2014, 11:03:55) [GCC 4.7.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> --- node03(192.168.0.107)的python版本 == 2.7.3 ? 交互式检查python版本 | PASS | ------------------------------------------------------------------------------ Example-150 :: 交互式检查python版本 | PASS | 1 critical test, 1 passed, 0 failed 1 test total, 1 passed, 0 failed ============================================================================== Output: /home/shen/robotframework/150/output.xml Log: /home/shen/robotframework/150/log.html Report: /home/shen/robotframework/150/report.html shen@debian:~/robotframework/150$
复用example-150的测试用例
pybot -C on -v USERNAME:shen -v PASSWORD:123456 -V node-list.py -V versions.py example-150.robot | tee ../160/color_output.txt
欢迎你们继续提出问题,我将尽力以上述example的方式给出答案。