+ 首页>>技能>>内容

技能python-telnetlib实现底层自动化交互和常规采集500+次围观

我们不止一次讨论过关于非GUI的自动化测试,但是在我们遇到的更多自动化测试需求中,”GUI操作加非GUI调试”的场景反而更加多见。面对这个较为复杂的问题,直觉告诉我们以下两件事情:

  • 有没有现成工具?有,EasyTest等
  • 自行开发如何?理论上肯定可以

正好前段时间为公司某产品的底层测试写了一个小工具,为其命名:PySuperPrint,利用Python内置库telnetlib,基本上可以完美实现telnet下的自动化测试,且交互过程快速稳定。来看一下我的代码Gist:

# -*- coding:utf-8 -*-

'''
Nothing Here......
'''

import telnetlib,time,threading,os

#定义异常类,从Exception基类继承,重写__str__
class telnetException(Exception):

    #异常类构造方法
    def __init__(self,host,errcode,errmsg,logintype):
        self.host=host
        self.errcode=errcode
        self.errmsg=errmsg
        self.logintype=logintype

    #返回的异常信息
    def __str__(self):
        return "<%s 到 %s 主机时发生错误,错误码 %s,错误信息:%s>" % (self.logintype,self.host,self.errcode,self.errmsg)

# 连接类,支持Telnet,SSH
class Klogintype(object):

    # 默认采用telnet连接,可以在实例化的时候直接给定该参数
    def __init__(self,logintype='telnet',kconobj=telnetlib.Telnet()):
        self.logintype=logintype
        self.kconobj=kconobj

    # telnet4000登陆调试方法
    def KtelnetCon(self,host,port,username,password):

        try:
            self.kconobj.open(host,port)
            self.kconobj.read_until("Username:")
            self.kconobj.write(username+"\r\n")
            self.kconobj.read_until("Password:")
            self.kconobj.write(password+"\r\n")

        except:
            print telnetException(host,300,"服务器未响应",self.logintype)

    #23端口登陆方法
    def KtelnetCon23(self,host,port,username,password):

        try:
            self.kconobj.open(host,port)
            #self.kconobj.read_until("nvr1825 login: ")
            self.kconobj.expect(['.*login: '],5)
            self.kconobj.write(username+"\r\n")
            self.kconobj.read_until("Password: ")
            self.kconobj.write(password+"\r\n")

        except:
            print telnetException(host,300,"服务器未响应",self.logintype)


    #发送前置字符方法
    def Ksendfstr(self,forwardstr):

        #发送命令前查找前置字符
        self.kconobj.expect([forwardstr],5)


    #命令交互
    def Ktelnetsbc(self,commandname,forwardstr):

        #发送命令参数
        self.kconobj.write(commandname+"\r\n")
        msg=self.kconobj.read_until(forwardstr)

        #解决中文乱码
        print msg.decode('gbk')


    #实时打印方法,可做采集用,默认采集到文本中
    def KtelnetRpp(self,commandname,logpath):

        self.kconobj.write(commandname+"\r\n")
        fileHandle=open(logpath,'w+')
        while self.kconobj.read_some():
            time.sleep(10)

            #非阻塞方式读取
            klog=self.kconobj.read_very_eager()

            print klog #debug

            #写入日志
            fileHandle.write(klog)

        fileHandle.close()

    #关闭通道方法
    def kcloseme(self):
        self.kconobj.close()


#定义一个采集类,从Thread类中继承
class Kcollection(threading.Thread):
    def __init__(self,commandname,logpath):
        #调用父类构造方法
        threading.Thread.__init__(self)
        self.commandname=commandname
        self.logpath=logpath

    def run(self):
        k=Klogintype()
        k.KtelnetRpp(self.commandname,self.logpath)

#定义一个菜单
def showmenu():

    print ('''

    *************** 常用信息快速查看 ***************

    1.查看XXX版本信息
    2.查看XXXXX信息

    **************** 自动化/采集任务/打印自动捕获 *************

    14.执行vmstat性能参数采集(默认规则,关注bi,bo,si,so,cpu分布)
    15.查看网口相关信息,丢包情况等
    16.执行批量采集任务,多线程采集不同设备(vmstat)
    17.清理采集日志


    ''' )


if __name__=="__main__":

    #显示菜单
    showmenu()
    userinput=raw_input("请输入你要执行的操作选项:")

    #必要的实例化
    k=Klogintype()
    k.KtelnetCon('172.16.114.93',4000,'admin','admin123')

    k.Ksendfstr("nvr->")

    while not userinput:
        userinput=raw_input("请务必输入一个选项:")
    else:
        #提交主体命令区域,显示一些常用信息
        elif userinput=='13':
            k.Ktelnetsbc('somecommand',"nvr->")
        elif userinput=='14':
            #采集任务需要重新初始化,Debug,一般用批量采集
            k.KtelnetCon23('172.16.114.93',23,'admin','kedacomIPC')
            k.Ksendfstr('admin@nvr.*:~$')
            t=Kcollection('vmstat 1',r'C:\KSuperPrint-Log.txt')
            t.start()
            print "成功启动一个采集线程: %s | 状态:正在运行中......" % t.name

        elif userinput=='16':
            #执行批量采集任务
            iplists=raw_input("请输入批量采集设备的IP地址,用英文逗号隔开:")

            for ip in iplists.split(','):

                k=Klogintype()
                k.KtelnetCon23(ip,23,'admin','kedacomIPC')
                k.Ksendfstr("admin@nvr.*:~$")
                t=Kcollection('vmstat 1',r'C:\KSuperPrint-Log-'+ip+".txt")
                t.start()
                print "成功启动一个采集线程: %s | 状态:正在运行中......" % t.name
        elif userinput=='17':
                pass

代码片段仅供参考。
这里解释一下我没有用pexpect模块的原因,pexpect是Python下极为强大的一个实现自动化交互的模块,支持telnet,ssh等协议,但是pexpect只适用于unix-platform,对于在win上的调试没有目前来讲没有更好的解决方案。
回到文章开头我们探讨的那个话题,假如我们需要在GUI自动化中跟telnet进行交互,这时候可以采用一种比较巧妙的办法,就是封装一个py给自动化框架用,给出一个简单的例子:

# -*- coding:utf-8 -*-

'''
执行环境 Python2.X
作者:Archer
版本:1.0 Beta
'''

__author__ = 'Archer'

import telnetlib,sys

# 定义Kteldebug函数,默认gbk解码
def Kteldebug(ip,navpromot,command,port=17230,decodetype='gbk',timeout=30):

    #创建一个对象引用,创建调试连接
    Ktelnet=telnetlib.Telnet(ip,port=port,timeout=timeout)

    #等待前置字符出现
    Ktelnet.read_until(navpromot)

    if not isinstance(command,str):

        return "命令行格式有误,请重新输入"

    else:

        #最后发送\r\n相当于某些COM组件的sendline
        Ktelnet.write(command+'\r\n')

        #返回服务器响应的值,调用解码格式
        return Ktelnet.read_until(navpromot).decode(decodetype)


if __name__=="__main__":

    print Kteldebug(sys.argv[1],sys.argv[2],sys.argv[3])

这样我们在自动化框架中通过执行系统命令就可在cmd中返回我们想要的调试信息,然后我们就可以自由处理这些我们想要的信息了。

python Ktelnetdbg.py "xx.xx.xx.xx" "->" "version"

从上面第一段Gist中我们可以看到很多telnetlib的优秀特性,包括正则表达式匹配buffer等,欢迎各位继续深入挖掘。

Github Gist

https://gist.github.com/qddegtya/8121370

+ 猜你喜欢...

===== 关于 DiggerPlus =====
DiggerPlus是国内新锐测试人垂直内容博客,专注于挖掘测试工具,普及测试技术,专注于测试人能力提升,博客上线后就受到广大测试人的热烈追捧;此外,DiggerPlus深度整合评测资源,揭秘科技数据和真相,让读者更懂科技,更好地把玩科技。 我们始终保持"独立,客观,严谨,优秀"的优良作风,努力为读者带来源源不断的优质内容。想访问更多酷毙的测试人网站?赶紧来DiggerPlus测试人网址导航看看吧!

===== DiggerPlus Team =====
DiggerPlus Team是DiggerPlus官方发起的团队,这是一群热爱科技,热爱测试,喜欢深度挖掘的热血测试人,他们是评测师,测试专家。 我们欢迎优秀的测试人加入DiggerPlus Team。 加入DiggerPlus,可以成为我们的认证Dper,认证Dper拥有DiggerPlus独一无二的专栏并得到个人展示。

===== DiggerPlus 官方读者群 =====
DiggerPlus官方读者群(一)

+ 关于本文作者

Python/C/C++/Javascript程序员,持续学习者,目前专注于前端开发。

的专栏 | 专栏作者 | 访问小A的主页

+ 已有1个评论

Copyright © 2014 DiggerPlus. 91 queries in 2.176 seconds.
使用合作网站账号快速登录,更多精彩等着您: 开源中国