接口测试:应用稳定和安全的护航者
作者: 金琦
编者按:随着互联网技术的飞速发展,Web应用和移动端应用成为人们日常生活中不可或缺的一部分,同时越来越多的企事业单位信息系统开始依赖Web接口进行数据交换和业务流程的整合,而随之而来的是对接口测试和接口安全的需求日益增长。接口测试保证了接口在被集成到业务系统前达到预期操作和输出,并暴露潜在的故障和错误,提高业务系统的可靠性和稳定性,接口安全则是确保业务系统的安全性和可信度的重要手段。本期我们解释了接口测试的基本概念,并体验了一组接口测试的操作实例,以期对接口测试技术有一些感性的认识。
当今在软件开发中,接口测试已经成为不可或缺的一部分,与其他测试类型相比,接口测试具有独特的地位和作用。它主要关注系统各个模块之间的交互,通过验证这些接口是否按照规范进行数据传递和交互,来判断系统是否能够正常运行。与功能测试、性能测试等测试类型相比,接口测试更注重测试中间件、API等底层组件,其测试粒度更细,能够发现其他测试类型无法发现的问题和风险。学校的信息系统也非常需要完善的接口测试,从而确保系统的稳定性和可靠性。
接口测试是指对系统中各组件之间的接口进行测试,以确保它们能够正确地集成和协作,并满足预期的功能和性能要求。接口测试是一种黑盒测试方法,独立于系统的内部实现细节,主要关注输入和输出之间的交互行为。接口测试是软件开发过程中非常重要的一环,它能够帮助开发人员提高软件系统的质量和稳定性,加快开发周期,降低成本。
什么是接口
在计算机编程中,接口(Interface)是指不同模块、程序或系统之间互相通信的约定。它定义了各个模块之间如何交互,包括输入输出的格式以及发送和接收消息的协议等。常见的接口类型包括应用程序接口、操作系统接口、网络接口、数据库接口等。可以说,接口是现代计算机编程不可或缺的一部分。
当下接口测试中的“接口”通常是指一个Web API(Application Programming Interface),即网络应用程序编程接口,是一种定义了系统或组件之间交互方式的规范。在Web开发中,API通常指提供给客户端(如浏览器、移动应用等)访问和处理数据的接口。例如,在前后端分离的Web应用中,客户端通过调用API来获取数据或执行某些操作。接口定义了请求的格式、参数和返回数据的格式等信息。具体来说,接口可以看作是一个标准规范,它描述了一个函数、类、模块或系统对外提供的输入和输出,以及如何使用这些输入和输出与之交互。我们可以通过调用接口中的方法或发送请求来向实现接口的程序或系统发起请求,并获取返回的结果。接口的一大优势是降低了模块之间的耦合度,使得各个模块可以独立开发、测试和维护,同时也方便了扩展和更新。此外,接口还有助于促进代码复用,提高了整个系统的可重用性和可维护性。
接口测试初学者会混淆接口和路由,它们的区别是:路由是指将HTTP请求映射到相应的处理函数上的分配和请求过程。在Web应用程序中,通常有很多请求需要被处理,如GET请求、POST请求等,每个请求可能需要调用不同的处理函数来完成相应的操作,这时就需要使用路由将不同的请求映射到对应的处理函数上。简而言之,接口定义了客户端与服务端交互的规范,路由则定义了服务器如何处理不同的HTTP请求并将其分派到相应的处理函数上。
HTTP协议与接口测试
要对接口进行测试,首先要了解接口的协议和接口的定义。目前的软件系统之间的消息接口大部分是基于HTTP协议收发的。HTTP协议的特点是,客户端发出一个HTTP请求给服务端,服务端就返回一个HTTP响应,这就与API程序调用的机制是一致的。所以我们可以通过最常规的HTTP接口的报文结构和构成来了解接口的构造。
①请求报文:HTTP请求报文由请求行、请求头、空行和请求包体(body)组成,如图1所示。
根据HTTP标准,HTTP请求可以使用多种请求方法,以表明要对给定资源执行的操作。典型的POST方法的请求报文示例如2图所示。
该报文使用POST方法对/test接口提交了使用multipart/form-data作为content-type的表单。
②响应报文:HTTP响应报文由状态行、响应头部、空行和响应包体(body)组成,如图3所示。其中状态行包含了协议版本、状态码以及状态描述。一个具体的HTTP响应报文如下页图4所示。协议版本指明了报文使用的HTTP协议版本。状态码是一个三位数字,用来表示处理的结果,状态码的类别如表1所示。其中的通用首部字段是指请求报文和响应报文都会使用到的首部字段,具体如下页表2所示。
在这个响应报文中,状态码为200 OK,表示服务器成功地处理了客户端请求并返回了响应。状态行中的“HTTP/1.1”表示使用的HTTP协议版本,后面的“Date”表示响应报文的发送日期和时间。接下来是头部,由四个键值对组成:
“Content-Type: text/html”表示响应体中包含的数据类型为HTML文本。
“Content-Length: 1234”表示响应体的长度为1234个字节。
“Connection: keep-alive”表示该连接可重用,服务器可以在短时间内保持连接以便于后续请求和响应之间的数据传输。
最后一行是空行,用于分隔头部和响应主体。
响应主体是一个HTML页面,其中包含一个标题和一个段落。该响应报文向客户端返回了一个示例HTML文档。
HTTP接口测试示例
为了让读者更好地理解接口测试过程,笔者使用中学教师较熟悉的Python搭建了一个简易的学生信息系统(下载地址:http://wx.ourschool.cn/down/code.zip)来进行接口测试,由于提供API的示例的Server.py是基于Flask框架编写,所以需要先用pip命令(pip install flask)安装Flask依赖包,Python环境下运行应用程序Server.py,服务器将绑定到本地的0.0.0.0:80端口,并在开启调试模式的情况下(debug=True)监听来自客户端的请求,如图5所示。
这是一个基于Flask框架实现的HTTP服务端程序,实现了基础的“查、增、删”功能,该程序提供了以下一个路由和三个API接口,整体结构如图6所示。
1.home路由
当客户端发送GET请求到服务器根路径时,执行home()函数并返回包含学生信息的HTML页面。该页面会显示出所有已定义的学生信息。GET请求home路由报文如下页图7所示。
2.GET_students接口
当客户端发送GET请求到/students路径时,服务器会从请求参数中获取到ID值并进行处理。如果ID存在,则只返回对应ID的学生信息;否则,返回所有已定义的学生信息。返回的数据格式为JSON。GET_students接口报文如图8所示。
3.ADD_students接口
当客户端发送POST请求到/students路径时,服务器会从请求正文中获取JSON格式的数据,并将其添加到内存中的学生信息列表中。在添加学生信息前,服务器会先判断提交的数据是否合法。如果数据格式不正确,缺少必要字段或ID已存在,服务器会返回错误信息并拒绝该次请求。否则,服务器将成功添加新的学生信息,并返回确认的响应数据。ADD_students接口报文如图9所示。
4.DELTE_students接口
当客户端向/students路径发送DELETE请求时,服务器将从请求参数中获取ID值并进行处理。如果指定的ID存在,则服务器将删除对应的学生信息并返回删除成功的响应。否则,服务器将返回错误提示信息,拒绝该次请求。DELTE_students接口报文如图10所示。
接下来为了体验接口的报文结构数据,还需要安装burp suite community(社区版)抓包工具。以下根据给定的服务器代码和接口测试代码,对一些常规的手动接口测试用例进行分析(前述下载链接包含的“测试代码”文件夹下有Python代码对应完成10个手动接口测试用例)。
①测试首页信息:使用GET请求方法向http://127.0.0.1发起请求。
实验结果:返回状态码200和包含‘<h1>Student list</h1>’和‘<th>ID</th><th>名字</th><th>年龄</th>’的响应内容。
打开Burp Suite,然后打开该软件自带浏览器输入“127.0.0.1”,查看“HTTP历史记录”,可看到抓到一组请求响应数据报文,如下页图11所示。
②测试获取学生信息:使用已存在数据向http://127.0.0.1/students发起GET请求,查询ID为1的学生信息,参数为:id=1。
实验结果:返回状态码200和包含id为1、名字为‘张三’、年龄为18的学生信息的响应,如下页图12所示。
③测试获取学生信息:使用不存在数据向http://127.0.0.1/students发起GET请求,参数为:id=4。
由于演示程序目前只有3条学生信息记录,所以实验结果为:返回状态码200和为空数组的响应内容。
④测试添加学生信息:使用合法数据向http://127.0.0.1/students发起POST请求(运行测试代码4.py),如图13所示。
实验结果:返回状态码200和包含“Student added successfully”的响应内容,如图14所示。
⑤测试添加学生信息:使用不正确数据格式向http://127.0.0.1/students发起POST请求(运行测试代码5.py),参数如下页图15所示。
实验结果:返回状态码400和包含“Missing required fields”的响应内容,如下页图16所示。
最后我们体验一下接口自动化测试,在之前下载的文件中,找到Python自动化测试示例程序AutoTest.py,并运行pip命令安装requests(HTTP 请求库)和tqdm(进度条)依赖包:pip install requests tqdm。程序会自动对提供的接口进行测试并输出测试结果,如下页图17所示。
测试首页函数:test_home。
对首页发起了GET请求并判断返回状态码和返回数据是否正确。
测试获取学生信息函数:test_get_students。
正确的ID、错误的ID、不指定ID,这三种数据构建GET请求并判断返回状态码和返回数据是否正确。
测试添加学生信息函数:test_add_students。
合法数据、数据格式不正确、缺少必要字段、ID已存在,这四种数据构建POST请求并判断返回状态码和返回数据是否正确。
测试删除学生信息函数:test_delete_students。
正确的ID、不存在的ID、不传递ID、非数字,这四种数据构建DEL请求并判断返回状态码和返回数据是否正确,再判断是否正确删除了数据。
运行上述示例可以体验到将软件测试由手工变成了自动,进而可以低成本、快速地反复运行,并可以做手工做不了、不好做的测试(如针对一些输入不可见的特殊字符、二进制数据等)。虽然自动化测试并不能彻底代替手工测试,但作为一种高效、快速和对测试人员要求更高的软件测试方法,它已经被越来越多行业的软件开发组织所采纳。
结语
人工智能和自动化技术在接口测试领域的应用已经深刻影响了测试行业。利用人工智能的自适应学习和自我优化算法,可以预测和识别潜在的故障和异常,提高了测试效率和覆盖范围。同时,自动化测试工具可以帮助测试人员更快、更准确地进行接口测试,进一步提高测试效果和质量。例如,现在广泛使用的SoapUI和Postman都是功能强大的自动化接口测试工具。同时随着人工智能技术的发展,越来越多的组织开始依靠人工智能进行自动化测试和缺陷预测。例如,用机器学习算法,在执行测试的过程中分析测试结果并进行缺陷预测,以便更快速、更准确地确定缺陷位置,提高测试效率和可靠性。再如,用人工智能技术在测试执行过程中动态优化测试用例,并指导测试用例自动演化,提升测试覆盖度和准确性。下期我们通过Docker容器化快捷部署来加深这方面的体验。