自动化进化论之“完结篇”

发表于:2019-4-26 08:16

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:测试女巫    来源:51Testing软件测试网原创

  终于到了这一系列的最后一期,每一次真的比较纠结,因为工作实在太忙了,每一次都纠结是不是要放弃,每一次又坚持了下来,为自己打个Call,其实这个系列真的非常有意义,记录了我从只会作黑盒测试的正宗黑盒测试人员,慢慢的有了具备开发协助黑盒测试的自动化工具,这个工具从被别人鄙视“搞什么搞”的低级阶段渐渐发展成有班长,成规模,让别人觉得“有点样子”的中级阶段,再到这次真的有了界面,一个真的有模有样,让别人可以另眼相看的阶段,这个期间的痛并快乐着的感受,真的只有经历的人才会知道。但是大家千万不要以为这个完结篇就代表了女巫目前的工作level,这个“完结篇”是2016年的“完结篇”,因为从2016年做了这个完结篇,真的主管才真的重视我们的自动化工具,然后从2017年开始,真的黑盒测试任务渐渐变少,到2019年真的几乎已经没有了黑盒测试任务,自动化工作反而成了工作的重点,所以真觉得还挺神奇的,几年前的非本职工作,被别人在质疑搞什么搞得自动化,现在变成了主业,真的很多时候你不去努力一把,你不知道自己有多厉害哈哈。
  好吧,心路历程总结完毕,我们真的可以开始介绍我们的工具,我们的工具
  比较厉害,有了界面,这个界面是用C++实现,我们是在C++中调用Python脚本的方式来实现我们的自动化
  一、如何配置C++与Python结合编程的编程环境
  1.Python的资料Copy
  首先将Python安装目录下的Libs和include文件copy下来,如下图
  2.VS端的设置
  VS需要创建一个MFC的项目,这里就不再赘述,之前的C++已经叙述过如何创建,创建完毕请注意
  1)运行的模式如果选择debug Mode如下图
  a.需要将Python的Include和Libs copy到我们建立的C++ project的路径下,如下图
  b.Include文档的配置,选择项目->属性->C/C++的”一般”->其它include 目录选择a 中copy的include所在的路径
  c.Libs 配置依赖项路径
  选择项目->属性->连接器->一般->其它程式库目录,如下图:
  d.在Debug中运行,需要设置依赖项
  首先需要在libs文件夹下的Python27.lib复制一个,并将其名称改为python27_d.lib,如下图
  然后到选择项目->属性->连接器->输入路径下,将python27_d.lib设置到“其它相依性”此栏位中,如下图
  e.配置“先行编译标头档”
  需要选择“未使用先行编译表头档”如下图:
  2)运行模式如果选择Release Mode如下图
  除了不需要设置依赖项即步骤d,其它与选择Debug一样
  3)例子说明:
  下面的例子即为可以编译成功的例子
  二、Python C++ API 的学习
  1.资料来源:地址
  Python的官网:Https://docs.python.org/2/c-api/index.html
  注意选择的是Python 2.7.11这个与我们安装的Python的版本一样:我们安装的就是Python27。如【图1】
  【图1】
  2.具体的Topic
  Python/C API Reference Manual
  此Topic中一共有10个分类,建议不要每个分类都看,因为其中的信息量太大了,可以以实现的功能为中心,选择性的学习这些接口函数。
  10个分类分别是:Introduction;The very High Level Layer;Reference
  Counting;Exception Handing;Utilities;Abstract;Concrete Objects
  Layer;Initialization, Finalization,
  3.常用接口函数
  1)Initialization, Finalization and Threads
  Void Py_Initialize (void)
  初始化Python解释器,在一个内嵌Python的应用软件中,在调用其它的API函数前,必须要调用此函数。此函数没有参数,没有返回值,且如果初始化失败就会出现致命的失败。
  Int Py_IsInitalized()
  判断是否初始化成功,如果成功返回值是True(非0)否则为False(0);此函数没有参数。
  Py_Finalize()
  取消所有的Py_Initialize()此函数做的初始化,且摧毁所有已经做过的初始化。此函数没有参数,没有返回值
  2)The very High Level Layer
  此分类主要是执行一个文档或者缓冲区中的源代码
  PyRun_SimpleString(const char *command)
  它是PyRun_SimpleStringFlags(const char *command PyCompiler *flags)的简化版,即只需要提供一个参数即可,这句命令的意思是执行Python中的一段代码。
  PyObject *PyEval_CallObject(PyObject*pfunc,PyObject*pargs)
  第一个参数是Module中需要调用的函数,是通过此函数获得PyObject_GetAttrString(此函数在下面会讲到) pargs是函数的参数列表,通常Py_BuildValue(char*format,……)来构建。
  Int PyRun_AnyFile(FILE *fp, const char *filename)
  该API的作用是运行名称为filename的python脚本
  3)Concrete Objects Layer
  这个分类主要是明确特定的某些Python的对象类型,传送一个对象必须需要搞清楚它是什么类型,同样如果你接收一个对象必须知道这个对象是什么类型的,如果不知道首先需要check它是什么类型的,例如如果希望确认这个对象是否为字典类型,则需要使用PyDict_Check()这个函数。这个章节就是讲述Python对象类型的结构图
  Python对象类型主要分为基本的对象,数字类型对象,序列类型对象,映射类型对象,其它对象
  序列类型对象中的String/Bytes 对象类型
  这些对象包含的函数,如果获得的参数不是string类型的参数,则会返回一个TypeError的错误。
  PyObject* PyString_FromString(const char *v)
  将参数中的字串常量转成一个字串对象。
  Module Objects
  PyObject * PyModule_GetDict(PyObject *module)
  返回一个字典类型的对象,此对象包含模块名称。此对象与模块对象的__dict__属性是相同的。这个函数不会fail,如没有会返回
  File Objects
 PyObject* PyFile_FromString(char *filename,char *mode)
  返回一个打开的文件类型的Python对象,该对象的打开方式由mode指定,mode的取值同C语言的函数fopen():

 FILE* PyFile_AsFile(PyObject *p)
  将与p相关联的文件对象作为FILE指针
  4)Import Modules
  PyObject *PyImport_ImportModule(const char *name)
  导入一个Python模块,参数Name可以是“.py”文件的文件名,类似Python内建函数Import
  注意:参数是const char类型,即调用时直接写PyImport_ImportModule("candpython")即可,candpython就是需要调用的模块的名称即“.py”文件的文件名称。
  PyObject*PyImport_Import(PyObject *name)
  作用与上面函数一样,但是注意其需要传进来的参数是PyObject类型,不是简单的char类型,所以需要将模块名称使用
  PyString_FromString(const char *v)转换成PyObject类型才可以使用这个函数,这两个函数Mary均做过实现,可以实现相同功能
  5)Object Protocol
  PyObject *PyObject_GetAttrString(PyObject*o, const char *attr_name )
  两个参数,第一个参数是导入“. py ”的module 对象,第二个参数是此module对象中的字串,这个函数的意义是获得此Module中的函数名称字串,并将此字串转成Object类型。
  Int PyObject_HasAttr(PyObject *o,PyObject *attr_name)
  两个参数,第一个参数是导入“. py ”的module 对象,第二个参数是此module对象中的字串,这个函数的意义是确认Module中是否有attr_name此字串
  注意:这个函数传进去的第二个参数为Object所以如果使用这个函数,需要先将字串类型转成object类型。
  如果能找到,返回值为1否则为0,注意无论是否能找到,这个函数总是执行成功的,不会有错误的现象产生。
  6)Int PyObject_HasAttrstring(PyObject*o, const char *attr_name )
  与2)都一样,唯一不同的是传入的第二个参数是Const char类型,不需要将其转成Object。
  三、代码例子
  1、不需要传入参数的简单Python内嵌例子
  说明:
  1)初始化Py_Initialize();
  2)直接运行Python的代码,这段代码的意思就是添加当前的路径
   PyRun_SimpleString(“import sys”)
  PyRun_SimpleString("sys.path.append('./')");
  3)载入一个名字叫candpython的脚本
   pName=PyString_FromString("candpython");
  pModule =PyImport_ImportModule("candpython");
  4)运行candpython的脚本中的函数
   pFunc=PyObject_GetAttrString(pModule,"getlog");
  PyEval_CallObject(pFunc,NULL);
  5)结束初始化 Py_Finalize();
  2.需要传入参数的Python内嵌例子之较为复杂的实现
  与不需要传入参数一样的内容不再赘述。
  1)首先创建一个元组类型,元组的大小是2
  2)将参数从C可以理解的内容转成Python可以读懂的内容
  3)将此两个参数插入到一个元组对象中
  4)调用此函数以及函数的参数即可

  3.需要传入参数的Python内嵌例子之较为简单的实现
  1)将C能理解数据翻译成Python能读懂的对象类型
  注意这里是将两个参数直接翻译,并没有一个一个的翻译
  2)调用函数以及此函数的两个参数
  4.Python返回值传回给C++
  该Python脚本执行的是一个加法运算,先从控件获得加数和被加数,将其转换为Python对象并传给Python脚本,执行脚本后得到结果,再将此结果转换为C++数据类型回传给C++,并在控件中显示。
  该脚本Python脚本执行的是at command的压力测试,先从控件获得COM口,将其转换为Python对象传给Python脚本,执行完脚本后,得到测试总次数,Pass次数和Fail次数,再将此结果转换为C++数据类型回传给C++,并在控件中显示。由于需要转换的Python对象有多个,所以此处用的是int PyArg_ParseTuple(PyObject *args, const char *format,…)
  5.运行Python脚本
  运行脚本使用PyRun_AnyFile(FILE *fp, const char *filename),为了得到FILE指针,需要先将Python脚本以只读方式打开并转换为Python对象,再将其转换为FILE指针,
  四、实际项目说明
  1.简单例子
  Atcommand2.exe就是C++的执行档案,承担的是界面的工作
  Atgpioreq2.py是界面中调用的脚本

  其实点击“确认”按键就是让下面的脚本执行,这样看起来是不是漂亮很多!
  2.较漂亮的例子
  如果你觉得上面的界面太简单了,看一下以下的例子:
  一个非常漂亮的两个界面,其中汇集了边界测试,压力测试,而且考虑到每个项目需要将一些参数开放出来给使用者使用,对于使用者非常方便,需要测试什么项目,选择什么项目,根据项目的情况设置具体的参数,然后直接点击run就可以自动执行python的脚本,真的很酷!

  这一系列告一段落,这个系列对于女巫的职业生涯真的意义非凡,对于别人的冷嘲热讽,只要内心够坚持,每天都在进步,日积月累真的就会产生奇妙的结果,当我们把这个有界面的测试工具拿出来时,老板就开始慢慢减少我们team的黑盒测试工作,直到现在几乎没有黑盒测试工作,还要感谢那些质疑我们搞什么搞得同事,虽然他们依然还在做着一成不变的工作……所以还是那句话:路漫漫其修远兮,吾将上下而求索……加油!

     ......
查看更多精彩内容,请点击下载:
http://www.51testing.com/html/18/n-4458218.html
版权声明:本文出自《51测试天地》第五十三期。51Testing软件测试网及相关内容提供者拥有51testing.com内容的全部版权,未经明确的书面许可,任何人或单位不得对本网站内容复制、转载或进行镜像,否则将追究法律责任。
《2023软件测试行业现状调查报告》独家发布~

精彩评论

  • 王承庆
    2019-4-28 10:13:50

    最后这个“虽然他们依然还在做着一成不变的工作……”感受到了你的嘲讽,嘿嘿嘿

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号