首页 > 编程语言 >ast获取指定python文件中携带指定装饰器函数的实现

ast获取指定python文件中携带指定装饰器函数的实现

时间:2024-07-27 17:40:27浏览次数:7  
标签:node name ast python 指定 用例 test class def

在实现自动化测试过程中,需要根据指定的装饰器来标记需要执行的用例或函数,下面根据使用ast库来实现读取指定文件中的数据结构后对其内容进行解析并拿到携带对应装饰器的函数。
根据以下方法仅能解析func、class-func的数据结构,其余数据结构可能不兼容,需要根据实际情况进行完善调整。

# 被解析文件
import pytest

from AutoTestMain.common.MyDecorator import sj_auto
from libs.sj_logger import logger


class Test01:
    @sj_auto(case_name="自动化用例1")
    @pytest.mark.smoke
    def test_01(self, args, kwargs):
        raise ValueError("test1")
        print("执行了类函数用例1")

    @sj_auto(case_name="自动化用例7")
    @pytest.mark.smoke
    def test_07(self, args, kwargs):
        print("执行了类函数用例7")


def setup():
    print("模块内所有用例执行前需要执行的内容")


def teardown():
    print("模块内所有用例执行完毕后需要执行的内容")


class Test02:

    def setup_class(self):
        print("在类内所有案例执行前执行内容")

    def teardown_class(self):
        print("在类内所有案例执行完成后执行的内容")

    def setup_method(self):
        print("在执行用例前执行的代码")

    def teardown_method(self):
        print("在执行用例后执行的代码")

    @sj_auto(case_name="自动化用例2", case_level="P0")
    @pytest.mark.smoke
    def test_02(self, test1: str, except_result):
        logger.info(f"执行了用例:{test1}")
        logger.info(f"对比了预期:{except_result}")

    @sj_auto(case_name="自动化用例4", case_level="P0")
    @pytest.mark.smoke
    def test_04(self, test1: str, except_result):
        logger.info(f"执行了用例:{test1}")
        logger.info(f"对比了预期:{except_result}")

    @sj_auto(case_name="自动化用例5", case_level="P0")
    @pytest.mark.smoke
    def test_05(self, test1: str, except_result):
        logger.info(f"执行了用例:{test1}")
        logger.info(f"对比了预期:{except_result}")


@sj_auto(case_name="自动化用例3", case_level="P1")
@pytest.mark.smoke
@pytest.mark.skip(reason="不想执行")
def test_03(test1: str, test2: int):
    """
    测试使用的用例
    :param test1:
    :param test2:
    :return:
    """
    logger.info("执行了用例3")


@sj_auto()
@pytest.mark.smoke
@pytest.mark.skip(reason="不想执行")
def test_06(test1: str, test2: int):
    """
    测试使用的用例
    :param test1:
    :param test2:
    :return:
    """
    logger.info("执行了用例6")


@pytest.mark.smoke
@pytest.mark.usermanage
def test_04():
    print("执行了用例1")

# 解析函数
import ast

from libs.sj_logger import logger


def find_decorated_functions(file_path, decorator_name):
    with open(file_path, 'r', encoding='utf-8') as f:
        source_code = f.read()
    tree = ast.parse(source_code)
    decorated_functions = []
    tree_parse(tree, decorated_functions, decorator_name)
    logger.info(f"获取到指定装饰器目录结构:{decorated_functions}")
    return decorated_functions


def tree_parse(tree, decorated_functions, decorator_name, class_name=None, class_check=0):
    """当前仅处理func、class-func类型的数据,如有使用其他层级结构的情况,当前会处理异常"""
    for node in tree.body:
        if isinstance(node, ast.FunctionDef):
            if any((isinstance(decorator, ast.Name) and decorator.id == decorator_name) or (
                    isinstance(decorator, ast.Call) and decorator.func.id == decorator_name) for
                   decorator in node.decorator_list):
                node_info = {"class_name": None, "funcs_name": []}
                if class_name is not None:
                    class_check += 1
                    node_info["class_name"] = class_name
                # 如果是0,则说明不是class结构,则直接添加到装饰器目录结构
                if class_check == 0:
                    node_info["funcs_name"].append(node.name)
                    decorated_functions.append(node_info)
                else:
                    # 说明是第一次进入一个类,直接将对应数据记录到装饰器目录结构
                    if class_check == 1:
                        node_info["funcs_name"].append(node.name)
                        decorated_functions.append(node_info)
                    # 说明是多次进入一个类,需要从已有的装饰器目录结构中拿到同类的数据
                    else:
                        for node_tree in decorated_functions:
                            if node_tree["class_name"] == class_name:
                                node_tree["funcs_name"].append(node.name)
                                break
        elif isinstance(node, ast.ClassDef):
            class_name = node.name
            class_check += 1
            tree_parse(node, decorated_functions, decorator_name, class_name)
            # 说明一个class已经处理完成,需要还原class_name
            class_check = 0
            class_name = None
        else:
            # 其他的可能是import之类的,无需处理
            pass


if __name__ == '__main__':
    case_path = r"D:\MyCode\AjTmp\backend\AutoTestMain\PyCase\test_demo.py"
    functions = find_decorated_functions(case_path, decorator_name="sj_auto")
    # print(functions)

执行结果:

[
    {
        "class_name": "Test01",
        "funcs_name": [
            "test_01",
            "test_07"
        ]
    },
    {
        "class_name": "Test02",
        "funcs_name": [
            "test_02",
            "test_04",
            "test_05"
        ]
    },
    {
        "class_name": null,
        "funcs_name": [
            "test_03"
        ]
    },
    {
        "class_name": null,
        "funcs_name": [
            "test_06"
        ]
    }
]

标签:node,name,ast,python,指定,用例,test,class,def
From: https://www.cnblogs.com/T-Ajie/p/18327262

相关文章

  • python—pandas基础(1)
    文章目录安装设定系统环境Pandas的主要数据结构Series对象创建使用列表创建属性values和index指定index使用list列表指定index传入字典创建,默认将key作为index将一个标量与index对象一起传入创建DataFrame对象创建创建DataFrame对象valuesindexcolumns属性列表创建索......
  • Python毕业设计基于Django的网上购物销售系统(代码+数据库+文档LW+运行成功)
    文末获取资源,收藏关注不迷路文章目录一、项目介绍二、主要使用技术三、研究内容四、核心代码五、文章目录一、项目介绍随着互联网技术的不断发展和普及,电子商务行业迅速崛起。越来越多的消费者选择在线购物,享受便捷、快速的购物体验。因此,开发一款基于Python的购物......
  • python毕业设计基于Django的电子书阅读系统的设计与实现 爬虫+大屏可视化
    文末获取资源,收藏关注不迷路文章目录一、项目介绍二、主要使用技术三、研究内容+四、核心代码五、文章目录一、项目介绍随着互联网的普及和移动设备的广泛应用,人们获取信息和阅读的方式发生了巨大变化。传统的纸质书籍阅读方式虽然经典,但存在携带不便、更新速度慢等......
  • python_wholeweek2
    目录编码方式open函数的使用open进行写入时有关于编码解码前面的open函数使用加了一个r绝对路径和相对路径的使用open函数的几种modewithopen的使用(对比open函数而言补充知识点,之前用过replace但是给忘了附加对于python识别文本时的编码错误链接解释编码方式​ txt文件的编码方......
  • Python 与 Visual Studio Professional 2022(64 位)- 预览版本 5.0 交互窗口挂起
    我正在MicrosoftVisualStudioProfessional2022(64位)-预览版17.11.0预览版5.0上运行Python开发工作负载。我正在关注VisualStudio中的Python教程https://learn.microsoft.com/en-us/visualstudio/python/tutorial-working-with-python-in-visual-studio-st......
  • Python面试宝典第19题:最小路径和
    题目        给定一个包含非负整数的mxn网格grid,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。说明:每次只能向下或者向右移动一步。        示例1:输入:grid=[[1,3,1],[1,5,1],[4,2,1]]输出:7解释:因为路径1→3→1→1→1的总......
  • 基于python的出租车管理网站的设计与实现【源码+文档+PPT】
    ......
  • 如何在Linux上的python中以后台模式打开程序?
    我需要在Linux上以后台模式使用python打开另一个程序。我尝试过subprocess.call("yourcommand")但它不是后台模式。并且os.startfile("file")在Linux上不起作用。请帮助我。可以使用Python的subprocess模块在Linux上以后台模......
  • 【学习笔记】Matlab和python双语言的学习(TOPSIS法)
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、TOPSIS法1.模型原理2.基本步骤(1)原始矩阵正向化(2)正向矩阵标准化(3)计算得分并归一化二、代码实现----Matlab1.主程序2.正向化处理函数3.极小型正向化函数4.中间型正向化函数5.区间型正向化......
  • 基于Python flask 的豆瓣电影top250数据评分可视化
    跟着CSDN上学习一下爬虫和简单的可视化分析,最后完成了一个简单的小项目。1.项目简介        基于Pythonflask的豆瓣电影评分可视化。通过采用Python编程语言,使用flask框架搭建影视系统,并使用相关技术实现对豆瓣网站的爬取、数据存储和可视化分析。2、成果展示:......