js修改id的值_如何修改pytesthtml源码来优化接口自动化测试报告

b082dc966a2fa7d1c1fb1cc61ed19d71.gif

你这么优秀,一定只想把“柠檬班”置顶

前言

大家好,我是柠檬班Python6期的学员小翟。

以前常用unittest做接口自动化测试,后来想获取单个接口的响应时间,便采用pytest单元测试框架。

虽然获得的时间不太准确。

因为pytest测试报告的时间是从一个用例开始到结束,其中包括了断言,所以实际时间比响应时间略长。

如果从参考的角度看,这个时间虽然不是很准确,但仍有价值。

Pytest与ddt冲突

如果你想使用pytest,就不能使用ddt做数据驱动了,否则运行时会抛出异常。

提示@data不是pytest的一个fixture


这时可以使用pytest的参数化,即下面这种形式:

f8813e4be4a6f8aef423c32867bd0cc2.png

一般来说,使用最多的是前两个参数,argnames和argvalues。

argnames:用逗号分隔的字符串,表示一个或多个参数名或参数列表/元组。

argvalues:是一个列表,让前面的参数argnames依次从中取值用于迭代

4eaa9275be610974c1e7130ed434efa8.png

这样的话,我们就解决了第一个问题。

即用pytest参数化来代替unittest的数据驱动。

测试报告中的用例名字不规范

迫不及待的点了运行,突然发现测试报告中的用例名字很糟糕,这是什么鬼,为什么会这样写?

d395ef37c491682df42258fe43b67663.png

97ab44e41b8e1eda0667ee065d51dfb1.png

这样的测试用例名字,第一眼让人感觉很凌乱,因为根本看不出是哪条接口的。

如果能将测试用例中的case_id对应的值作为用例名字就比较完美了:

c043ba01b370e80210eb6f9c9c4048e5.png

当时我的第一思路是,先去看看测试报告的元素。

ce8e49b849ead6e671c5ce7c84002165.png

这个用例名字的元素对应的标签的td。

对应的class属性值是"col-name"。

那能不能去pytest-html的源码中看看在哪一块。

2bf07ed4bfd325c763f59d6e7ba147c5.png

在其他地方没有找到,但在plugin.py中找到了,可以看到找到了一个,没错就是我们想要的td标签。

那么还有一个参数self.test_id是什么?

大胆的猜测一下,应该是td标签对应的文本值吧。

4c4cfbc0eda293a69aaa8daea055c886.png

既然要改变td标签的文本值,现在已经猜测是self.test_id对应的值。

接下只需搜索一下self.test_id是怎么定义的,一切便迎刃而解!


图1:

3c8ec21daef95cd912f25ee3bb7d5d74.png

图2:

7f529617049e141e908147f0b0a331bb.png

图3:

d1295c39e965c8a67339d22c020e1d99.png

但是真的这么简单吗?

请看上图,一共找到了4个self.test_id。

除了刚刚我们找的那个,有2个和report.nodeid有关。

有1个和extra_index和test_index有关,report.nodeid可能是report的一个属性。

而后面两个参数是crate_asset的两个形参,这些东西我们能直接获取到吗?

看到这里,感觉第一个思路错了,至少是方向有问题!

想想之前,在做unittest的时候,ddt通过修改源码改变用例名字。

ddt修改时并不是去HTMLTestRunner中修改的。

同理,我们推断下,pytest要修改用例名字,关注点应该是参数化,而不是pytest-html的源码。

ed447087a2f3e03f47d6c8d98102c183.png

这样就获得了第二个思路,去查看parametrize()这个函数的源码。

查看源码

在查看源码过程中,偶然看到另一个函数是这样定义的:

8a01b440801d99128e39076dbcdae0f4.png

特别是ids[index] = testid + str(counters[testid]),是不是特别熟悉?

对了,这个就是测试报告里的[data0],[data1]...

而且看看counters的怎么定义的,参数是匿名函数lambda,默认是从0开始。

看到这里,大概就比较清楚了,我们最重要的关注点应该是ids,而ids恰好是parametrize()函数的一个参数。

15479d40ee911915b32dd575416f921f.png

源码给出的解释是:ids是一个字符串列表或可调用的字符串。

如果是字符串列表,则每个字符串对应argvalues,它们是测试id的一部分。

如果是None,则会使用自动生成的id。如果是可调用的...

看这么两句就可以了,如果是None,会自动生成用例名字(测试id就是我们说的用例名字),也就是我们看到的[data0],[data1]...。

如果有100条用例,那么第100条的用例名字就是[data99]。

如果是列表,会将列表中的每一次迭代的值作为用例名字

这下我们知道如何修改用例名字了。

直接给@pytest.mark.parametrize()添加ids参数就行。

2501a6aeb0ca808bcfec7e574673a94a.png

利用JS优化测试用例名字

经过第二步的优化,我们满足了最基本的需求。

即想要的用例名字必须是测试用例里自己定义的,而不是一系列默认生成的值。

c5399a49e8b658ad28e194262544be74.png

但问题又来了,看报告中前面一长串,真的很不美观。

如何去掉前面的

TestCases/test_my_requests.py::TestMyRequests::test_send_requests。

首先考虑去源码里直接定位,但根据之前的经验,源码里这一串可能就是一个属性的值,你能得到的无非就是类似于report.属性的这种方式。

何况,在对pytest和pytest-html运行原理不了解的前提下,这样无疑在浪费时间

这时看到了js,pytest所在位置的resources目录下有个main.js。

我们可以通过js来修改td标签中的文本内容。

2f31cf57bbd11497752741c9d324be31.png

可以在main.js定义一个函数change_testName()。

提取字符串

通过split()方法来提取字符串 

TestCases/test_my_requests.py::TestMyRequests::test_send_requests[checkUpdate_normal]中的checkUpdate_normal。

当然你也可以用正则

ad804e546497b177ab02eb5238f1d92e.png

pytest-html加载js的原理是,它会将resources目录下的main.js中加载到最终的html测试报告的中。

这是生成的html报告源码:

28b0f4004f2058dcda2adcc5cd532012.png

642a2a2de853e4ec97acfa1bf16dabde.png

既然不需要我们主动引入js,只要在main.js中定义好函数就行,但是却发现好像自定义的js函数不起作用。

此道不通,必须换另一条道。

既然main.js中定义了那么多js函数,我们是否可以将自定义的js语句放到一个已知的函数里面。

当然前提是变量不能有重名,不能影响已知函数的功能。

找来找去,发现了有个疑似初始化的函数init()。

所以放在这个函数里比较合适

7852ff8f0cdc26400aa19513d03a5c4e.png

调整之后的init函数

1db804a9b27e7d871511ebab1f468f46.png

大功告成:还差点什么

经过运行之后,发现我们的目的已经达到,既可以获得单个接口的测试时间,又调整了用例名字。

比原来美观多了 唯一的建议修改源码,最好使用pipenv创建一个虚拟环境。

因为多个项目之间共用pytest-html的话,一旦修改了pytest-html源码中的js,那么所有的项目样式都会变。

为了保持多个项目依赖库之间不受干扰,请使用虚拟环境。

d3e23c3f2a7d1f9e45920c969fb5ff5f.png

这样,我们的修改就完成了吗?

请仔细看我们添加的js代码:

a3d7955cf11727fb99fec271cbf77ba0.png

诚然,当参数化的时候,它没有问题。

可是有的场景我们不需要参数化,比如设计一个test_update_normal的测试用例

c259895be36db85ee6dca038555a67c1.png

得到的测试报告是这样的:

7373b1b2cead276ac0431eb1b504e941.png

有没有一种很丑的感觉,第3条用例的名字不符合我们的要求。

这是因为参数化生成的用例名字包含[],所以我们才能用js对[]做分割,不使用参数化的用例没有[],这时候再去调用js就抛异常了,等于什么都没改变

既然js有异常行为,相应的就该有捕获异常的方法。

try...catch这时候可以用起来了,捕获异常,再对异常情况添加处理方式

e39f7c081fb8beb5eb37dde4b8d3a832.png

再次生成的测试报告长这样子:

146a6297ed44153e62d6730c653ece9e.png

这时感觉用例名字标准多了,我们修改源码。

不但要达到基本目的,更重要的是维护源码的健壮性。

如果因为修改引起的源码只能在少数情况下使用,那么这样做等于是破坏。

另外,再次说明一下,请在虚拟环境下尝试源码修改。

891c1a461b426694acd19ad7fec0c5b5.png

5af553333900372f76a15cbcc40b32cb.png 

今日福利

需要接口自动化测试环境搭建学习视频

可加小米老师微信:

13327316731

暗号:公众号

a9a3b2ba18f42fd99e04231e54482325.png

494003091224a29824e3c6fecb693938.png

1582b120f02d948e4de327cd9a7eb2b7.png

7ce6a2e533bb5001d8bf2123eb9cea64.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java接口自动化测试是指利用Java编程语言来编写测试代码,通过调用接口的方式来对软件或系统进行自动化测试。 在进行Java接口自动化测试时,我们可以使用各种开源的测试框架和工具,例如JUnit、TestNG、RestAssured等,这些工具提供了丰富的API和功能,可以方便地进行接口测试的编写和执行。 接口自动化测试源码主要包括以下几个方面: 1. 导入相关的测试框架和工具库:在Java源码中,我们需要导入相应的依赖库,以及测试框架和工具库。例如,可以使用Maven或Gradle构建工具来管理项目依赖,并在配置文件中添加所需的库。 2. 编写测试用例:测试用例是接口自动化测试的核心部分。通过使用测试框架提供的API和注解,我们可以轻松地编写测试用例代码。测试用例通常包括预期结果、实际结果和断言等内容,以验证接口的正确性。 3. 发送HTTP请求:接口测试需要发送HTTP请求,并获取接口的响应结果。可以使用Java的HttpURLConnection或HttpClient等库来发送GET、POST、PUT等不同类型的请求,并获取响应内容。在代码中可以设置请求参数、请求头、请求体等信息。 4. 解析响应内容:接口响应通常是一个JSON格式的字符串或XML格式的数据。我们可以使用JSON解析库(如Jackson、Gson等)或XML解析库(如DOM、SAX等)来解析响应数据,并提取需要验证的字段或属性。 5. 断言和验证:在接口测试中,我们需要对接口的返回结果进行断言和验证。通过使用断言库(如AssertJ、JUnit提供的assert方法等),我们可以对返回结果进行判断,判断是否符合预期或预期条件。 6. 执行和报告:最后,我们需要执行测试用例,并生成测试报告来展示测试结果。测试框架和工具库通常提供了执行和报告的功能,可以通过命令行或插件的方式执行测试,并生成测试报告。 总结起来,Java接口自动化测试源码涵盖了导入依赖库、编写测试用例、发送HTTP请求、解析响应内容、断言验证、执行和报告等多个方面的代码实现。有效的源码设计和编写可以提高接口测试的效率和质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值