¡¡¡¡

apiAutoTest£º×Ô¶¯»¯²âÊÔÖеÄÊý¾ÝÒÀÀµ´¦Àí

ԭʼ°æ±¾

¼òÊ飺https://www.jianshu.com/p/6bfaca87a93b
²©¿ÍÔ°£º/zy7y/p/13426816.html
testerhome£ºhttps://testerhome.com/topics/25003

×îÐÂÓÃÀý½ØÍ¼ÒÔ¼°ÓÃÀýÌîд¸ñʽ

case.png

Snipaste_2020-11-23_07-21-53.png

Êý¾ÝÒÀÀµ/·¾¶²ÎÊýÒÀÀµ

365betÌåÓýÔÚÏßÀí½âµÄ²ÎÊýÒÀÀµ/½Ó¿ÚÒÀÀµ¾ÍÊǽӿڽøÐйØÁª²Ù×÷£¬±ÈÈçÓÐЩ²éѯ½Ó¿ÚÐèÒªµÇ¼֮ºó²Å¿ÉÒÔ²Ù×÷£¬ÄÇô365betÌåÓýÔÚÏßÃǾÍÐèÒªÄõ½tokenÖ®ÀàµÄ¶«Î÷£¬ÕâÒ»²¿·Ö¶«Î÷ÊǷŵ½headerÖеģ¬apiAutoTestÎ§ÈÆµÄÖ»Óз¾¶²ÎÊýÒÀÀµ£¬ÇëÇóÊý¾ÝÒÀÀµ

  • ·¾¶²ÎÊýÒÀÀµ

    Æ©Èç˵ÏÖÔÚµÄrestful£¬Ò»¸öusers½Ó¿Ú£¬Â·ÓÉÒ»°ãÕâÑùµÄusersËûµÄÇëÇó·½Ê½ÊÇget£¬Õâ¸ö·ÓÉ365betÌåÓýÔÚÏßÃǰÑËûÈÏΪÊDzéËùÓÐÓû§£¬Èç¹û²éijһ¸öÓû§¿ÉÄÜÊÇÕâÑùµÄusers/:idÒ²ÊǸögetÇëÇó£¬ÕâÀïÕâ¸öidÏë±í´ïµÄÒâ˼ÊÇÕâÀïÓиöÐèÒª¸öÓû§idµÄ²ÎÊý£¬±ÈÈç1-500ÀïÃæµÄÈ365betÌåÓýÔÚÏßâ1¸ö£¬Ò²¾ÍÊÇ˵Õâ¸öidÊǿɱäµÄ£¬¿ÉÒԴӵǼ½Ó¿ÚµÄ·µ»ØÏìӦȡһ¸ö½ÐuserIdµÄÖµ

  • ÇëÇó²ÎÊýÒÀÀµ

    Õâ¸öÓ¦¸ÃºÃÀí½âЩ£¬¾ÍÊÇ˵֧¸¶½Ó¿ÚÐèÒªµÄ¶©µ¥id£¬ÊÇ´ÓÉÏÒ»²½Ìá½»¶©µ¥½Ó¿Ú·µ»ØµÄÏìÓ¦¶©µ¥id

¾Ù¸öÀý×Ó

¼ÙÉèÏÖÔÚÓиöʵ¼ÊÏìÓ¦½á¹û×ÖµäÈçÏÂ

{"case_002": {
        "data": {
            "id": 500,
            "username": "admin",
            "mobile": "12345678",
        }},
  "case_005": {
        "data": {
            "id": 511,
            "create_time": 1605711095
        },
    }
}
  • excelÖнӿÚ·¾¶ÄÚÈÝ£ºusers/&$.case_005.data.id&/state/&$.case_005.data.careate_time&

    ´úÂëÄÚ²¿½âÎöºóÈçÏÂ:users/511/state/1605711095

    &$.case_005.data.id& ´ú±í´ÓÏìÓ¦×ÖµäÖÐÌáÈ¡case_005×ÖµäÖÐdata×ÖµäÖеÄidµÄÖµ£¬ÌáÈ¡³öÀ´µÄ½á¹ûÊÇ511

  • excelÖÐÇëÇó²ÎÊýÄÚÈÝÈçÏÂ:

    {
     "pagenum": 1, 
     "pagesize": "12",
     "data": &$.case_005.data&, 
     "userId": &$.case_002.data.id&
    }
    

    ´úÂëÄÚ²¿½âÎöºóÈçÏÂ:

    {
     "pagenum": 1, 
     "pagesize": "12",
     "data": {
                "id": 511,
                "create_time": 1605711095
            }, 
     "userId": 500
    }
    

Æäʵ²»ÄÑ¿´³öÆäÖйæÔò&jsonpathÌáÈ¡Óï·¨&£¬Èç¹ûÄãÐèÒªµÄÄÚÈÝÊÇ×Ö·û´®ÀàÐÍ£¬Ö»ÐèÒªÕâÑù"&jsonpathÌáÈ¡Óï·¨&"

ÉÏ´«Îļþ

ÓÃÀýÖÐÊéд¸ñʽ£¬ÔÚÉÏ´«ÎļþÀ¸

# µ¥ÎļþÉÏ´«ÔÚexcelÖÐд·¨
{"½Ó¿ÚÖнÓÊÜÎļþ¶ÔÏóµÄ²ÎÊýÃû": "Îļþ·¾¶µØÖ·"}

# ¶àÎļþÉÏ´«ÔÚexcelÖÐд·¨
{"½Ó¿ÚÖнÓÊÜÎļþ¶ÔÏóµÄ²ÎÊýÃû": ["Îļþ·¾¶1", "Îļþ·¾¶2"]}

Ô¤ÆÚ½á¹û

ÓÃÀýÊéд¸ñʽ

# ¶ÏÑÔÒ»¸öÄÚÈÝ
{"jsonpathÌáÈ¡±í´ïʽ": Ô¤ÆÚ½á¹ûÄÚÈÝ}
# ¶à¸ö¶ÏÑÔ
{"jsonpathÌáÈ¡±í´ïʽ1": Ô¤ÆÚ½á¹ûÄÚÈÝ1,"jsonpathÌáÈ¡±í´ïʽ2": Ô¤ÆÚ½á¹ûÄÚÈÝ2}

ÆäËûÓÅ»¯

  • config.yamlÎļþÖÐÐÂÔö¿ÉÅäÖóõʼheader£¬ÕûÌå´úÂëÓÅ»¯£¬Ïà±È֮ǰ£¬Í¬Ñù²âÊÔÓÃÀýÖ´ÐÐÏ£¬¿ìÁË2s×óÓÒ
  • ½«ÅäÖÃÎļþ¶ÁÈ¡£¬ÓÃÀý¶ÁÈ¡ÕûºÏÔÚread_file.pyÏÂ
  • ÒÆ³ý±¨¸æÑ¹Ëõ·½·¨
  • ¼õÉÙÈÕÖ¾ÐÅÏ¢

ÏÖÒÀÀµ´¦Àí´úÂë

tools/init.py

#!/usr/bin/env/python3
# -*- coding:utf-8 -*-
"""
@project: apiAutoTest
@author: zy7y
@file: __init__.py
@ide: PyCharm
@time: 2020/7/31
"""
import json
import re

import allure

from jsonpath import jsonpath
from loguru import logger


def extractor(obj: dict, expr: str = '.') -> object:
    """
    ¸ù¾Ý±í´ïʽÌáÈ¡×ÖµäÖеÄvalue£¬±í´ïʽ, . ÌáÈ¡×ÖµäËùÓÐÄÚÈÝ£¬ $.case Ìáȡһ¼¶×Öµäcase£¬ $.case.data ÌáÈ¡case×ÖµäϵÄdata
    :param obj :json/dictÀàÐÍÊý¾Ý
    :param expr: ±í´ïʽ, . ÌáÈ¡×ÖµäËùÓÐÄÚÈÝ£¬ $.case Ìáȡһ¼¶×Öµäcase£¬ $.case.data ÌáÈ¡case×ÖµäϵÄdata
    $.0.1 ÌáÈ¡×ÖµäÖеĵÚÒ»¸öÁбíÖеĵڶþ¸öµÄÖµ
    """
    try:
        result = jsonpath(obj, expr)[0]
    except Exception as e:
        logger.error(f'ÌáÈ¡²»µ½ÄÚÈÝ£¬¶ª¸øÄãÒ»¸ö´íÎó£¡{e}')
        result = None
    return result


def rep_expr(content: str, data: dict, expr: str = '&(.*?)&') -> str:
    """´ÓÇëÇó²ÎÊýµÄ×Ö·û´®ÖУ¬Ê¹ÓÃÕýÔòµÄ·½·¨ÕÒ³öºÏÊʵÄ×Ö·û´®ÄÚÈݲ¢½øÐÐÌæ»»
    :param content: ԭʼµÄ×Ö·û´®ÄÚÈÝ
    :param data: ÔÚ¸ÃÏîÄ¿ÖÐÒ»°ãΪÏìÓ¦×ֵ䣬´Ó×Öµäȡֵ³öÀ´
    :param expr: ²éÕÒÓõÄÕýÔò±í´ïʽ
    return content£º Ìæ»»±í´ïʽºóµÄ×Ö·û´®
    """
    for ctt in re.findall(expr, content):
        content = content.replace(f'&{ctt}&', str(extractor(data, ctt)))
    return content


def convert_json(dict_str: str) -> dict:
    """
    :param dict_str: ³¤µÃÏñ×ÖµäµÄ×Ö·û´®
    return json¸ñʽµÄÄÚÈÝ
    """
    try:
        if 'None' in dict_str:
            dict_str = dict_str.replace('None', 'null')
        elif 'True' in dict_str:
            dict_str = dict_str.replace('True', 'true')
        elif 'False' in dict_str:
            dict_str = dict_str.replace('False', 'false')
        dict_str = json.loads(dict_str)
    except Exception as e:
        if 'null' in dict_str:
            dict_str = dict_str.replace('null', 'None')
        elif 'true' in dict_str:
            dict_str = dict_str.replace('true', 'True')
        elif 'False' in dict_str:
            dict_str = dict_str.replace('false', 'False')
        dict_str = eval(dict_str)
        logger.error(e)
    return dict_str


def allure_title(title: str) -> None:
    """allureÖÐÏÔʾµÄÓÃÀý±êÌâ"""
    allure.dynamic.title(title)


def allure_step(step: str, var: str) -> None:
    """
    :param step: ²½Öè¼°¸½¼þÃû³Æ
    :param var: ¸½¼þÄÚÈÝ
    """
    with allure.step(step):
        allure.attach(json.dumps(var, ensure_ascii=False, indent=4), step, allure.attachment_type.TEXT)

tools/data_process.py

#!/usr/bin/env/python3
# -*- coding:utf-8 -*-
"""
@project: apiAutoTest
@author: zy7y
@file: data_process.py
@ide: PyCharm
@time: 2020/11/18
"""
from tools import logger, extractor, convert_json, rep_expr, allure_step
from tools.read_file import ReadFile


class DataProcess:
    response_dict = {}
    header = ReadFile.read_config('$.request_headers')
    have_token = header.copy()

    @classmethod
    def save_response(cls, key: str, value: object) -> None:
        """
        ±£´æÊµ¼ÊÏìÓ¦
        :param key: ±£´æ×ÖµäÖеÄkey£¬Ò»°ãʹÓÃÓÃÀý±àºÅ
        :param value: ±£´æ×ÖµäÖеÄvalue£¬Ê¹ÓÃjsonÏìÓ¦
        """
        cls.response_dict[key] = value
        logger.info(f'Ìí¼Ókey: {key}, ¶ÔÓ¦value: {value}')

    @classmethod
    def handle_path(cls, path_str: str) -> str:
        """·¾¶²ÎÊý´¦Àí
        :param path_str: ´øÌáÈ¡±í´ïʽµÄ×Ö·û´® /&$.case_005.data.id&/state/&$.case_005.data.create_time&
        ÉÏÊöÄÚÈÝ365ÌåÓýͶע£¬´ÓÏìÓ¦×ÖµäÖÐÌáÈ¡µ½case_005×ÖµäÀïdata×ÖµäÀïidµÄÖµ£¬¼ÙÉèÊÇ500£¬ºóÃæ&$.case_005.data.create_time& ÀàËÆ£¬×îÖÕÌáÈ¡½á¹û
        return  /511/state/1605711095
        """
        # /&$.case.data.id&/state/&$.case_005.data.create_time&
        return rep_expr(path_str, cls.response_dict)

    @classmethod
    def handle_header(cls, token: str) -> dict:
        """´¦Àíheader
        :param token: д£º дÈëtokenµ½headerÖУ¬ ¶Á£º ʹÓôøtokenµÄheader£¬ ¿Õ£ºÊ¹Óò»´øtokenµÄheader
        return
        """
        if token == '¶Á':
            return cls.have_token
        else:
            return cls.header

    @classmethod
    def handler_files(cls, file_obj: str) -> object:
        """file¶ÔÏó´¦Àí·½·¨
        :param file_obj: ÉÏ´«ÎļþʹÓ㬸ñʽ£º½Ó¿ÚÖÐÎļþ²ÎÊýµÄÃû³Æ:"Îļþ·¾¶µØÖ·"/["ÎļþµØÖ·1", "ÎļþµØÖ·2"]
        ʵÀý- µ¥¸öÎļþ: &file&D:
        """
        if file_obj == '':
            return
        for k, v in convert_json(file_obj).items():
            # ¶àÎļþÉÏ´«
            if isinstance(v, list):
                files = []
                for path in v:
                    files.append((k, (open(path, 'rb'))))
            else:
                # µ¥ÎļþÉÏ´«
                files = {k: open(v, 'rb')}
        return files

    @classmethod
    def handle_data(cls, variable: str) -> dict:
        """ÇëÇóÊý¾Ý´¦Àí
        :param variable: ÇëÇóÊý¾Ý£¬´«ÈëµÄÊÇ¿Éת»»×Öµä/jsonµÄ×Ö·û´®,ÆäÖпÉÒÔ°üº¬±äÁ¿±í´ïʽ
        return ´¦ÀíÖ®ºóµÄjson/dictÀàÐ͵Ä×ÖµäÊý¾Ý
        """
        if variable == '':
            return
        data = rep_expr(variable, cls.response_dict)
        variable = convert_json(data)
        return variable

    @classmethod
    def assert_result(cls, response: dict, expect_str: str):
        """ Ô¤ÆÚ½á¹ûʵ¼Ê½á¹û¶ÏÑÔ·½·¨
        :param response: ʵ¼ÊÏìÓ¦×Öµä
        :param expect_str: Ô¤ÆÚÏìÓ¦ÄÚÈÝ£¬´ÓexcelÖжÁÈ¡
        return None
        """
        expect_dict = convert_json(expect_str)
        index = 0
        for k, v in expect_dict.items():
            actual = extractor(response, k)
            index += 1
            logger.info(f'µÚ{index}¸ö¶ÏÑÔ,ʵ¼Ê½á¹û:{actual} | Ô¤ÆÚ½á¹û:{v} \n¶ÏÑÔ½á¹û {actual == v}')
            allure_step(f'µÚ{index}¸ö¶ÏÑÔ',  f'ʵ¼Ê½á¹û:{actual} = Ô¤ÆÚ½á¹û:{v}')
            assert actual == v

Ô´ÂëµØÖ·

master: ·Ö֧Ϊ×îдúÂë

version1.0: ·Ö֧Ϊ֮ǰ¿ªÔ´µÄ´úÂ루ͨ¹ý×Öµäµü´úµÄ·½Ê½À´´¦ÀíÊý¾ÝÒÀÀµ£©

Https://gitee.com/zy7y/apiAutoTest.git

Https://github.com/zy7y/apiAutoTest.git

ºóÐø´òËã

ĿǰÔÚ¹«Ë¾ÕýÔÚ×ö½Ó¿Ú²âÊÔ£¬ËµÊµ»°Ò²ÊÇÃþË÷×ÅÀ´£¬ÒÔÉϵÄÓÅ»¯Ïî¶¼ÊÇʵ¼Ê×öµÄ¹ý³ÌÖÐͻȻÏëµ½µÄ£¬È»ºó¾Í¸üÐÂÁË

  • ½ÓÈëÓÃÀýǰºóÖÃSQL£¬ ǰÖÃSQLĿǰÏëµÄÊÇÏÖÔÚÏîÄ¿ÖÐÓöµ½µÄÎÊÌ⣬ÓÐЩ½Ó¿ÚûÓзµ»ØÐèÒªµÄÊý¾Ý£¬ÕâÀï¾ÍÒªÓÃǰÖÃSQL²éѯµÄ½á¹û´«µ½ÇëÇóÊý¾ÝÀïÃæÁË£¬ºóÖÃSQLÖ÷ÒªÊÇÇëÇóºó²é¿´Êý¾Ý¿âÖеÄÊý¾ÝÊÇ·ñ±ä¶¯£¬ÐγÉÊý¾Ý¿â¶ÏÑÔ 2020/12/08 Íê³É £¬ ÖÁ´Ë apiAutoTest Ó¦¸Ã²»»á ÔÙÓдó¸üÐÂ~~~ лл ¿´Õâ¸öDemoµÄÈË
  • Æóҵ΢ÐÅÍÆËÍ£ºÄ¿Ç°ÏîÄ¿ÖÐÔ¤ÏëµÄЧ¹û£¬ÊǺó¶ËÈËÔ±Ìá½»´úÂ룬×Ô¶¯²¿ÊðÖ®ºó£¬Í¨¹ýgitlab-ci Æô¶¯²âÊÔ´úÂ룬½øÐнӿڲâÊÔÍê³ÉÖ®ºó²É¼¯allureÖеIJâÊÔ½á¹ûÒ»ÓÐÒì³£/ʧ°ÜÓÃÀý¾Í·¢ËÍÓʼþ²¢½øÐÐÆóҵ΢ÐÅÍÆË͸øÁìµ¼ Õâ¸öÆäʵ¾ÍÊÇÖØÐ·¢ËÍÇëÇó~
  • .... ¾Í²»ËµÁË»¹ÓкܶàÓÅ»¯ÏÄÜÁ¦²»¹»ºÃºÃ³äµç°É£¬¡«¡«

ÖÂл

лл¸÷λ¶ÔapiAutoTestµÄ°ïÖú£¬Ð»Ð»¡«¡«¡«

posted @ 2020-11-23 00:00  zy7y  ÔĶÁ(454)  ÆÀÂÛ(3±à¼­  ÊÕ²Ø