pytest单侧模块_入门汇总

Pytest简单介绍

(pytest是python的一个测试框架,主要是用来进行一些小的测试)

  • 安装:pip install -U pytest
  • 查看是否安装成功:pytest --version
  • 运行:在当前文件所在目录下执行pytest,会寻找当前目录以及子目录下以test开头的py文件或者以test结尾的py文件,找到文件后,在文件中找到以test开头函数并执行。(或者执行pytest 文件名--这样可以指定某个文件进行pytest的测试  或者  python -m pytest xxx.py)

在执行pytest xxx.py时,若增加参数:pytest -v -s xxx.py   (-v:显示运行的函数;-s:显示内部的打印信息)

  • 编写pytest测试样例的规则:
    1. 测试文件以test_开头
    2. 测试类以Test开头,并且不能带有init方法
    3. 测试函数以test_开头
    4. 断言使用基本的assert即可
  • 断言--正常:
assert value == 0
  • 断言--异常(pytest.raise方法):
 1 #断言1除以0,将产生一个ZeroDivisionError类型的异常。
 2 import pytest  
 3 def test_zero_division():  
 4     with pytest.raises(ZeroDivisionError):  
 5         1 / 0       
 6         
 7 #有的时候,我们可能需要在测试中用到产生的异常中的某些信息,比如异常的类型type,异常的值value等等。下面我们修改下上面的测试:
 8 import pytest  
 9 def test_recursion_depth():  
10     with pytest.raises(ZeroDivisionError) as excinfo:  
11     1/0  
12     assert excinfo.type == 'RuntimeError'  
13 #因为该测试断言产生的异常类型是RuntimeError,而实际上产生的异常类型是ZeroDivisionError,所以测试失败了。在测试结果中,可以看到assert子表达式excinfo.type的值。
  • 在test前,可以通过增加skip或xfail进行跳过(失败)测试案例
1 import pytest
2 
3 # @pytest.mark.skipif()   跳过
4 # @pytest.mark.skip()    跳过
5 # @pytest.mark.xfail()     若出错跳过,pass也跳过,但会显示pass
6 def test_123():
7     # pytest.skip()    也可以实现'跳过'目的
8     assert 1 == 0
  • 简单例子:
1 # coding:utf-8
2 import pytest
3 
4 def fun(x):
5     return x + 1
6 
7 def test_fun():
8     assert fun(2) == 3

结果:

(venvX) F:\test_jiaxin>pytest test_para1.py
============================= test session starts =============================
platform win32 -- Python 2.7.9, pytest-3.7.1, py-1.5.3, pluggy-0.7.1
rootdir: F:\test_jiaxin, inifile:
plugins: allure-adaptor-1.7.10
collected 1 item                                                               test_para1.py .                                                          [100%]========================== 1 passed in 0.09 seconds ===========================

pytest之feature-scope

  • function:每个test都运行,默认是function的scope.
  • class:每个class的所有test只运行一次.
  • module:每个module的所有test只运行一次.
  • session:每个session只运行一次.

比如你的所有test都需要连接同一个数据库,那可以设置为module,只需要连接一次数据库,对于module内的所有test,这样可以极大的提高运行效率。

代码:

1 @pytest.fixture(scope="module")
2     def hero_backup_policy(self, acmp_cfg):
3         return AcloudBackupPolicy(acmp_cfg)
4 
5 @pytest.fixture(scope="function")
6     def hero_acloud_backup_policy(self, acmp_cfg):
7         return Server(acmp_cfg)

pytest的参数化方式

  • pytest.fixture()方式进行参数化,fixture装饰的函数可以作为参数传入其他函数

  • conftest.py 文件中存放参数化函数,可作用于模块内的所有测试用例

  • pytest.mark.parametrize()方式进行参数化

 

待测试代码片段:(is_leap_year.py)

 1 # coding:utf-8
 2 def is_leap_year(year):
 3     # 先判断year是不是整型
 4     if isinstance(year, int) is not True:
 5         raise TypeError("传入的参数不是整数")
 6     elif year == 0:
 7         raise ValueError("公元元年是从公元一年开始!!")
 8     elif abs(year) != year:
 9         raise ValueError("传入的参数不是正整数")
10     elif (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:
11         print"%d年是闰年" % year
12         return True
13     else:
14         print"%d年不是闰年" % year
15         return False
  • pytest.fixture()

  1. pytest.fixture()中传入的参数为list,用例执行时,遍历list中的值,每传入一次值,则相当于执行一次用例。

  2. @pytest.fixture()装饰的函数中,传入了一个参数为request。

  3. 这里的测试数据是直接存在list中的,能否存入json文件或者xml文件再进行读取转换为list呢?

代码:

 1 # coding:utf-8
 2 import is_leap_year
 3 import pytest
 4 
 5 class TestPara():
 6     is_leap = [4, 40, 400, 800, 1996, 2996]
 7     is_not_leap = [1, 100, 500, 1000, 1999, 3000]
 8     is_valueerror = [0, -4, -100, -400, -1996, -2000]
 9     is_typeerror = ['-4', '4', '100', 'ins', '**', '中文']
10 
11     @pytest.fixture(params=is_leap)
12     def is_leap(self, request):
13         return request.param
14 
15     @pytest.fixture(params=is_typeerror)
16     def is_typeerror(self, request):
17         return request.param
18 
19     def test_is_leap(self, is_leap):
20         assert is_leap_year.is_leap_year(is_leap) == True
21 
22     def test_is_typeerror(self, is_typeerror):
23         with pytest.raises(TypeError):
24             is_leap_year.is_leap_year(is_typeerror)
  • conftest.py 文件 -- 测试数据与用例分离

  1. 采用conftest.py文件存储参数化数据和函数,模块下的用例执行时,会自动读取conftest.py文件中的数据。

代码:

 conftest.py文件
1
# coding:utf-8 2 import pytest 3 4 is_leap = [4, 40, 400, 800, 1996, 2996] 5 is_not_leap = [1, 100, 500, 1000, 1999, 3000] 6 is_valueerror = [0, -4, -100, -400, -1996, -2000] 7 is_typeerror = ['-4', '4', '100', 'ins', '**', '中文'] 8 9 @pytest.fixture(params=is_leap) 10 def is_leap(request): 11 return request.param 12 13 @pytest.fixture(params=is_typeerror) 14 def is_typeerror(request): 15 return request.param
 test_para.py文件
1
# coding:utf-8 2 3 import is_leap_year 4 import pytest 5 6 class TestPara(): 7 def test_is_leap(self, is_leap): 8 assert is_leap_year.is_leap_year(is_leap) == True 9 10 def test_is_typeerror(self, is_typeerror): 11 with pytest.raises(TypeError): 12 is_leap_year.is_leap_year(is_typeerror)
  • pytest.mark.parametrize() -- 进行参数化

  1. 采用标记函数参数化,传入单个参数,pytest.mark.parametrize("参数名",lists)。
  2. 采用标记函数传入多个参数,如pytest.mark.parametrize("para1, para2", [(p1_data_0, p2_data_0), (p1_data_1, p2_data_1),...]。
  3. 这里:测试用例中传入2个参数,year和期望结果,使输入数据与预期结果对应,构造了2组会失败的数据,在执行结果中,可以看到失败原因。

代码:

 1 # coding:utf-8
 2 import is_leap_year
 3 import pytest
 4 
 5 class TestPara():
 6     # 参数传入year中
 7     @pytest.mark.parametrize('year, expected', [(1, False), (4,True), (100, False), (400, True), (500, True)])
 8     def test_is_leap(self, year, expected):
 9         assert is_leap_year.is_leap_year(year) == expected
10 
11     @pytest.mark.parametrize('year, expected', [(0, ValueError),('-4', TypeError), (-4, ValueError), ('ss', TypeError), (100.0, ValueError)])
12     def test_is_typeerror(self, year, expected):
13         if expected == ValueError:
14             with pytest.raises(ValueError) as excinfo:
15                 is_leap_year.is_leap_year(year)
16                 assert excinfo.type == expected
17         else:
18             with pytest.raises(TypeError) as excinfo:
19                 is_leap_year.is_leap_year(year)
20                 assert excinfo.type == expected

参考链接:https://blog.csdn.net/zhusongziye/article/details/79902772

 

pytest-fixture扩展内容

1.  把一个函数定义为Fixture很简单,只能在函数声明之前加上“@pytest.fixture”。其他函数要来调用这个Fixture,只用把它当做一个输入的参数即可。

 1 import pytest
 2 
 3 @pytest.fixture()
 4 def before():
 5     print '\nbefore each test'
 6 
 7 def test_1(before):
 8     print 'test_1()'
 9 
10 def test_2(before):
11     print 'test_2()'

result:

(venvX) F:\test_jiaxin>pytest -v -s test_compute.py
============================= test session starts =============================
platform win32 -- Python 2.7.9, pytest-3.7.1, py-1.5.3, pluggy-0.7.1 -- f:\projects\sandom\venvx\scripts\python.exe
cachedir: .pytest_cache
rootdir: F:\test_jiaxin, inifile:
plugins: allure-adaptor-1.7.10
collected 2 items                                                              test_compute.py::test_1
before each test
test_1()
PASSED
test_compute.py::test_2
before each test
test_2()
PASSED========================== 2 passed in 0.17 seconds ===========================

 

2.  进行封装

 1 import pytest
 2 
 3 @pytest.fixture()
 4 def before():
 5     print '\nbefore each test'
 6 
 7 # 每个函数前声明
 8 @pytest.mark.usefixtures("before")
 9 def test_1():
10     print 'test_1()'
11 @pytest.mark.usefixtures("before")
12 def test_2():
13     print 'test_2()'
14 
15 #封装在类里,类里的每个成员函数声明
16 class Test1:
17     @pytest.mark.usefixtures("before")
18     def test_3(self):
19         print 'test_1()'
20     @pytest.mark.usefixtures("before")
21     def test_4(self):
22         print 'test_2()'
23 
24 #封装在类里在前声明
25 @pytest.mark.usefixtures("before")
26 class Test2:
27     def test_5(self):
28         print 'test_1()'
29     def test_6(self):
30         print 'test_2()'

result:

(venvX) F:\test_jiaxin>pytest -v -s test_compute.py
============================= test session starts =============================
platform win32 -- Python 2.7.9, pytest-3.7.1, py-1.5.3, pluggy-0.7.1 -- f:\projects\sandom\venvx\scripts\python.exe
cachedir: .pytest_cache
rootdir: F:\test_jiaxin, inifile:
plugins: allure-adaptor-1.7.10
collected 6 items                                                              test_compute.py::test_1
before each test
test_1()
PASSED
test_compute.py::test_2
before each test
test_2()
PASSED
test_compute.py::Test1::test_3
before each test
test_1()
PASSED
test_compute.py::Test1::test_4
before each test
test_2()
PASSED
test_compute.py::Test2::test_5
before each test
test_1()
PASSED
test_compute.py::Test2::test_6
before each test
test_2()
PASSED========================== 6 passed in 0.11 seconds ===========================

 

3.  fixture还可以带参数,可以把参数赋值给params,默认是None。对于param里面的每个值,fixture都会去调用执行一次,就像执行for循环一样把params里的值遍历一次。

1 import pytest
2 
3 @pytest.fixture(params=[1, 2, 3])
4 def test_data(request):
5     return request.param
6 
7 def test_not_2(test_data):
8     print('test_data: %s' % test_data)
9     assert test_data != 2

result:

(venvX) F:\test_jiaxin>pytest -v -s test_compute.py
============================= test session starts =============================
platform win32 -- Python 2.7.9, pytest-3.7.1, py-1.5.3, pluggy-0.7.1 -- f:\projects\sandom\venvx\scripts\python.exe
cachedir: .pytest_cache
rootdir: F:\test_jiaxin, inifile:
plugins: allure-adaptor-1.7.10
collected 3 items                                                              test_compute.py::test_not_2[1] test_data: 1
PASSED
test_compute.py::test_not_2[2] test_data: 2
FAILED
test_compute.py::test_not_2[3] test_data: 3
PASSED================================== FAILURES ===================================
________________________________ test_not_2[2] ________________________________test_data = 2def test_not_2(test_data):print('test_data: %s' % test_data)
>       assert test_data != 2
E       assert 2 != 2test_compute.py:64: AssertionError
===================== 1 failed, 2 passed in 0.12 seconds ======================

 

转载于:https://www.cnblogs.com/sunshine-blog/p/9468399.html

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pythonreshape函数三个参数_详解numpy.ndarray.reshape()函数的参数问题

我们知道numpy.ndarray.reshape()是用来改变numpy数组的形状的,但是它的参数会有一些特殊的用法,这里我们进一步说明一下。代码如下:import numpy as npclass Debug:def __init__(self):self.array1 np.ones(6)def mainProgram(self):print(…

javafx 和swing_集成JavaFX和Swing

javafx 和swing我刚刚完成了对使用Swing的应用程序组件的重写,现在正在使用JavaFX,最后得到了与更大的swing应用程序集成的JavaFX组件。 这是一个很大的应用程序,重写花了我一段时间,最后一切都很好,我很高兴自己做到了…

servlet.jar--jar not loaded错误

出错信息:validateJarFile(D:\Program Files\apache-tomcat-6.0.29\webapps\BookShop\WEB-INF\lib\servlet.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class 造成这种错误的原因有两个:serv…

练习6.6

6.6:说明形参、局部变量以及局部静态变量的区别。编写一个函数,同时用到这三种形式。 Ans:形参及函数体内定义的变量,都是局部变量,必须进行初始化,否则会出现未定义行为,这是由于局部变量的生命…

java map 最大值_MAP集合选出最大值

import java.util.Arrays;import java.util.HashMap;import java.util.Map;import org.junit.Test;public class TestHashMap {//统计各空气质量的最高值Testpublic void test1(){String pm25 "农展馆423,东四378,丰台花园406,天坛322,海淀区万柳398," "官园40…

Apache Hadoop HDFS数据节点Apache Mesos框架

介绍 该项目允许在Mesos上运行HDFS。 您应该熟悉HDFS和Mesos基础知识: http://mesos.apache.org/documentation/latest/ https://hadoop.apache.org/docs/r2.7.2/hdfs_design.html 项目要求: Mesos 0.23.0 JDK 1.7.x Hadoop 1.2.x或2.7.x 流浪汉 …

java byte 转 c_C 和 Java 之间的byte数据的转换问题

C语言里通常可能开发人员直接定义struct 作为数据包,因此在java客户端接收struct 中的数据时候,受整数等类型的高低位存放的影响,需要进行相应的转换,参考:转换代码如下:package com.lizongbo.util;/**** Title: 数字转换工具类** Description: 将数字类型与byte数组互相转换**…

MyEclipse中如何设置 jdk 和 jre 编译运行环境

MyEclipse设置JDK和JRE具体的应用版本其实很简单,分为三种状况: 1、设置默认使用的JDK和JRE环境。 具体步骤:菜单window-preferences-java-Installed JRES。 点中了,右边的窗口点ADD按钮,记住选择添加安装了Java目录下…

dubbo集群服务下一台服务挂了对服务调用的影响

一、问题描述:项目中2台dubbo服务给移动端提供查询接口,移动端反应说查询时而很快(秒刷),时而很慢(4-5秒)。 二、问题分析: 1、问题猜想:网络不稳定原因导致,但是切换公司wifi和手机4G,问题依旧存在。说明问…

C89与C99标准比较

1、增加restrict指针 C99中增加了公适用于指针的restrict类型修饰符,它是初始访问指针所指对象的惟一途径,因此只有借助restrict指针表达式才能访问对象。restrict指针指针主要用做函数变元,或者指向由malloc()函数所分配的内存变量。restri…

java rest客户端_Java中的简单REST客户端

java rest客户端如今,大多数用于与某些服务器通信的移动应用程序都使用REST服务。 这些服务也是JavaScript或jQuery的常用惯例。 现在,我知道在Java中为REST服务创建客户端的2种方法,在本文中,我将尝试演示这两种方法,…

C++并发编程实战---阅读笔记

1. 当把函数对象传入到线程构造函数中时,需要避免“最令人头痛的语法解析”。如果传递了一个临时变量,而不是一个命名的变量;C编译器会将其解析为函数声明,而不是类型对象的定义。 例如: class background_task { publ…

java md2_java中加密的实现方法(MD5,MD2,SHA)

java中加密的实现方法(MD5,MD2,SHA)实例代码:注释都很清楚,import java.security.MessageDigest;import javax.xml.bind.annotation.adapters.HexBinaryAdapter;public class Main {static String src "Hello,sahadev!"…

Java向后不兼容历史的观察

在大多数情况下,Java是一个非常向后兼容的编程语言。 这样做的好处是,与大规模破坏兼容性相比,大型系统通常可以相对容易的方式升级为使用Java的较新版本。 这样做的主要缺点是Java坚持了一些设计决策,这些决策自那时以来就被认为…

C语言中输入输出格式控制

1、C语言中,非零值为真,真用1表示;零值为假,假用0表示。 2、转义字符参考: \a 蜂鸣,响铃 \b 回退:向后退一格 \f 换页 \n 换行 \r 回车,光标到本行行首 \t 水平制表 …

java udp 接受阻塞_Java UDP发送与接收

IP地址?端口号?主机名?什么是Socket?什么是UDP?什么是TCP?UDP和TCP区别?以上问题请自行百度,有标准解释,此处不再赘述,直接上干货!实例:发送端&a…

JavaScript 运行机制详解:Event Loop

参考地址:http://www.ruanyifeng.com/blog/2014/10/event-loop.html 一、为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢&a…

原码, 反码, 补码 详解

本篇文章讲解了计算机的原码, 反码和补码. 并且进行了深入探求了为何要使用反码和补码, 以及更进一步的论证了为何可以用反码, 补码的加法计算原码的减法. 论证部分如有不对的地方请各位牛人帮忙指正! 希望本文对大家学习计算机基础有所帮助! 一. 机器数和真值 在学习原码, 反码…

java eden space_JVM虚拟机20:内存区域详解(Eden Space、Survivor Space、Old Gen、Code Cache和Perm Gen)...

1.内存区域划分根据我们之前介绍的垃圾收集算法,限定商用虚拟机基本都采用分代收集算法进行垃圾回收。根据对象的生命周期的不同将内存划分为几块,然后根据各块的特点采用最适当的收集算法。大批对象死去、少量对象存活的,使用复制算法&#…

gradle 插件 自定义_Gradle自定义插件

gradle 插件 自定义本教程介绍了创建Gradle独立自定义插件的方法。 它涵盖以下主题 创建任务,并在“自定义”插件中使用 独立的自定义插件 简短的插件ID 使用settings.gradle自定义Gradle设置 项目信息: Gradle版本:1.1 操作系统平台&…