HttpRunner3.x 源码解析(5)-runner.py

首先看下生成的pytest文件

from httprunner import HttpRunner, Config, Step, RunRequest, RunTestCase


class TestCaseLogin(HttpRunner):

    config = (
        Config("登录成功").variables(**{"password": "tester", "expect_foo2": "config_bar2"}).base_url("https://api.pity.fun")
        .verify(False)
        .export(*["token"])
    )

    teststeps = [
        Step(
            RunRequest("登录成功")
            .with_variables(**{"foo1": "bar1"})
            .setup_hook("${get_request($request)}")
            .post("/auth/login")
            .with_headers(**{"Content-Type": "application/json"})
            .with_json({"username": "${ENV(username)}", "password": "${ENV(password)}"})
            .teardown_hook("${get_reponse($response)}")
            .extract()
            .with_jmespath("body.msg", "token")
            .validate()
            .assert_equal("status_code", 200)
            .assert_equal("body.code", 0)
            .assert_equal("body.msg", "哈哈哈")
        ),
    ]


if __name__ == "__main__":
    TestCaseLogin().test_start()

首先类继承了HttpRunner类

主要包括config和teststeps两部分

函数的入库是test_start()方法

test_start

  def test_start(self, param: Dict = None) -> "HttpRunner":
        """main entrance, discovered by pytest"""
        self.__init_tests__()
        self.__project_meta = self.__project_meta or load_project_meta(
            self.__config.path
        )
        self.__case_id = self.__case_id or str(uuid.uuid4())
        self.__log_path = self.__log_path or os.path.join(
            self.__project_meta.RootDir, "logs", f"{self.__case_id}.run.log"
        )
        log_handler = logger.add(self.__log_path, level="DEBUG")

        # parse config name
        config_variables = self.__config.variables
        if param:
            config_variables.update(param)
        config_variables.update(self.__session_variables)
        self.__config.name = parse_data(
            self.__config.name, config_variables, self.__project_meta.functions
        )

        if USE_ALLURE:
            # update allure report meta
            allure.dynamic.title(self.__config.name)
            allure.dynamic.description(f"TestCase ID: {self.__case_id}")

        logger.info(
            f"Start to run testcase: {self.__config.name}, TestCase ID: {self.__case_id}"
        )

        try:
            return self.run_testcase(
                TestCase(config=self.__config, teststeps=self.__teststeps)
            )
        finally:
            logger.remove(log_handler)
            logger.info(f"generate testcase log: {self.__log_path}")

首先调用了__init_tests__()方法

 teststeps是pytest文件中的Step列表,示例只有1个步骤。

 

config.perform方法返回了一个Tconfig对象,这个对象定义了testcase的config中的关键字和内容

 

teststeps是py文件中的Step列表,

调用的step.perform()方法,返回__step_context,而__step_context来自step_context调用perfoem方法。

在Step类的初始化函数可以看到,step_context可以是如下几种

 

当step_contxt时RunTestCase时,调用它的perfom方法如下,可以看到返回的是一个TStep对象。

 

 接着看test_start()

self.__project_meta = self.__project_meta or load_project_meta(
    self.__config.path
)

 返回项目的资源文件

self.__case_id为caseid或者是一个uuid
self.__log_path为日志目录
config_variables = self.__config.variables为config部分的变量
self.__config.name = parse_data(
    self.__config.name, config_variables, self.__project_meta.functions
)获取config中的name
if USE_ALLURE:
    # update allure report meta
    allure.dynamic.title(self.__config.name)
    allure.dynamic.description(f"TestCase ID: {self.__case_id}")

logger.info(
    f"Start to run testcase: {self.__config.name}, TestCase ID: {self.__case_id}"
)

如果用了allure报告,则定义title和描述

 

return self.run_testcase(
    TestCase(config=self.__config, teststeps=self.__teststeps)
)

将config和teststeps列表传给TestCase并调用HttpRunner类的run_testcase方法执行用例

run_testcase

这个方法最后返回的也是HttpRunner实例

主要的是下面这一句,执行了用例的步骤。

extract_mapping = self.__run_step(step)

 __run_step方法

如果步骤中存在request,则调用__run_step_request来执行步骤,并返回返回testdata

如果存在testcase,则调用__run_step_testcase(step)来执行,最后返回test_data

    def __run_step(self, step: TStep):
        """run teststep, teststep maybe a request or referenced testcase"""
        logger.info(f"run step begin: {step.name} >>>>>>")

        if step.request:
            step_data = self.__run_step_request(step)
        elif step.testcase:
            step_data = self.__run_step_testcase(step)
        else:
            raise ParamsError(
                f"teststep is neither a request nor a referenced testcase: {step.dict()}"
            )

        self.__step_datas.append(step_data)
        logger.info(f"run step end: {step.name} <<<<<<\n")
        return step_data.export_vars

__run_step_request

这个方法解析request并调用request方法来执行

resp = self.__session.request(method, url, **parsed_request_dict)

 

parsed_request_dict解析请求字典

parsed_request_dict

{'method': 'POST', 'url': '/auth/login', 'params': {}, 'headers': {'Content-Type': 'application/json'}, 'req_json': {'username': 'tester', 'password': 'tester'}, 'data': None, 'cookies': {}, 'timeout': 120, 'allow_redirects': True, 'verify': False}

if step.setup_hooks:
    self.__call_hooks(step.setup_hooks, step.variables, "setup request")

如果存在setup_hooks就调用hook

 

 

# teardown hooks
if step.teardown_hooks:
    self.__call_hooks(step.teardown_hooks, step.variables, "teardown request")

如果存在teardown就调用hook

 最后返回step_data

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/16897.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

4.4.1内核编译

内核源码下载地址&#xff1a; https://mirrors.edge.kernel.org/pub/linux/kernel/v4.x/linux-4.4.1.tar.gz 安装依赖包&#xff1a;报错就装 cp /boot/config-xxx ./.config make mrproper make menuconfig,然后save保存&#xff0c;退出 make -j4 //四线程编译 sudo ma…

Java基础(十六)泛型

1. 泛型概述 1.1 生活中的例子 举例1&#xff1a;中药店&#xff0c;每个抽屉外面贴着标签 举例2&#xff1a;超市购物架上很多瓶子&#xff0c;每个瓶子装的是什么&#xff0c;有标签 举例3&#xff1a;家庭厨房中&#xff1a; Java中的泛型&#xff0c;就类似于上述场景中的…

计算机视觉的应用4-目标检测任务:利用Faster R-cnn+Resnet50+FPN模型对目标进行预测

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用4-目标检测任务&#xff0c;利用Faster RcnnResnet50FPN模型对目标进行预测&#xff0c;目标检测是计算机视觉三大任务中应用较为广泛的&#xff0c;Faster R-CNN 是一个著名的目标检测网络&#x…

【Java校招面试】基础知识(六)——计算机网络

目录 前言一、TCP协议 / UDP协议二、HTTP协议后记 前言 本篇主要介绍计算机网络的相关内容。 “基础知识”是本专栏的第一个部分&#xff0c;本篇博文是第六篇博文&#xff0c;如有需要&#xff0c;可&#xff1a; 点击这里&#xff0c;返回本专栏的索引文章点击这里&#xf…

操作系统——操作系统逻辑结构

0.关注博主有更多知识 操作系统入门知识合集 目录 2.1操作系统的逻辑结构 思考题&#xff1a; 2.2CPU的态 思考题&#xff1a; 2.3中断机制 2.1操作系统的逻辑结构 操作系统的结构指的是操作系统的设计和实现思路&#xff0c;按照什么样的结构设计、实现。 操作系统的…

公司新来的00后真是卷王,工作没2年,跳槽到我们公司起薪18K都快接近我了

说00后躺平了&#xff0c;但是有一说一&#xff0c;该卷的还是卷。这不&#xff0c;前段时间我们公司来了个00后&#xff0c;工作都没两年&#xff0c;跳槽到我们公司起薪18K&#xff0c;都快接近我了。后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了。 …

通过Python的PIL库给图片添加图片水印

文章目录 前言一、素材准备1.原图2.水印图 二、使用PIL库给图片添加图片水印1.引入库2.定义图片路径3.打开原图4.打开水印图片5.计算水印图片大小6.计算原图大小7.调整水印图片大小7.1调整前7.2调整后 8.计算水印图片位置8.1左上8.2左下8.3右上8.4右下8.5中间 9.添加水印10.保存…

Doris(20):Doris的函数—数学函数

1 查看函数名 show builtin functions in test_db; 2 abs(double a) 功能: 返回参数的绝对值 返回类型:double类型 使用说明:使用该函数需要确保函数的返回值是整数。 3 acos(double a) 功能: 返回参数的反余弦值 返回类型:double类型 MySQL 中反余弦函数 ACOS(…

数据库基础及用户管理授权

数据库概念 关系型数据库 数据结构二维表格 库 -> 表 -> 列&#xff08;字段&#xff09;&#xff1a;用来描述对象的的一个属性&#xff1b;行&#xff1a;用来描述一个对象的信息 mysql&#xff08;5.7/8.0&#xff09; maridb ocracle postgresql sqlserver(windows…

196页11万字智慧水务平台建设方案

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用&#xff0c;如有侵权请联系删除。 业务需求分析 3.1 主要业务描述 &#xff08;1&#xff09;调度中心主要业务描述 配套工程调度中心为一级调度机构&#xff0c;同时也是水务集团原水供水的统一调度中心。…

Iron Web Scraper 2023.4.13 Crack

Iron Web Scraper 被认为是 C# 的互联网抓取库&#xff0c;它能够让用户和开发者激发和最终的个人浏览行为&#xff0c;以提取文件、内容甚至图片和应用程序。动词作为 .NET 的本机项。IronWebScraper 具有从后台处理礼貌和多线程进程的能力&#xff0c;这使得用户程序很容易简…

SpringCloud学习(七)——统一网关Gateway

文章目录 1. 网关介绍2. 网关搭建2.1 引入依赖2.2 创建启动类2.3 编写配置2.4 测试 3. 路由断言工厂4. 路由过滤器4.1 过滤器配置4.2 全局过滤器4.3 过滤器执行顺序 5. 跨域问题处理 1. 网关介绍 到现在&#xff0c;我们可以使用Nacos对不同的微服务进行注册并管理配置文件&am…

天气预报查询 API 提供个性化的天气服务的设计思路

引言 假设你是一个开发人员或公司&#xff0c;正在考虑开发一款天气应用程序&#xff0c;但你意识到市场上已经有很多竞争者在使用天气预报查询 API 来提供类似的服务&#xff0c;本文将一起探寻一些创新的方法来提高应用程序的竞争力。 扩大竞争力的一些建议 如果市面上已经…

Redis主从复制和哨兵模式

Redis主从复制 概念 主从复制&#xff0c;是指将一台Redis服务器的数据&#xff0c;复制到其他的Reds服务器。前者称为主节点(master / leader),后者称为从节点(slave / follower)。 数据的复制是单向的&#xff0c;只能由主节点到从节点。 Master以写为主&#xff0c;Slave…

spring2:创建和使用

目录 1.创建Spring项目 1.1创建Maven类 1.2添加Spring支持框架 1.3添加启动类 2.存储Bean对象 2.0 spring项目中添加配置文件(第一次) 2.1创建Bean 2.2把Bean注册到容器中 3.获取并使用Bean对象 3.1创建上下文 3.2获取指定Bean对象 getBean()方法 --> 获取什么…

Flutter 组件抽取:日期(DatePicker)、时间(TimePicker)弹窗选择器【仿照】

简介 仿照《Flutter 仿ios自定义一个DatePicker》实行的日期弹窗选择器&#xff08;DatePicker&#xff09;、时间弹窗选择器&#xff08;TimePicker&#xff09; 效果 范例 class _TestPageState extends State<TestPage> {overridevoid initState() {super.initStat…

ros基础笔记

1创建工作空间 catkin_init_workspace 将文件夹初始化成ros文件 编译工作空间catkin_make vi ~/.bashrc 加入环境变量bashrc一下在任何终端都生效 catkin_create_pkg learning_communication通讯机制 std_msgs数据结构 rospy roscpp catkin_create_pkg mbot_description ur…

SpringBoot实现导出Excel功能

1 问题背景 需求要做一个导出excel的功能 2 前言 本篇着重阐述后端怎么实现&#xff0c;前端实现的部分只会粗略阐述。该实现方案是经过生产环境考验的&#xff0c;不是那些拿来练手的小demo。本文阐述的方案可以借鉴用来做毕设或者加到自己玩的项目中去。再次声明&#xff0c;…

题目 3166: 蓝桥杯2023年第十四届省赛真题-阶乘的和--不能完全通过,最好情况通过67.

原题链接&#xff1a; 题目 3166: 蓝桥杯2023年第十四届省赛真题-阶乘的和 https://www.dotcpp.com/oj/problem3166.html 致歉 害&#xff0c;首先深感抱歉&#xff0c;这道题还是没有找到很好的解决办法。目前最好情况就是67分。 这道题先这样跳过吧&#xff0c;当然以后还…

day9 实现UDP通信

目录 socket函数拓展 UDP通信实现过程 代码实现 socket函数拓展 send与recv函数&#xff1a; /*用于发送数据*/ ssize_t send(int sockfd, const void *buf, size_t len,int flags);/*用于接收数据*/ ssize_t recv(int sockfd, void *buf, size_t len,int flags);/*前三个…