Pytest框架实战二

  在Pytest框架实战一中详细地介绍了Pytest测试框架在参数化以及Fixture函数在API测试领域的实战案例以及具体的应用。本文章接着上个文章的内容继续阐述Pytest测试框架优秀的特性以及在自动化测试领域的实战。

conftest.py

       在上一篇文章中阐述到Fixture函数的特性,第一是函数的返回值,第二是测试固件的特性。但是在实际的工作里面会有非常多的Fixture函数,那么怎么合理的安排更加友好呢?建议把公共的部分剥离出来统一的管理和调用,而非公共的部分就使用常规的函数来处理就可以了。在API自动化测试中公共的部分主要是认证授权的机制,也就是登录成功后返回的TOKEN在后续的请求中需要带上这个TOKEN才能够获取服务端的认可客户端才能够获取资源信息。在Pytest测试框架中可以把Fixture函数分离到conftest.py的文件中,这个文件它的特性具体如下。

  • 它是一个模块,但是这个模块不需要导入就可以使用里面的Fixture函数

  • 在目录结构的设计上,conftest.py文件建议在项目的第一层级目录结构中

  • conftest.py就是用来分离公共的Fixture函数

结合第一篇文章的案例,下来把登录认证授权代码分离到conftest.py文件中,这样测试模块使用的时候直接调用它就可以了,分离到conftest.py模块里面的代码如下。


#!/usr/bin/python3
#coding:utf-8
# author:wuya

import  pytest
import  requests
import json

@pytest.fixture()
def access_token():
  r=requests.post(
    url='http://47.95.142.233:8000/login/auth/',
    json={"username":"13484545195","password":"asd888"})
  return r.json().get('token',None)

@pytest.fixture()
def headers(access_token):
  return {'Authorization':'JWT {token}'.format(token=access_token)}

如上是把登录认证授权的代码分离到conftest.py的文件中,下来在测试模块里面直接调用就可以了,涉及到的测试模块的代码如下:


#! /usr/bin/env python
# -*- coding:utf-8 -*-
# author:wuya

import pytest
import  requests
import  json

def writeID(prodctID):
  json.dump(str(prodctID),open('prodctID','w'))

def getID():
  return int(json.load(open('prodctID')))

def addProduct(headers):
  r=requests.post(
    url='http://47.95.142.233:8000/interface/product/',
    json={"name":"测试数据","product_type":"WEB","version":"1.0","master":"无涯","description":"测试"},
    headers=headers)
  writeID(prodctID=r.json()['id'])
  return r

def delProduct(headers):
  r=requests.delete(
    url='http://47.95.142.233:8000/interface/product/{productID}/'.format(productID=getID()),
    headers=headers)
  return r

@pytest.fixture()
def init(headers):
  addProduct(headers)
  yield
  delProduct(headers)

def test_so_product(init,headers):
  '''产品搜索验证'''
  r=requests.get(
    url='http://47.95.142.233:8000/interface/products?name=测试数据',
    headers=headers)

如上可以看到init()函数也是Fixture函数,但是并没有分离到conftest.py文件中,理由主要是init()函数它是基于业务需求而编写的Fixture函数但是并不是公共的Fixture函数,在后面随着编写测试用例越来越多的情况下,这种基于业务的Fixture函数会特别多。如上的代码执行后的结果信息如下图所示。

图片

在企业级的API自动化测试框架中,完全的可以把conftest.py应用进去,特别是登录认证授权的这部分特性功能。

命令行解释器

       在微服务架构的产品中存在一个特性就是使用不同的租户来登录系统,访问的业务形态都是一样的,但是在底层会针对数据做隔离。正因为如此,所以就会有众多的集群模式来满足底层的计算能力。那么这样在编写的测试用例上,就需要更多的灵活性,这个灵活性主要指的是不能把登录的账户和密码写死,要满足不同的集群验证模式,那么也就意味着登录的用户是可以自定义的,但是这个自定义的用户必须是系统已被订阅的租户。这样设计的优势就是可以满足不同集群验证产品的特性以及定时轮训检测不同集群的底层计算能力和系统的稳定性。使用这部分可以使用Pytest测试框架的命令行解释权完全能够解决这部分,下面针对之前的代码进行改造,把登录系统的账户与密码完全的自定义化,改造后的代码如下。


#!/usr/bin/python3
#coding:utf-8
# author:wuya

import  pytest
import  requests
import json

def pytest_addoption(parser):
  '''添加pytest的自定义命令行参数'''

  parser.addoption(
    '--username',action='store',default='13484545195',help='myoption: type1 or pyte2'
  )
  parser.addoption(
    '--password',action='store',default='asd888',help='myoption: type1 or pyte2'
  )

@pytest.fixture()
def username(request):
  return request.config.getoption('--username')

@pytest.fixture()
def password(request):
  return request.config.getoption('--password')


@pytest.fixture()
def access_token(username,password):
  r=requests.post(
    url='http://47.95.142.233:8000/login/auth/',
    json={"username":username,"password":password})
  return r.json().get('token',None)

@pytest.fixture()
def headers(access_token):
  return {'Authorization':'JWT {token}'.format(token=access_token)}

在如上的代码中,完全的把登录的账户与密码分离了出来,这样就可以满足上面说的针对不同的集群以及集群规模化的验证模式,而且在上面也使用了默认的模式,也就是说执行的时候可以指定自定义的账户与密码,如下执行的方式是指定了账户与密码(自定义但是必须是指定的账户密码是系统的用户)


pytest -v  -s test_login.py --username=13588545195 --password=asd888

执行后的结果信息如下所示。

图片

也可以执行的时候使用默认命令行指定的账户与密码,执行以及执行结果如图所示。

图片

如上所示,使用Pytest的命令行解释器的特性,可以很轻松的解决了执行过程中随意的制定自定义的变量。

pytest.ini

在Pytest框架中,使用conftest.py是为了更好地分离Fixture函数,这样能够达到Fixture函数的共享机制,从而能够在各个模块以及测试函数里面调用,从而减少重复代码的数量。一般而言编写的测试类都是以Test开头,编写的测试函数都是以test开头,而所有的测试模块在test的包下,以及执行的过程中为了输出详细的信息以及打印输出的信息,在执行的时候都会带上-v与-s的命令,当然还有其他的信息。这些都是完全可以分离到pytest.ini的文件中,由它进行统一的管理。pytest.ini地工程的第一层级的位置,如下内容是pytest.ini文件内容。


[pytest]
#指定执⾏时候的默认信息
addopts= -v -s --driver Chrome --html=report.html  --reruns 3
#注册标记
markers=
    login:执⾏标记为login的测试函数
    register:执⾏标记为register的测试函数
#指定Pytest的最低版本号
minversion=3.0
#指定忽略执⾏⽬录
norecursedirs=.pytest_cache
#指定测试⽬录
testpaths=test
#指定测试模块搜索的规则
python_files=test_*
#指定测试类搜索的规则
python_classes=Test*
#指定测试函数搜索规则
python_functions=test_*

如上种指定了测试目录以及测试框架执行过程中测试的搜索规则。使用了pytest.ini的优势是后续执行过程中就不需要带上如-s这样的命令以及指定执行的目录。

tox.ini

tox.ini与pytest.ini是一样的,不过使用tox.ini可以代替pytest.ini的配置文件,而且在tox.ini的配置文件里面可以指定多个不同解释器的版本,这样的优势是在执行具体的测试用例的过程中就能够兼顾到多个不同Python解释器版本执行的情况。tox是一个命令行的工具,它允许测试在多种环境下执⾏,它的⼯作流程具体可以理解为:通过setup.py⽂件为待测程序创建源码安装包,这样就会查看tox.ini中所有的环境设置。把所有pytest.ini的配置都移动到 tox.ini⾥⾯,tox.ini文件内容如下。


[tox]
envlist = py3.5, py3.6, py3.7, py3.8, py3.9, py3.10, py3.11
skipsdist = True
indexserver =
 default = https://pypi.doubanio.com/simple
[testenv]
install_command = pip install -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host irrors.aliyun.com {opts} {packages}
deps =
 -rrequirements.txt
commands = coverage erase
 py.test --cov={toxinidir} -sx test
 coverage html
setenv =
 PYTHONPATH = {toxinidir}/py3
[testenv:dev]
deps = pytest
commands = {posargs:py.test}
[pytest]
#指定执⾏时候的默认信息
addopts= -v -s
#注册标记
markers=
 login:执⾏标记为login的测试函数
 register:执⾏标记为register的测试函数

#指定Pytest的最低版本号
minversion=3.0
#指定忽略执⾏的⽬录
norecursedirs=.pytest_cache
#指定测试⽬录
testpaths=test
#指定测试模块搜索的规则
python_files=test_demo.py
#指定测试类搜索的规则
python_classes=Test*
#指定测试函数搜索规则
python_functions=test_*

如上所示,指定了多个不同Python解释器的版本。执行的命令直接就是tox,执行后就会执行指定目录下所有的测试用例并且会在指定的Python解释器版本中都会执行,执行结果如下图。

图片

在不管是UI的测试框架还是API的测试框架中,把Pytest测试框架的配置引入进去,这样执行的时候就不需要刻意的指定被执行的目录以及各种命令,更多的精力可以聚焦于测试场景的编写以及代码的封装。

  • 14
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是 Selenium pytest 项目实战的一些笔记: 1. 安装所需的软件和库: - 安装 Python:在官网下载 Python 并安装。 - 安装 Selenium:使用 pip 命令安装 Selenium 库。 - 安装 pytest:使用 pip 命令安装 pytest 框架。 2. 创建项目结构: - 创建一个项目文件夹,并在其中创建一个名为 `tests` 的文件夹,用于存放测试用例。 - 在项目文件夹中创建一个名为 `conftest.py` 的文件,用于存放共享的测试配置和夹具。 3. 编写测试用例: - 在 `tests` 文件夹中创建一个名为 `test_example.py` 的文件,用于编写测试用例。 - 导入必要的依赖模块,如 pytest 和 selenium。 - 编写测试函数,使用 pytest 的装饰器 `@pytest.mark.parametrize` 定义参数化的测试用例。 - 在测试函数中通过 Selenium WebDriver 实例化浏览器,并执行相应的操作和断言。 4. 配置夹具: - 在 `conftest.py` 中使用 pytest 的 `fixture` 装饰器定义夹具函数。 - 夹具函数可以在测试用例中被调用,以提供预置条件或资源。 - 例如,可以创建一个 `driver` 夹具,用于在每个测试用例之前启动浏览器,并在测试完成后关闭浏览器。 5. 运行测试用例: - 在项目根目录下打开终端,并运行 `pytest` 命令来运行所有的测试用例。 - 使用命令行参数可以指定运行特定的测试用例,如 `pytest -k test_example`,将只运行名称中包含 "test_example" 的测试用例。 这些是 Selenium pytest 项目实战的一些基本笔记,希望能对你有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜鸟学识

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值