前言:

在单元测试框架中,主要分为:测试固件,测试用例,测试套件,测试执行及测试报告;

测试固件不难理解,也就是我们在执行测试用例前需要做的动作和测试执行后的需要做的事情;

比如在UI自动化测试中,我们更加关注的是界面的操作,而不是关注打开浏览器和关闭浏览器;

在数据库中,我们更加关注的是怎么去操作Mysql数据库,而不是关注数据库的连接和断开;

所以如上的这些打开浏览器和关闭浏览器,连接数据库和断开数据库,我们可以让测试固件去干,测试用例层面是关住执行结果和断言结果,

如:UnitTest单元测试框架中的setup和teardown,还有setupClass和teardownClass(需要配合@classmethod装饰器一起使用)是测试固件;

那么本节是介绍pytest的类似于这类的固件;

1、FixTure返回值,代码示例如下:

'''
fixture的作用
1. return 返回值
2. 初始化和清理操作
3. conftest.ini 全局
'''
import json
import pytest
import requests
import yaml

# 读取BookYaml文件
def readYaml():
with open('books.yaml','r',encoding='utf-8') as fp:
return list(yaml.load_all(fp))

@pytest.fixture()
# 认证登录
def get_Token():
login_url = "http://127.0.0.1:5550/auth"
data = {"username": "admin","password": "Admin"}
response = requests.post(url=login_url,json=data)
# 返回token值
return response.json()['access_token']

# 使用Pytest参数化思想
@pytest.mark.parametrize('datas',readYaml())
# 定义测试方法
def test_books(get_Token,datas):
if datas['method'] == 'get':
r = requests.get(
url=datas['url'],
headers= {"Authorization":"JWT {0}".format(get_Token)}
)
# 断言Get方法返回的结果
assert datas['expect'] in json.dumps(r.json(),ensure_ascii=False)
elif datas['method'] == 'post':
r = requests.post(
url=datas['url'],
json=datas['dict1'],
headers= {"Authorization":"JWT {0}".format(get_Token)}
)
# 断言Post方法返回的结果
assert datas['expect'] in json.dumps(r.json(),ensure_ascii=False)
elif datas['method'] == 'put':
r = requests.put(
url=datas['url'],
json=datas['dict1'],
headers= {"Authorization":"JWT {0}".format(get_Token)}
)
# 断言Put方法返回的结果
assert datas['expect'] in json.dumps(r.json(),ensure_ascii=False)
elif datas['method'] == 'delete':
r = requests.delete(
url=datas['url'],
headers= {"Authorization":"JWT {0}".format(get_Token)}
)
# 断言Delete方法返回的结果
assert datas['expect'] in json.dumps(r.json(), ensure_ascii=False)

if __name__ == '__main__':
# 执行模块
pytest.main(['-s','-v','test_fixture_api.py'])

装饰器@pytest.fixture(),它声明是一个函数fixture,如果测试函数的参数列表中包含了fixture名,那么执行pytest时会检测到它,且在测试函数执行前执行fixture,再把返回数据给测试函数
接下来看下另外的案例,测试UI自动化场景时,不管怎么都得打开浏览器进行操作,最后再关闭浏览器,此时用到fixture来处理
# UI案例示例
import pytest
from selenium.webdriver.common.by import By

# 安装pip3 install pytest-selenium

@pytest.fixture()
def int(selenium):
selenium.maximize_window()
selenium.implicitly_wait(10)
selenium.get('http://www.baidu.com/')
yield
selenium.quite()

def test_baidu_title(int,selenium):
assert selenium.title == '百度一下,你就知道'

def test_so_text(int,selenium):
so = selenium.find_element(By.ID,'kw')
so.send_keys('pytest')
assert so.get_attribute('value') == 'pytest'

def test_url(int,selenium):
selenium.find_element_by_link_text('新闻').click()
# 获取全部的handles再进行切换到指定的窗口
selenium.switch_to.window(selenium.window_handles[0])
assert selenium.current_url == 'http://news.baidu.com/'

if __name__ == '__main__':
pytest.main()

# 在终端上输入如下命名执行:pytest -v 测试模块 --driver Chrome(指定测试的浏览器)
# 命令:pytest -v -s test_fixture_ui.py --driver Firefox
2、fixture之conftest.py
2.1 通过conftest.py可以共享fixture,是pytest特有的本地测试配置文件,既可以用来设置项目级别的fixture,可以用来导入外部插件,还可用来指定钩子函数(共享)
2.2 conftest.py 文件是不可以导入的,只可共享它所在目录及子目录

Mysql案例,把链接数据库方法放在conftest.py 模块下
import pymysql
import pytest

# 连接数据库
@pytest.fixture()
def connSql():
conn = pymysql.connect(
host='localhost',
user='root',
password='123456',
charset='utf8',
database='srs'
)
return conn

Mysql代码如下:
import pytest

# 关闭数据库
def closeSql(connSql):
connSql.close()

# 创建游标
@pytest.fixture()
def connCursor(connSql):
return connSql.cursor()

# 关闭游标
def closeCursor(connSql):
connSql.close()

@pytest.fixture()
def int(connSql,connCursor):
connSql
connCursor
yield
closeSql(connSql)
connCursor(connSql)

# 查询数据库
def test_select_sql(connSql,connCursor):
# 创建游标
sql = 'select * from tbcourse'
# 执行游标
connCursor.execute(sql)
result = connCursor.fetchall()
print('查询数据:\n',result)

if __name__ == '__main__':
pytest.main(['-v','-s','test_fixture_sql.py'])

执行结果如下:
终端中运行:pytest -s -v test_fixture_sql.py

使用conftest.py有这个几点需要特别的注意:
1、conftest.py文件绝对不能当一般的模块导入,这点需要特别的注意
2、conftest.py很多时候被当作pytest测试框架的一个本地插件库来执
3、在一个测试包(目录)下面,conftest.py被看成是该目录下所有测试用例使用的fixture仓库
 
conftest.py 文件中主要是依照scope的参数来控制fixture执行配置和销毁逻辑,下面介绍的是fixture默认值 function函数
分为四类分别为:
Session:会话级别:针对一个项⽬中所有的模块,类,以及测试函数
Module:模块级别,主要是针对一个模块的范围
Class:针对类级别,主要是针对一个类的范围

Function:函数级别,主要是针对一个函数的
fixture级别之:function函数级别

import pytest
from selenium import webdriver
@pytest.fixture(scope='function')
def driver():
return webdriver.Firefox()

@pytest.fixture(scope='function')
def init(driver):
driver.maximize_window()
driver.get('http://www.baidu.com/')
# 隐性等待
driver.implicitly_wait(10)
yield
driver.quit()
测试模块代码为:

import pytest
from selenium.webdriver.common.by import By

def test_baidu_title(driver,init):
assert driver.title == '百度一下,你就知道'

def test_so_text(int,driver):
so = driver.find_element(By.ID,'kw')
so.send_keys('pytest')
assert so.get_attribute('value') == 'pytest'

def test_url(int,driver):
driver.find_element_by_link_text('新闻').click()
# 获取全部的handles再进行切换到指定的窗口
driver.switch_to.window(driver.window_handles[0])
assert driver.current_url == 'http://news.baidu.com/'

if __name__ == '__main__':
pytest.main()

fixture级别之:class、module,session函数级别

import pytest
from selenium import webdriver
# fixture级别之class
@pytest.fixture(scope='class')
def driver():
return webdriver.Firefox()

@pytest.fixture(scope='class')
def init(driver):
driver.maximize_window()
driver.get('http://www.baidu.com/')
# 隐性等待
driver.implicitly_wait(10)
yield
driver.quit()

# fixture级别之module
@pytest.fixture(scope='module')
def driver():
return webdriver.Firefox()

@pytest.fixture(scope='module')
def init(driver):
driver.maximize_window()
driver.get('http://www.baidu.com/')
# 隐性等待
driver.implicitly_wait(10)
yield
driver.quit()

# fixture级别之session
@pytest.fixture(scope='session')
def driver():
return webdriver.Firefox()

@pytest.fixture(scope='session')
def init(driver):
driver.maximize_window()
driver.get('http://www.baidu.com/')
# 隐性等待
driver.implicitly_wait(10)
yield
driver.quit()
测试模块代码为:
import pytest
from selenium.webdriver.common.by import By
class TestUi(object):

def test_baidu_title(self,int,selenium):
assert selenium.title == '百度一下,你就知道'

def test_so_text(self,int,selenium):
so = selenium.find_element(By.ID,'kw')
so.send_keys('pytest')
assert so.get_attribute('value') == 'pytest'

def test_url(self,int,selenium):
selenium.find_element_by_link_text('新闻').click()
# 获取全部的handles再进行切换到指定的窗口
selenium.switch_to.window(selenium.window_handles[0])
assert selenium.current_url == 'http://news.baidu.com/'

if __name__ == '__main__':
pytest.main()

Pytest单元测试框架之FixTure基本使用的更多相关文章

  1. Pytest单元测试框架之FixTure内置临时文件tmpdir操作

    1.前言:某些接口需要引用上个接口返回的值,作为下个接口的入参,但笔者又不想在本地维护及创建此文件,此时引出fixture内置函数中的临时文件存储tmpdir 2.首先下面的源码是使用flask框架写 ...

  2. Pytest单元测试框架-测试用例运行规则

    1.Pytest测试用例运行规则 在pytest单元测试框架下面执行用例,需要满足以下几个特点: 1. 文件名以test_*.py开头或者*_test.py 2. 测试类.测试函数以test开头 3. ...

  3. Pytest单元测试框架-Pytest环境安装

    unittest是python自带的单元测试框架,它封装好了一些校验返回的结果方法和一些用例执行前的初始化操作,使得单元测试易于开展,因为它的易用性,很多同学也拿它来做功能测试和接口测试,只需简单开发 ...

  4. Pytest单元测试框架:插件-allure-pytest环境搭建并在本地生成一个测试报告

    之前写了allure-pytest的官方文档啃的内容,有些交流的朋友,实践起来没什么头绪,所以就有了这篇文章,也给自己填个坑 第一步:搭建Allure.JDK环境 1. 搭建JDK环境 不装jdk你会 ...

  5. Pytest单元测试框架之简单操作示例

    前言: Pytest是第三方单元格测试框架,更加简单,灵活,而且提供了更多丰富的扩展: Pytest与UnitTest框架的区别 UnitTest测试用例执行顺序是依照ascii码执行,而Pytest ...

  6. Pytest单元测试框架——Pytest+Allure+Jenkins的应用

    一.简介 pytest+allure+jenkins进行接口测试.生成测试报告.结合jenkins进行集成. pytest是python的一种单元测试框架,与python自带的unittest测试框架 ...

  7. Pytest单元测试框架-学习

    pytest: Python的一个单元测试框架,基于UnitTest二次开发,语法上更加简洁,可以用来做Python开发项目的单元测试,UI自动化.接口自动化测试等,有很多的插件访问Pytest插件汇 ...

  8. pytest单元测试框架

    一.安装方式 1.安装命令:pip install pytest 2.html安装插件:pip install pytest -html 二.pytest执行指定测试用例 1.思想:通过对测试用例进行 ...

  9. Pytest 单元测试框架

    1.pytest 是 python 的第三方单元测试框架,比自带 unittest 更简洁和高效 2.安装 pytest pip install pytest 3.验证 pytest 是否安装成功 p ...

随机推荐

  1. Pass Infrastructure基础架构(下)

    Pass Infrastructure基础架构(下) pass注册  PassRegistration该类在示例中简要显示了各种pass类型的定义 .该机制允许注册pass类,以便可以在文本pass管 ...

  2. java数据提交时问题

    form 表单中的action有参数时,当method为get时,servlet无法获取该参数 ajax提交数据,servlet无法进行请求转发和重定向. ${pageContext.request. ...

  3. Kettle通过Http post请求webservice接口以及结果解析处理

    kettle中有两种方式请求webservice服务,一个是Web服务查询,但是这个有缺陷,无法处理复杂的需求,遇到这种情况就需要用Http post来处理了. 网上也有很多关于Http post请求 ...

  4. 纯小白干货:Java import以及Java类的搜索路径

    如果你希望使用Java包中的类,就必须先使用import语句导入.import语句与C语言中的 #include 有些类似,语法为:import package1[.package2-].classn ...

  5. 排查bug:竟然是同事把Redis用成这鬼样子,坑了我

    首先说下问题现象:内网sandbox环境API持续1周出现应用卡死,所有api无响应现象 刚开始当测试抱怨环境响应慢的时候 ,我们重启一下应用,应用恢复正常,于是没做处理.但是后来问题出现频率越来越频 ...

  6. 学习JDK源码(二):Integer

    最近没有好好保持学习的好习惯,该打. 天天忙,感觉都不知道在干嘛.真的厌倦了普通的Java代码,还是想学点新技术. 用了这么久的Java,最常用的数据类型肯定是Int了,而他的包装类Integer用的 ...

  7. ANDROID开发 Fatal signal 11(SIGSEGV) at 0x问题解决方案

    最近做ANDROID开发,也遇到了很多程序员遇到的一个问题:FATAL SIGNAL 11(SIGSEGV) at 0xxxxx,自然是各种搜索是否有人已然解决,虽然搜索出来的已有案例不少,基本都是内 ...

  8. Android开发问题之Installation failed due to invalid URI!

    真机调试遇到以下问题: [2017-07-20 13:43:53 - VCL02PANEL] Installation failed due to invalid URI![2017-07-20 13 ...

  9. C#WebService的创建与发布

    VS中新建项目-Web-ASP.NET Web应用程序 然后确定,选择空模版就可以了 其中CRMService.asmx是点击项目新建Web服务(asmx) 这样基本的功能就能用了,然后就是发布 点击 ...

  10. http强制缓存、协商缓存、指纹ETag详解

    目录 实操目录及步骤 缓存分类 强制缓存 对比缓存 指纹 Etag 摘要及加密算法 缓存总结 每个浏览器都有一个自己的缓存区,使用缓存区的数据有诸多好处,减少冗余的数据传输,节省网络传输.减少服务器负 ...