从0到1框架搭建,Python+Pytest+Allure+Git+Jenkins接口自动化框架(超细整理)

前言

接口测试是对系统和组件之间的接口进行测试,主要是效验数据的交换,传递和控制管理过程,以及相互逻辑依赖关系。其中接口协议分为HTTP,RPC,Webservice,Dubbo,RESTful等类型。

接口测试流程
1、需求评审,熟悉业务和需求
2、开发提供接口文档
3、编写接口测试用例
4、用例评审
5、提测后开始测试
6、提交测试报告

两种常见的 HTTP 请求方法:GET 和 POST

框架是一套基于Python+Pytest+Requests+Allure+Jenkins而设计的数据驱动接口自动化测试的框架。

技术栈:
Python、Pytest、Requests、Pactverity、Excel、Json、Mysql、Allure、Logbook、Git、Jenkins

框架结构图:

从0到1框架搭建,Python+Pytest+Allure+Git+Jenkins接口自动化框架(超细整理)_第1张图片

项目功能:
Python+Pytest+Allure+Jenkins接口自动化框架,实现Excel或Json维护测试用例,支持数据库操作,利用封装的请求基类调取相应的测试用例接口,获取配置文件中的环境地址与环境变量,

结合Pytest进行单元测试,使用LogBook进行记录日志,并生成allure测试报告,最后进行Jenkins集成项目实现集成部署,并发送测试报告邮件。

工具类封装

1、日志模块
项目中的log日志是logbook进行日志记录的,方便测试开发调试时进行排错纠正或修复优化。日志可选择是否打印在屏幕上即运行时是否在终端输出打印。日志格式输出可调整。

handle_log.py部分源码

  1. def log_type(record, handler):

  2. log = "[{date}] [{level}] [{filename}] [{func_name}] [{lineno}] {msg}".format(

  3. date=record.time, # 日志时间

  4. level=record.level_name, # 日志等级

  5. filename=os.path.split(record.filename)[-1], # 文件名

  6. func_name=record.func_name, # 函数名

  7. lineno=record.lineno, # 行号

  8. msg=record.message # 日志内容

  9. )

  10. return log

  11. # 日志存放路径

  12. LOG_DIR = BasePath + '/log'

  13. print(LOG_DIR)

  14. if not os.path.exists(LOG_DIR):

  15. os.makedirs(LOG_DIR)

  16. # 日志打印到屏幕

  17. log_std = ColorizedStderrHandler(bubble=True)

  18. log_std.formatter = log_type

  19. # 日志打印到文件

  20. log_file = TimedRotatingFileHandler(

  21. os.path.join(LOG_DIR, '%s.log' % 'log'), date_format='%Y-%m-%d', bubble=True, encoding='utf-8')

  22. log_file.formatter = log_type

  23. # 脚本日志

  24. run_log = Logger("global_log")

  25. def init_logger():

  26. logbook.set_datetime_format("local")

  27. run_log.handlers = []

  28. run_log.handlers.append(log_file)

  29. run_log.handlers.append(log_std)

  30. return ""

打印在终端的日志,如下图所示。

从0到1框架搭建,Python+Pytest+Allure+Git+Jenkins接口自动化框架(超细整理)_第2张图片

同时运行项目后,会在项目文件log中自动生成一个以当天日期命名的log文件。点击log日志文件可查看日志详情即项目运行时所记录的日志或报错日志。如下图所示。

从0到1框架搭建,Python+Pytest+Allure+Git+Jenkins接口自动化框架(超细整理)_第3张图片

2、配置文件模块
项目中涉及到一些配置文件如username、password或环境变量时,我们可通过配置文件来获取配置值。通过配置文件中key与value的定义来确定获取配置文件的值。

handle_init.py部分源码

  1. class HandleInit:

  2. # 读取配置文件

  3. def load_ini(self):

  4. file_path = BasePath + "/config/config.ini"

  5. cf = configparser.ConfigParser()

  6. cf.read(file_path, encoding='UTF-8')

  7. return cf

  8. # 获取ini里面对应key的value

  9. def get_value(self, key, node=None):

  10. if node == None:

  11. node = 'Test'

  12. cf = self.load_ini()

  13. try:

  14. data = cf.get(node, key)

  15. logger.info('获取配置文件的值,node:{},key:{}, data:{}'.format(node, key, data))

  16. except Exception:

  17. logger.exception('没有获取到对应的值,node:{},key:{}'.format(node, key))

  18. data = None

  19. return data

获取配置文件中的值日志如下图所示。

B3

3、接口请求封装
获取相关测试用例及接口用例配置,记录请求相关参数的日志,定义Allure测试报告的步骤。

handle_apirequest.py部分代码

  1. class ApiRequest:

  2. def api_request(self, base_url, test_case_data, case_data):

  3. get_name = None

  4. get_url = None

  5. get_method = None

  6. get_headers = None

  7. get_cookies = None

  8. get_case_name = None

  9. get_case_params = None

  10. response_data = None

  11. try:

  12. get_name = test_case_data['config']['name']

  13. get_url = base_url + test_case_data['config']['url']

  14. get_method = test_case_data['config']['method']

  15. get_headers = test_case_data['config']['headers']

  16. get_cookies = test_case_data['config']['cookies']

  17. except Exception as e:

  18. logger.exception('获取用例基本信息失败,{}'.format(e))

  19. try:

  20. get_case_name = case_data['name']

  21. get_case_params = case_data['params']

  22. except Exception as e:

  23. logger.exception('获取测试用例信息失败,{}'.format(e))

  24. with allure.step("请求接口:%s,请求地址:%s,请求方法:%s,请求头:%s,请求Cookies:%s" % (

  25. get_name, get_url, get_method, get_headers, get_cookies)):

  26. allure.attach("接口用例描述:", "{0}".format(get_case_name))

  27. allure.attach("接口用例请求参数:", "{0}".format(get_case_params))

  28. logger.info(

  29. '请求接口名:%r,请求地址:%r,请求方法:%r,请求头:%r,请求Cookies:%r' %\

  30. (get_name, get_url, get_method, get_headers, get_cookies))

  31. logger.info('请求接口名:%r,请求接口用例名:%r,接口用例请求参数:%r' %\

  32. (get_name, get_case_name, get_case_params))

  33. try:

  34. response_data = baseRequest.run_main(get_method, get_url, get_case_params, get_headers)

  35. except Exception as e:

  36. logger.exception('用例请求返回失败,{}'.format(e))

  37. logger.info('请求接口名:%r,请求接口用例名:%r,返回参数:%r' % (get_name, get_case_name, response_data.json()))

  38. return response_data

4、Excel数据处理-测试用例

测试用例中维护在Excel文件中,类中定义如何获取Excel中的相关数据(如获取某个单元格的内容,获取单元格的行数,以及将数据写入Excel中等操作)。

handle_exceldata.py部分源码

  1. class OperationExcel:

  2. def __init__(self, file_name=None, sheet_id=None):

  3. if file_name:

  4. self.file_name = file_name

  5. self.sheet_id = sheet_id

  6. else:

  7. self.file_name = ''

  8. self.sheet_id = 0

  9. self.data = self.get_data()

  10. # 获取sheets的内容

  11. def get_data(self):

  12. data = xlrd.open_workbook(self.file_name)

  13. tables = data.sheets()[self.sheet_id]

  14. return tables

  15. # 获取单元格的行数

  16. def get_lines(self):

  17. tables = self.data

  18. return tables.nrows

  19. # 获取某一个单元格的内容

  20. def get_cell_value(self, row, col):

  21. return self.data.cell_value(row, col)

5、JSON数据处理-测试用例

  1. {

  2. "config":{

  3. "name":"post接口名",

  4. "url":"/langdetect",

  5. "method":"POST",

  6. "headers":{

  7. "Content-Type":"application/json"

  8. },

  9. "cookies":{

  10. }

  11. },

  12. "testcase":[

  13. {

  14. "name":"测试用例1",

  15. "params":{

  16. "query":"测试"

  17. },

  18. "validate":[

  19. {

  20. "check":"status_code",

  21. "comparator":"eq",

  22. "expect":"200"

  23. }

  24. ]

  25. },

  26. {

  27. "name":"测试用例2",

  28. "params":{

  29. "query":"python"

  30. },

  31. "validate":[

  32. {

  33. "check":"msg",

  34. "comparator":"eq",

  35. "expect":"success"

  36. }

  37. ]

  38. }

  39. ]

  40. }

获取Json文件中里具体字段的值。
handle.json.py部分源码

  1. class HandleJson:

  2. # 读取json文件

  3. def load_json(self, file_name):

  4. if file_name == None:

  5. file_path = ""

  6. else:

  7. file_path = file_name

  8. try:

  9. with open(file_path, encoding='UTF-8') as f:

  10. data = json.load(f)

  11. return data

  12. except Exception:

  13. print("未找到json文件")

  14. return {}

  15. # 读取json文件里具体的字段值

  16. def getJson_value(self, key, file_name):

  17. if file_name == None:

  18. return ""

  19. jsonData = self.load_json(file_name)

  20. if key == None:

  21. getJsonValue = ""

  22. else:

  23. getJsonValue = jsonData.get(key)

  24. return getJsonValue

基类封装

接口支持Get、Post请求,调用requests请求来实现接口的调用与返回。接口参数包括,接口地址、接口请求参数、cookie参数、header参数。

  1. class BaseRequest:

  2. def send_get(self, url, data, header=None, cookie=None):

  3. """

  4. Requests发送Get请求

  5. :param url:请求地址

  6. :param data:Get请求参数

  7. :param cookie:cookie参数

  8. :param header:header参数

  9. """

  10. response = requests.get(url=url, params=data, cookies=cookie, headers=header)

  11. return response

  12. def send_post(self, url, data, header=None, cookie=None):

  13. """

  14. Requests发送Post请求

  15. :param url:请求地址

  16. :param data:Post请求参数

  17. :param data:Post请求参数

  18. :param cookie:cookie参数

  19. :param header:header参数

  20. """

  21. response = requests.post(url=url, json=data, cookies=cookie, headers=header)

  22. return response

  23. # 主函数调用

  24. def run_main(self, method, url, data, header, cookie=None):

  25. try:

  26. result = ''

  27. if method.upper() == 'GET':

  28. result = self.send_get(url, data, header, cookie)

  29. elif method.upper() == 'POST':

  30. result = self.send_post(url, data, header, cookie)

  31. return result

  32. except Exception as e:

  33. logger.exception('请求主函数调用失败:{}'.format(e))

测试用例编写

引用Pytest来进行接口的单元测试,通过JSON中多个测试用例来做为参数化数据驱动。结合Allure制定相应接口的测试报告。在接口返回断言之前,我们先进行该接口的契约测试,

我们采用的是Pactverity的全量契约校验测试。当契约测试通过时,我们再进行返回参数的相关校验测试。

test_getRequestJson.py部分源码

 
  
  1. @allure.feature('测试GET请求模块')

  2. class TestRequestOne():

  3. @allure.title('测试标题')

  4. @allure.testcase('测试地址:https://www.imooc.com')

  5. @pytest.mark.parametrize('case_data', testCaseData['testcase'])

  6. def test_requestOne(self, case_data):

  7. try:

  8. api_response = apiRequest.api_request(baseurl, testCaseData, case_data)

  9. api_response_data = api_response.json()

  10. # pactverity——全量契约校验

  11. config_contract_format = Like({

  12. "msg": "成功",

  13. "result": 0,

  14. "data": EachLike({

  15. "word": Like("testng")

  16. })

  17. })

  18. mPactVerify = PactVerify(config_contract_format)

  19. try:

  20. mPactVerify.verify(api_response_data)

  21. logger.info(

  22. 'verify_result:{},verify_info:{}'.format(mPactVerify.verify_result, mPactVerify.verify_info))

  23. assert mPactVerify.verify_result == True

  24. except Exception:

  25. err_msg = '契约校验错误'

  26. logger.exception('测试用例契约校验失败,verify_result:{},verify_info:{}'.format(mPactVerify.verify_result,

  27. mPactVerify.verify_info))

  28. try:

  29. for case_validate in case_data['validate']:

  30. logger.info('断言期望相关参数:check:{},comparator:{},expect:{}'.format(case_validate['check'],

  31. case_validate['comparator'],

  32. case_validate['expect']))

  33. comparatorsTest.comparators_Assert(api_response, case_validate['check'],

  34. case_validate['comparator'], case_validate['expect'])

  35. logger.info('测试用例断言成功')

  36. except Exception as e:

  37. logger.exception('测试用例断言失败')

  38. except Exception as e:

  39. logger.exception('测试用例请求失败,原因:{}'.format(e))

主运行:

运用Pytest和Allure的特性,命令行运行测试用例文件夹,并生成对应的allure测试报告。

  1. if __name__ == "__main__":

  2. pytest.main(['-s', '-v', 'test_case/testRequest/', '-q', '--alluredir', 'reports'])

Alluer2 测试报告

当我们运行主函数时,并生成对应的测试用例报告时,我们可以看到在该文件夹中会生成对应的json文件的测试报告。

reports是json格式测试报告存放的目录位置,allure_reports是html测试报告文件生成的目录位置。allure命令如下。

allure generate reports -o allure_result/

项目根目录下的allure_reports文件,存放的是allure生成的测试报告。可看出文件下有一个HTML文件,可通过Python的编辑器Pycharm来打开该HTML文件(测试报告),或可通过allure命令来打开该HTML。

感谢每一个认真阅读我文章的人!!!

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。 

          视频文档获取方式:
这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片即可自行领取。

你可能感兴趣的:(自动化测试,软件测试,python,pytest,git,软件测试)