上图:

python自动化流水线_自动化测试

getpathInfo.py:获取autoapi文件夹所在的目录,便于项目换家,有没有其实无所谓的;

import os


def get_path():
    path = os.path.split(os.path.realpath(__file__))[0]
    return path


if __name__ == '__main__':
    print('测试路径是否OK,路径为:', get_path())

readConfig.py

import os
import configparser
import getpathInfo

path = getpathInfo.get_path()  
config_path = os.path.join(path, 'config')  
config = configparser.ConfigParser()  # 调用外部的读取配置文件的方法
config.read(config_path, encoding='utf-8')


class ReadConfig():

    def get_http(self, name):
        value = config.get('HTTP', name)
        return value

    def get_email(self, name):
        value = config.get('EMAIL', name)
        return value

    def get_account(self, name):
        value = config.get('ACCOUNT', name)
        return value


environment = ReadConfig().get_http('environment')  # 切换环境
mobile_phone = ReadConfig().get_account('mobile_phone')
password = ReadConfig().get_account('password')
parent_username = ReadConfig().get_account('parent_phone')
parent_pwd = ReadConfig().get_account('parent_pwd')

common:公共方法文件夹,最省事配置:日志封装(中文日志在这里要留意,有坑),请求封装(如果有token之类的限制的话)

logs.py

import logging
import time
 
from getpathInfo import get_path
 
 
class Log(object):
    def __init__(self, logger=None):
        """
        指定保存日志的文件路径,日志级别,以及调用文件
        将日志存入到指定的文件中
        """
 
        # 创建一个logger
        self.logger = logging.getLogger(logger)
        self.logger.setLevel(logging.DEBUG)
        # 创建一个handler,用于写入日志文件
        self.log_time = time.strftime('%Y-%m_%d_')
        self.log_path = get_path()+'\\log\\'
        self.log_name = self.log_path + self.log_time + 'test.log'
        fh = logging.FileHandler(self.log_name, 'a', encoding='utf-8')  # 追加模式,防止中文乱码
        fh.setLevel(logging.INFO)
 
        # 再创建一个handler,用于输出到控制台
        ch = logging.StreamHandler()
        ch.setLevel(logging.INFO)
 
        # 定义一个handler的输出样式
        formatter = logging.Formatter(
            '[%(asctime)s] %(filename)s->%(funcName)s line:%(lineno)d [%(levelname)s]%(message)s')
        fh.setFormatter(formatter)
        ch.setFormatter(formatter)
 
        # 给logger添加handler
        self.logger.addHandler(fh)
        self.logger.addHandler(ch)
 
        #  添加下面一句,在记录日志之后移除句柄
        fh.close()
        ch.close()
 
    def getLog(self):
        return self.logger
 
 
log = Log().getLog()
if __name__ == '__main__':
    log.info('日志')  # 抄过来的代码一定要进行测试

configHttp.py

这里是默认加上token的,但是并不是所有接口都是需要token,解决思路:再加个configHttpNormal.py,或者run_main()里再加个入参。

import json
import requests

from common.logs import log
from readConfig import environment,mobile_phone,password
from case.api.User import login
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)  # 如果有抓包需求,需要把verify设置成False,这行代码忽略系统之后的警告
"""
这个文件主要来通过get、post等方法来进行http请求,并拿到请求响应
"""

token = login(mobile_phone,password) # 登录方法
headers = {'Authorization': token,
           "Content-Type": 'application/json;charset=UTF-8',
           'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36'}


class RunMain():
    def send_post(self, path, data):
        response = requests.post(url=environment+path,data=json.dumps(data,ensure_ascii=False,separators=(',',':')).encode('utf-8'), headers=headers,verify=False)
        log.info(path)  # path
        log.info(data)  # 请求,便于复现
        log.info(response.status_code)  # 请求状态码
        return response

    def send_get(self, path, data):
        response = requests.get(url=environment+path, data=data, headers=headers,verify=False)
        log.info(path)
        log.info(data)
        log.info(response.status_code)
        return response

    def run_main(self, method, path=None, data=None):
        result = None
        if method.lower() == 'post':
            result = self.send_post(path, data)
        elif method.lower() == 'get':
            result = self.send_get(path, data)
        else:
            print("method值错误!!!")
        return result


if __name__ == '__main__':
    result1 = RunMain().run_main('get', '/v1/wrong-work/info?type=1').json()
    result2 = RunMain().run_main('Get', '/v1/wrong-work/info?type=2').json()
    print(result1)
    print(result2)

case:用例文件夹,敏捷模式中开发提测基本上都是单接口提测,而且同一个模块下的接口分给了不同的开发,为了方便定位到开发,所以我将平台所有的接口都写了过来╮(╯▽╰)╭,

老规矩,下方直接执行,可以进行单接口的相关验证。

python自动化流水线_python自动化流水线_02


相信各位也看了很多的接口自动化测试框架,我上面的应该没有多少新意,下面就是不同点;

regression_testing 顾名思义,回归测试ing,只有进行时,没有完成时……

python自动化流水线_软件测试_03


上图是使用unittest框架进行的,用例之间传参用法其实就是我上面展示的一部分;

其实这个文件夹下不适合使用unittest框架,因为通过用例之间的巧妙设计,虽然可以将业务之间的调用状态都模拟出来,但是由于脏数据的存在,某些bug没有在这些测试过程中表示出来。

python自动化流水线_自动化测试_04


之后优化思路:将regression_testing里面的方法改成test_*,写一个run方法,加上测试报告,邮件通知

python自动化流水线_自动化测试_05