HTTP接口自动化测试方法研究

2017-01-05 13:17

  杨清玉,李金丽,陈吉兰,李志伟

  (中标软件有限公司 操作系统测试认证中心,北京 100190)

       摘要:研究了HTTP接口自动化测试方法,采用Python语言开发代码,使用Request调用HTTP接口。提出了一种分层结构的自动化测试框架,将接口调用、测试用例和测试数据的代码分层开发,生成基于HTML的测试报告。提出了两种解决CSRF Token验证问题的方案。该方法开发出的自动化测试脚本具有结构清晰、易维护等优点,能够有效提高测试效率,降低测试成本。

  关键词:HTTP接口;Python;Request;自动化测试

0引言

 Web业务日趋复杂,系统愈加庞大,版本的发布周期变短,使得Web产品测试的难度极大地提高,工作量也大幅增加[1]。Web产品的测试中非技术性、重复性的测试工作占总的测试工作量比例比较大,因而需要大量的资源来保障Web产品的质量[2 3]。在开发Web产品时,开发过程中一般采用了分层的软件体系结构,Web页面通过HTTP协议向接口发送请求,后端处理请求返回结果。由于业务逻辑比较复杂,有着大量的接口,如果使用自动化测试代替手工测试,可以有效提高测试效率,降低测试成本。

1HTTP协议

  超文本传输协议(Hyper Text Transfer Protocol, HTTP)是互联网上应用最为广泛的一种网络协议。HTTP是基于请求和响应模式的无状态应用层协议。其客户/服务器模式的信息交换过程如图1所示。信息交换过程分四个部分:建立连接、发送请求信息、发送响应信息和关闭连接[4]。

图像 001.png

  绝大多数的Web开发都是构建在HTTP协议之上的Web应用。本文所进行的自动化测试的对象为中标软件有限公司的微云操作系统产品,该产品的Web接口为HTTP协议的接口。针对该接口的自动化测试,笔者采用Python语言进行代码的开发,使用Request进行HTTP接口的调用。使用Eclipse并安装PyDev插件作为集成开发环境,在自动化测试框架下开发自动化测试代码。

2Python和Request

  Python是一个通用目的的编程语言,已经有很多年的发展历程。这个稳定而成熟的语言是非常高层的、动态的、面向对象的和跨平台的。Python可以在所有主流的硬件平台和操作系统上运行。它继承了传统编译语言的强大性和通用性,同时也借鉴了简单脚本和解释语言的易用性,语法简捷清晰、可读性强、便于维护,并且具有一致性和规律性、丰富的标准库,以及许多可以很容易在Python中使用的第三方模块。Python还可以被当做最适合入门程序员掌握的优秀语言,因为它免费、面向对象、扩展性强,同时执行严格的编码标准[5]。

  Request对象的作用是与客户端交互,收集客户端的Form、Cookies、超链接,或者收集服务器端的环境变量。Request对象是从客户端向服务器发出请求,包括用户提交的信息以及客户端的一些信息。客户端可通过HTML表单或在网页地址后面提供参数的方法提交数据,然后通过Request对象的相关方法来获取这些数据。Request的各种方法主要用来处理客户端浏览器提交的请求中的各项参数和选项。

3自动化测试框架介绍

  3.1自动化测试框架设计思想

  本文设计的自动化测试框架采用分层结构,依据模块化、可复用、低冗余等原则,将代码根据不同的功能分为若干个独立的模块,这里将一类模块称为一层。每一层都完成自己特定的任务,各层之间根据需要去进行调用。分层思想最先是在软件开发过程中提出来的。当代码量小的时候,采用这种模式会增加工作量;但是当代码量变大时,采用这种模式可以使设计思路清晰,代码冗余度变低,可扩展性更好,代码维护更加方便,程序运行效率更高。

  3.2自动化测试框架实现

  自动化测试框架是由一个或多个自动化测试基础模块、自动化测试管理模块、自动化测试统计模块等组成的工具集合。本文的自动化测试框架如图2所示,分为测试环境配置层、接口操作层、测试数据层、测试用例层、测试用例管理层等。每一层都实现自己特定的功能,并提供接口给其他层调用。

图像 002.png

  Config层:测试环境配置层,存储测试环境相关设置参数。比如待测环境的IP、主机名、登录用户名、密码等。

  TestAPI层:接口操作层,对HTTP接口的调用进行封装。比如获取列表信息、添加、删除、修改等。

  TestData层:测试数据层,用于管理测试用例所需要用到的测试数据。Data文件的名称需要与对应的Test Case名称一致,以便数据解析。

  TestCase层:测试用例层,每一个TestCase类均采用单元测试框架来构造,即每一个TestCase均继承于unittest.testcase类。在实际的设计中,通过继承unittest.testcase类,重写并加入一些方法,从而形成了一个名为BaseTestCase的父类,全部的TestCase的类均继承自这个父类。

  TestSuite层:测试用例管理,包括测试用例执行的级别、每种测试级别对应的测试用例集以及日志记录级别。

  HTMLTestRunner层:测试报告管理模块,用于生成测试报告,这个报告是基于HTML的,方便浏览和统计。

  TestCenter层:测试管理层,是整个测试程序的入口。它实现了解析并找出需要执行的测试用例,执行测试用例脚本,并生成测试结果。

4测试代码开发

  在具体的测试代码开发过程中,主要编写TestAPI层、TestCase层和TestData层的代码。下面详细介绍这三层代码开发的模式。

  4.1TestAPI层

  这一层主要进行HTTP接口的调用。为了实现对接口的调用,首先,需要从项目组获取图3所示的接口说明。如果项目组没有完整的接口说明文档,可以结合firebug获取。需要在Firefox浏览器中安装firebug插件,启用插件后,在浏览器上所进行的操作会被记录下来。

图像 003.png

  然后,编写代码调用HTTP接口。下面以添加用户的HTTP接口调用代码为例进行说明。

  def addWebUser(self, data):

  url=self.base_url+"Web_users/"

  data=json.dumps(data)

  r=requests.post(url=url,data=data,

  headers=self.headers, verify=self.verify)

  return {'status_code':r.status_code,

  'result':json.loads(r.text)}

  由于实际测项目中HTTP接口接收的参数格式和返回的信息是json格式,因此需要导入json模块,并在调用接口前,使用json.dumps将参数转换成json格式,对返回信息使用json.loads转换成字典格式,以便后续使用。

  4.2TestCase层

  TestCase层用于存放编写的测试用例,调用TestAPI层的方法。可以将TestCase层与实际的测试用例对应起来。当接口发生变化时,只需修改TestAPI中的代码,而基本不需要修改或者只需要对TestCase层代码进行很少量的修改。每一个测试用例用一个类表示,且均继承自同一个父类BaseTestCase;而BaseTestCase则继承自unittest.testcase类,所以,TestCase类均具有unittest.testcase类的属性。在BaseTestCase类中定义了每个测试用例开始执行和结束时的动作以及一些case中用到的公共方法。

  TestCase类的代码包含四个部分:数据和实例初始化、测试环境准备、实际测试代码、资源回收。代码结构如下。

  class ITC_EditUser_LegalName(BaseTestCase):

  ′′′

  @summary:编辑用户-用户名合法

  ′′′

  def setUp(self):

  #第一部分——数据和实例初始化

  #调用父类方法,获取该用例所对应的测试数据模块

  self.user=super(self.__class__, self).setUp()

  self.user_api=UserAPIs()

  self.flag = True

  # 第二部分——测试环境准备

  #添加用户

  self.user_api.addUser(self.user.add_user)

  def test_EditUser_LegalName(self):

  #第三部分——实际测试代码

  #编辑用户

  def tearDown(self):

  #第四部分——用例执行结束后的资源回收

  #删除用户

  self.user_api.deleteUser(data)

  4.3TestData层

  测试数据文件均存放在TestData层。每一个测试用例对应的测试数据文件均以.py格式的文件存在,且文件名与测试用例名(TestCase层中的类名)相对应。下面以添加用户的测试数据文件进行说明。测试数据以变量的形式存在,其中XML格式的内容便于Python装饰器的使用。

  add_user={

  "name":"abcd",

  "password":"qwer1234"

  }

  xml_user_name = ′′′

  <data_driver>

  <user>

  <name>abcd</name>

  </user>

  <user>

  <name>ABCDEFG</name>

  </user>

  </data_driver>

  ′′′

5自动化测试执行

  5.1测试用例管理

  测试用例管理使用XML文件以及对应的解析代码来实现。测试用例执行的级别可以根据项目需要设置为全用例集、BVT用例集、模块级用例集、特定用例集等。每种测试级别使用对应的XML文件进行配置和管理。日志级别包括显示所有日志信息、只显示错误和警告日志信息、显示调试信息等。

  下面以模块级用例集的XML配置文件为例进行说明。module name为模块名称,description为对该模块的功能描述,filename为该模块对应的测试用例脚本存放的文件名称,run为执行标志,如果为True表示执行,如果为False表示不执行。

  <?xml version="1.0" encoding="UTF-8"?>

  <modules>

  <module name="User" id="01">

  <description>用户</description>

  <filename>User.py</filename>

  <run>True</run>

  </module>

  </modules>

  5.2测试报告生成

  测试报告采用unittest单元测试库扩展的HTMLTestRunner.py,可以生成HTML的自动化测试报告。使用方法如下面代码所示。

  fp=file(result_file, 'wb')

  runner=HTMLTestRunner(

  stream=fp,

  title=u"中标麒麟微云操作系统V2.0-HTTP接口自动化测试报告",

  description=(

  u"中标麒麟微云操作系统V2.0-HTTP接口自动化测试报告\\n"

  u'测试执行方式:%s' % exec_type

  )

  自动化测试执行完成后,会在指定的目录下生成测试报告。报告中显示测试报告名称、测试起始时间、测试时长、状态(包括通过用例数、失败用例数、错误用例数),显示测试用例列表,可以展开显示测试用例日志详情,测试通过的用例绿色显示,失败的用例橙色显示,错误的用例(一般是测试脚本有问题)红色显示,以便后续可以区分查看和分析。

6CSRF Token验证问题解决

  跨站请求伪造(Crosssite Request Forgery,CSRF)是一种对网站的恶意利用。由于目标站无token/referer限制,导致攻击者能以用户的身份完成操作,达到各种目的。

  为了提高Web的安全性,有些Web在提交Ajax请求时需要CSRF Token验证。如何在调用HTTP接口的头信息中设置正确的Cookie值,成为自动化测试HTTP接口的难点。笔者在实际项目测试中提出了两种解决方案,这两种方案都需要结合Firefox浏览器。

  6.1通过Firefox浏览器获取

  在Firefox浏览器中安装firebug插件,启用firebug。手动登录待测Web页面。查看firebug中登录操作的【网络】 【XHR】 【头信息】 【响应头信息】 【SetCookie】的内容。

  脚本流程图如图4所示。使用该方法由于需要模拟用户进行浏览器登录操作,因此需要导入selenium.Webdriver模块。

图像 004.png

  6.2通过Logout接口和Login接口获取

  在Firefox浏览器上先手动登录再退出待测Web页面。查看Firebug中退出操作的【网络】 【XHR】 【头信息】 【请求头信息】 【Cookie】的内容。

  脚本流程图如图5所示。该方法相对于通过Firefox浏览器获取的方法,效率更高。

7结论

  本文研究了HTTP接口自动化测试方法,采用Python语言开发代码,使用Request调用HTTP接口。提出了一种分层结构的自动化测试框架,将接口调用、测试用例和测试数据的代码分层开发,生成基于HTML的测试报告,方便浏览和统计。提出了两种解决CSRF Token验证问题的方案,并在实际项目中进行了应用。该自动化测试方法 开发出的自动化脚本结构清晰,容易维护,有效提高了测试效率,降低了测试成本。

图像 005.png

  参考文献

  [1] 王会青,冯秀芳. Web应用软件测试方法的研究[J]. 太原理工大学学报,2007, 38(4):54 57.

  [2] 瑁静,钟亦平,张世永. 基于协议分析的自动化Web性能测试[J]. 计算机工程,2005, 31(7):66 69.

  [3] WASSERMANN G, Yu Dachuan, CHANDER A. Dynamic test input ceneration for Web apllications[J]. ISST’08, July, 2008:20 24.

  [4] DOUGLAS E, COMER, DAVID L, 等. 用TCP/IP进行网际互连(第1卷)第4版[M].林瑶,蒋慧,杜蔚轩,译.  北京:电子工业出版社,1998.

  [5] CHUN W J. Python核心编程(第2版)[M]. 宋吉广,译. 北京:人民邮电出版社,2008.