Pytest单元测试框架:简单好用的参数化以及多种运行模式

单元测试框架,大家较为熟悉的有 Unittest、Nose(unittest 的扩展)。Pytest 倒是名不见经传,但是自从用了之后,就爱不释手,就像它自己描述的一样:simple powerful testing with Python。简单好用的参数化以及多种运行模式,让测试脚本简单清晰,调试运行更加方便。

一、参数化

比如我们在做自动化测试,当传入不同的参数时,期望返回的status code为200。如果用 Unittest做这块参数化比较复杂,而 pytest 会简单很多。在pytest中有pytest.mark.parametrize装饰器,轻松解决问题。我们就拿sogo的搜索作为例子。

用例说明:

步骤一、打开搜狗搜索(http://www.sogou.com/)

步骤二、输入tesla后点放大镜搜索

期望:返回正常

如果用接口来做的话,就相当于在query参数后面传tesla即可,验证状态码为200

如果用接口来做的话,就相当于在query参数后面传tesla即可,验证状态码为200

Import requests

Session = requests.session()

url = 'https://www.sogou.com/web?'

para = {'query': 'tesla'}

r = session.get(url, params=para, verify=False, allow_redirects=False)

assert r.status_code == 200

事实上,如果仅仅传一个搜索词就认为这个接口正常,那么很可能就出大篓子。所以我们可能需要传n个搜索词做验证。也就是说,para中的query后面的内容我们需要传多个不同的搜索词。比如说我们想搜索VR,BITCOIN等多个词的话,需要怎么做呢?

这个时候就是使用pytest中有pytest.mark.parametrize装饰器,如下代码第8行,通过在方法外面加一个装饰器就可以了。

Import pytest

Import requests

Session = requests.session()

url = https://www.sogou.com/web?'

search= ['tesla','VR','BITCOIN']

@pytest.mark.parametrize('test_input',search)

def test_status_code(test_input):

para = {'query':test_input}

r= session.get(url,params=para, verify=False, allow_redirects=False)

assert r.status_code == 200

此时有可能有同学提出疑问,对于多个参数我们用for循环也是可以做的,为何要用这个方法。原因是用pytest的参数化,传入的一个参数就是一个case,上面的例子我们传入了三个参数,那么形成的就是三个cases,哪个参数传入导致出错了,我们一目了然。那么要怎么做呢?我们在cmd里面运行脚本,假设脚本文件名为test_sogo_search.py,位置放在C盘下:

C:\>pytest test_sogo_search.py --html=./result/Report.html

在pytest的报告中你看到的是这样的

通过这样的报告,就能很清晰的知道哪个搜索词的验证结果是正确,哪个搜索词验证的结果是错误的。比起用for循环来说,是要清晰很多了。另外还有运行的时长,也是能给到额外的信息。

二、运行模式

Pytest的多种运行模式,让测试和调试变得更加得心应手,下面介绍5种用的比较多的模式。在介绍之前需要提醒一句,运行pytest时会找test开头的文件以及以test开头的方法或者class,不然就会提示找不到可以运行的case了。

1、运行后产生结果报告(htmlReport)

运行模式:

pytest test_case.py --html=./result/test_caseReport.html

效果:

当运行出错时,在report里能直观的看到错误原因,上图中,预期希望的status_code是302,但是实际是 200,所以就报错了。看着报告定位问题就变的非常容易。且测试结果不用整理,直接提交报告即可。

2、运行指定的Case

代码块(test_case.py)

class TestClassOne(object):

def test_one(self):

x = "this"

assert 'h' in x

def test_two(self):

x = "hello"

assert hasattr(x, 'check')

class TestClassTwo(object):

def test_one(self):

x = "this"

assert 'h' in x

def test_two(self):

x = "hello"

assert hasattr(x, 'check')

运行模式:

模式 1:$ pytest test_case.py

模式 2:$ pytest test_case.py::TestClassTwo

模式 3:$ pytest test_case.py::TestClassTwo::test_one

说明:

模式 1:直接执行整个test_case文件中在所有case

模式 2:运行test_case文件中TestClassTwo这个class下的两个cases

模式 3:运行test_case文件中TestClassTwo这个class下的test_one

效果:

当我们写了较多的cases时,如果每次调式都要运行一遍,无疑是很浪费时间的,通过这样的简单方式我们就可以方便的指定任何一个case来运行了。

注意:

定义class时,需要以T开头,不然pytest是不会去运行该class的。

3、多进程运行cases

pip install pytest-xdist

运行模式:

$ pytest tes_case.py -n NUM

效果:

当case达到一定量的时候,运行时间会变的很长,如果想缩短脚本运行的时间,那就可以用它来做。NUM填写你想并发的进程数。速度嗖嗖嗖~不信你试试!

4、重试运行cases

pip install pytest-rerunfailures

运行模式:

$pytest tes_case.py --reruns NUM

效果:

在做接口测试时,有时候会遇到 503 或者短时的网络波动,导致case会运行失败,而其实并非是我们想要的结果,此时可以通过重新运行case的方式,再次执行。重试多少次,跟你填写的NUM有关。

5、显示print内容

运行模式:

$pytest tes_case.py -s

效果:

在运行测试脚本时,为了调试或者想打印一些内容,我们会在代码中加一些print内容,但是在运行pytest时,这些内容不会被显示出来。如果带上-s的运行模式,就可以看到print的内容会显示出来。

另外Pytest的多种运行模式是可以叠加执行的,比如说,你想同时运行 4个进程又想打印出print的内容,可以用$pytest test_case.py -s -n 4

三、总结

pytest的安装简单,学习资料丰富,框架切换成本低,有兴趣就一起来学习pytest吧!

最后:

可以我的个人V:atstudy-js,可以免费领取一份10G软件测试工程师面试宝典文档资料。以及相对应的视频学习教程免费分享!,其中包括了有基础知识、Linux必备、Mysql数据库、抓包工具、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试等。

这些测试资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!

敲字不易,如果此文章对你有帮助的话,点个赞收个藏,给作者一个鼓励。也方便你下次能够快速查找。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值