接口测试框架实践(Python)

Posted iTesting

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了接口测试框架实践(Python)相关的知识,希望对你有一定的参考价值。

iTesting,爱测试,爱分享


2,3年以前给大家分享过如何用,但工具毕竟有限制,所以在真实的项目中,大家还是用自研的框架多。 我之前写过一个简单的基于unittest+request的接口测试框架,也分享给大家过,最近在免费直播中我也有讲到,但直播毕竟讲不透彻,还是有很多同学不是特别清楚,到底如何做一个接口测试框架,今天我们再次详细解释下,如何生成自己的接口测试框架。


关于接口测试,基本概念请,接口测试我们一般先手工做,然后再自动化,无论手工还是自动化,接口测试的步骤都大致如下:

1. 根据接口文档/规范及接口功能来设计测试用例,设计法则参考黑盒测试和白盒测试方法。

2. 准备测试数据,用工具(Postman, fiddler, soapui等)或代码(python+requests或其它语言),根据测试用例构造请求,发请求。

3. 检查服务器返回的结果。 包括状态码和返回值的检查。 各种合法非法的请求接口能否正确处理,要特别注意安全性(仅前端校验,后端忘记校验),authentication,性能(特别是并发),数据一致性,完整性方面(幂等)的问题。

接口测试的检查点,一般如下:


手工如何测试,很清楚了,那么我们讲接口测试自动化框架,从哪里开始呢?


既然是自动化,那么就必须不需要人工干预,框架如何做到不需要人工干预呢?窃以为有如下方面:

  1. 用例的自动收集。 就是要自动接受用户输入,自动分析并查找待跑用例。什么意思呢?你跑自动化时候,一般需要指定跑那些case,这些case属于哪个类别(regression, smoke, unit test?)框架需要能根据用户输入快速找到要跑到用例集,并把它加到待跑用例的列表里。如果你不指定,框架会跑默认文件夹下的用例集。

  2. 用例的运行方式。 就是组织查找到的用例集合,你想怎么运行? 顺序执行还是并发执行,执行过程中要不要记log,有错误是要继续还是要停止运行?运行失败要不要重新跑一遍?执行完毕后要不要收集执行结果?

  3. 测试报告。所有用例执行完毕后需要有整个运行情况的报告,包括整体运行结果,执行的用例列表,用例中成功百分比,失败百分比,失败的用例,框架有没有在它发生错误的时候截图?有没有记log,在失败的用例上点击用例名称,能不能通过链接的方式快速定位截图,log?  你想要txt格式的报告还是更user friendly的html格式?                                                                           

    前面3部分有了,一个测试框架的壳子就出来了,但还不够好,还需要加上:

  4. 自动触发运行。 何时运行这个框架?每次有代码改动?发版前?还是每日定时?

  5. 环境配置。基本上公司的测试环境不可能只有一个,那么如何配置同样的脚本跑在不同的环境上?

  6. Data provider (数据生成)。环境不一样,测试数据不能一样吧?如何提供不同环境的数据且不更改自动化代码?

  7. 邮件发送。 自动化测试结束后自动发送测试报告到相应人的邮箱。

  8. 日志,错误处理。运行中记录运行情况,错误情况及出错后的处理。


下面,我们就以我实现的EasyAPIFramework(Python+Unittest+HTMLTestRunner)为例,详细说明下框架是如何一步步搭建起来的。

Unittest。unittest是python语言里使用最广泛的一个框架,看名字就知道它本来做unit test用的,但因为太强大了,所以也被拿来做功能自动化,接口自动化。

unittest有四个重要的概念:

  • test fixture:represents the preparation needed to perform one or more tests(setup, teardown)。

    setUp(): 每次执行测试用例之前调用。无参数,无返回值。该方法抛出的异常都视为error,而不是测试不通过。没有默认的实现。

    tearDown(): 每次执行测试用例之后调用。无参数,无返回值。测试方法抛出异常,该方法也正常调用,该方法抛出的异常都视为error,而不是测试不通过。只用setUp()调用成功,该方法才会被调用。没有默认的实现。通过setup 和 tesrDown组装一个module成为一个固定的测试装置。注意:如果setup运行抛出错误,则测试用例代码则不会执行。但是,如果setpu执行成功,不管测试用例是否执行成功都会执行teardown。

  • test case:独立测试的单位,一般一个testcase完成一个功能。注意两点:

    1. testcase通常继承自测试类,测试类一般继承自unittest.TestCase。测试类里通常实现了setup(), teardown(), 及测试用例。

     2. test case要以test开头。

  • test suite:A test suite is a collection of test cases, test suite。通常用来聚合测试用例, 并且test suites可以嵌套。

  • test runner:A test runner is a component which orchestrates the execution of tests and provides the outcome to the user.运行测试用例的驱动类,可以执行TestCase,也可执行TestSuite。执行后TestCase和Testsuite会自动管理TestResult。简单来说就是run(),里面就是手工测试的步骤代码化。

除了上述概念,unittest里还有几个概念需要你知道:

TestLoder:是用来加载 TestCase到TestSuite中,其中有几个loadTestsFrom_()方法,就是从各个地方寻找TestCase,创建他们的实例,然后add到TestSuite中,再返回一个TestSuite实例

TextTestRunner:是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。

 TextTestResult:测试结果会保存到TextTestResult实例中,包括运行了多少用例,成功与失败多少等信息

一般来说,unittest执行测试的流程如下:

创建好TestCase,然后由TestLoader加载(也可以用TestDiscover指定文件夹的方式Load)TestCase到TestSuite,然后由TextTestRunner来运行TestSuite,运行的结果保存在TextTestResult中,整个过程集成在unittest.main模块中。

下面我们举个例子来看下,一个简单的unittest的测试用例长什么样子:

接口测试框架实践(Python)

好,看上图,这里我实现了一个测试类,它继承了unittest.TestCase.然后再测试类里实现了setup(), test_XXX(), teardown()方法,有的测试方法上我加个了@unittest.skip(). 说这个什么意思呢?我开始说测试框架要实现查找测试用例集,unittest帮我们把测试用例标记好了,所有的测试用例要以test开头,当你调用TestLoder(defaultTestLoader()类,通过该类下面的discover()方法可自动根据测试目录start_dir匹配查找测试用例文件(test*.py),并将查找到的测试用例组装到测试套件)查找测试用例集的时候,所以test开头的会被自动加入测试用例集。哪些被标记为unittest.skip()的则不会。 第2,我想实现跑某些用例,怎么办呢?unitest 不支持按照标签运行,但是它提供了testsuite概念,你可以把一个测试类的几个测试用例添加到testsuite里。这样unitest就实现了框架的第一要素,测试用例集的查找。

那么用例集查找好了,你定义的test_XXX()的方法最终都会在TextTestRunner的run()方法中被执行到。也就是说,通过TextTestRunner我们实现了用例的顺序执行。(并发执行unittest貌似不支持,并发执行可以用pytest)

看,利用unittest我们可以轻易开发出一个测试用例并实现了用例收集和用例执行。那么测试报告如何生成呢?我们可以借助HTMLTestRunner来实现。

HTMLTestRunner is an extension to the Python standard library’s unittest module. It generates easy to use HTML test reports


好, 有了unittest +HTMLRunner,测试框架所需要的123就有了,后面的6到8(自动触发运行,环境配置,Data provider (数据生成),邮件发送,日志,错误处理),其中(自动触发运行,环境配置,邮件发送)可以通过集成Jenkins的方式实现, Data provider (数据生成),日志,错误处理,需要我们代码实现。

我们再回过来看这个简单的框架。

接口测试框架实践(Python)

这个框架分了几个部分(以前写的英文版我就不翻译了哈):

"Common": --Common methods to facilitates the whole project.

  • html_report: To generate HTML report after test cases run.

  • shared_api: Import method like post/get to serve all the API requests.

  • txt_report: Independent way to run all the cases under test and generate simple txt format report.

主要来说就是一些公用的library,包括如对selenium的二次封装(web自动化),对API调用的二次封装(API自动化),datadriven读文件方法及项目所用到的公用库文件。

shared_api里包含了我对requests的封装,其实,针对webservices(一般为?wsdl文件)的API,也可以写个公用方法包括在内,可以看看它长什么样子:

接口测试框架实践(Python)

如果你要做web自动化框架,那么就写个Selenium_helper,包括你所有对selenium的wrap方法,然后你在测试类的setup(), teardown()两个类下调用(看出来了吧,框架本身应该和什么类型的测试无关,框架就是用来帮你组织你的测试用例的)。


"Page": --The page under test.

  • in this file, only store the page related function/method/date

  • test case related to this page should not be included here.

  • different page should have separated pages.

真正你要测试的项目(如果是功能自动化,你需要利用page object模式实现页面元素,和定位元素的loactor分离(其实测试数据,逻辑,业务都应该分离并可重用))。一个完整的页面或功能我们组织在一起叫一个page,这个page应该包括这个页面的元素,及针对元素的操作,但测试业务逻辑不般不包括。

一个page通常是什么样子呢?

接口测试框架实践(Python)


"Settings": --Global settings & configuration & global data.

  • __init__:

  • data_source: all the account, common test data.

  • test config: environment, domain or other common config.

这里就是整个项目的配置文件,包括数据配置也可以放置在内,一般会有变量来接受来自jenkins的环境变量。如果没有就设置default值。 Test_config里应该包含你测试的数据,不同环境区分开,也可以写到外部excel或者xml了,然后利用common方法里的datadriven方法读出。 我们就是通过这个来实现环境及数据的切换。

接口测试框架实践(Python)


"test" -- Test cases inherited from pages, this is the cases under test.

  • each test file should have a page file accordingly.

  • framework will only search the cases under this folder

就是你测试类和测试方法所在,通常你测试类的名称要和你测试对象的名称一样,只是在前面加test(注意unittest只有以test开头的测试用例才会被执行)。

接口测试框架实践(Python)

注意,setup()应该包括测试用例的数据准备(比如你需要打他driven,这次的数据就应该包括进来),还有selenium调用及browser的initial(针对web功能自动化),requests接口的初始化(API自动化)等。teardown()里,要做好相应的销毁动作。


"main" -- Load & run all of the test cases defined in test folder.

  • System will automated search all the test method defined in test folder and run them.

当然你也可以通过TestDiscover及testsuite的addTest来筛选你需要执行的用例,我简化为搜索所有test文件夹下的用例了(直接利用discover方法)。

好了,到这里为止,我们就实现了一个基本的接口测试框架,是不是感觉非常简单啊?(接口框架代码Github:https://github.com/Light07/EasyAPIAutomationFramework)


其实,在真正的项目实践中,要考虑到比这个要复杂的多,起码并发执行我们没实现啊,数据驱动我们也没实现。失败rerun也没有。后续我会重新实现一个开源的接口测试框架给大家,把我提及的全部功能都实现,当然,大家也可以直接选用pytest,我后续也会写下pytest教程,敬请期待。



 -  End  -

Kevin Cai, 江湖人称蔡老师。

两性情感专家,非著名测试开发。

技术路线的坚定支持者,始终相信Nobody can be somebody。      

                     

· 猜你喜欢的文章 ·

以上是关于接口测试框架实践(Python)的主要内容,如果未能解决你的问题,请参考以下文章

接口测试框架接入性能测试实践分享

实践分享接口测试框架接入性能测试

接口自动化测试框架-AIM

Python Locust性能测试框架实践

接口测试框架开发实践5:配置文件读取

接口自动化测试实践