Pytest框架

一、框架介绍及安装

框架介绍                        

  pytest是python的一种单元测试框架,与python自带的unittest测试框架类似,但是比unittest框架使用起来更简洁,效率更高。

安装                            

  pip安装:pip install pytest

二、框架使用流程

快速使用                        

  1.准备源码文件test.py。

  2.cmd中切换至源文件所在目录。

  3.运行pytest命令,

    或py.test命令,

    或python –m pytest命令。

pytest运行规则                  

  • 查找当前目录及其子目录下以test_*.py*_test.py文件。
  • 找到文件后,在文件中找到以test开头函数并执行

运行测试类                    

  • 多条用例时,需要建立测试类
  • 多个测试模块时,可以选择执行部分模块用例。
  • py.test -q test_two.py

用例设计原则                     

  • 文件名以test_*.py文件*_test.py
  • 测试类以Test开头,并且不能带有init方法
  • test_开头的函数
  • Test开头的类
  • test_开头的方法
  • 所有的包pakege必须要有__init__.py文件
  • 断言使用assert

执行用例规则                    

  • 某个目录下所有的用例

    pytest 目录名/

  • 执行某一个py文件下用例

    pytest脚本名称.py

  • -k按关键字匹配

    pytest -k "MyClass and not method

  • 按节点运行

    来自参数化的类名,函数名为参数,由:: characters分隔。

      运行.py模块里面的某个函数

        >pytest test_mod.py::test_func

      运行.py模块里面,测试类里面的某个方法

        >pytest test_mod.py::TestClass::test_method

  • 标记表达式

    >pytest -m slow

    将运行用@ pytest.mark.slow装饰器修饰的所有测试。后面章节会讲自定义标记mark的功能。

  • 从包里面运行

    >pytest --pyargs pkg.testing

    返将导入pkg.testing并使用其文件系统位置来查找来运行测试。

命令参数 

  -q    --quiet decrease verbosity(显示简单结果)
  -x    遇到错误时停止测试
  --maxfail=num
  当用例错误个数达到指定数量时,停止测试
  --help   帮助

三、Pycharm下运行pytest

xx.py脚本方式直接执行                   

  • 当写的代码里面没用到unittest和pytest框架时
  • 并且脚本名称不是以test_开头命名的
  • 此时pycharm会以xx.py脚本方式运行

当脚本命名为test_xx.py时                    

  • 用到unittest框架,此时运行代码,pycharm会自动识别到以unittest方式运行

以pytest方式运行                        

  • 需要改该工程设置默认的运行器
  • file->Setting->Tools->Python Integrated Tools->项目名称->Default test runner->选择py.test

四、断言

定义:断言为实际结果和期望结果去对比,符合预期那就测试pass,不符合预期那就测试failed。

常用断言

  pytest里面断言实际上就是python里面的assert断言方法,常用的有以下几种:

  assert xx           判断xx为真

  assert not xx    判断xx不为真

  assert a in b     判断b包含a

  assert a == b   判断a等于b

  assert a != b    判断a不等于b 

五、装饰器

pytest.mark.skip 可以标记无法在某些平台上运行的测试功能,或者希望失败的测试功能。

skip if意味着在不满足某些条件时才希望测试通过,否则 pytest应该跳过运行测试。 常见示例是在非 Windows 平台上跳过仅限Windows 的测试,或跳过  测试依赖于当前不可用的外部资源。

xfail 意味着你希望测试由于某种原因而失败。 一个常见的例子是对功能的测试尚未实施,或尚未修复的错误。 

skip

  跳过测试函数的最简单方法是使用跳过装饰器标记它,可以传递一个可选的原因。

  @pytest.mark.skip(reason=“本轮测试不执行此用例")

skip

  可以通过调用来在测试执行或设置期间强制跳过。

  pytest.skip(reason)功能:

def test_function():
    if not valid_config():
        pytest.skip(“本用例跳过")

skipif

如果你希望有条件地跳过某些内容,则可以使用 skipif 代替。

import sys
@pytest.mark.skipif(sys.version_info < (3,6),reason="requires python3.6 or higher")

skipif

可以在模块之间共享 skipif 标记。

对于较大的测试套件,通常最好有一个文件来定义标记,然后一致适用于整个测试套件。

minversion = pytest.mark.skipif(5>3,reason=“test")
@minversion
def test_function(): 

skip其它

可以在类上使用 skipif 标记。

如果要跳过模块的所有测试功能,可以在全局级别使用pytestmark名称:pytestmark = pytest.mark.skipif(...)

自定义标记 mark

pytest 可以支持自定义标记,自定义标记可以把一个 web 项目划分多个模块,然后指定模块名称执行。

@pytest.mark.webtest
def test_send_http():

如果不想执行标记 webtest 的用例,那就用”not webtest

六、Fixture

1、用例运行级别

  • 模块级(setup_module/teardown_module)开始于模块始末,全局的
  • 函数级(setup_function/teardown_function)只对函数用例生效(不在类中)
  • 类级(setup_class/teardown_class)只在类中前后运行一次(在类中)
  • 方法级(setup_method/teardown_method)开始于方法始末(在类中)
  • 类里面的(setup/teardown)运行在调用方法的前后

2、运行的优先级

setup_class>setup_method>setup >用例>teardown> teardown_method>teardown_class

3、函数和类混合

  • 如果一个.py 的文件里面既有函数用例又有类和方法用例,运行顺序如下:
  • setup_module/teardown_module 的优先级是最大的。
  • 函数里面用到的 setup_function/teardown_function和类里面的 setup_class/teardown_class 互不干涉

4、fixture 优势

  • 相对于 setup 和teardown 来说有以下几点优势:
  • 命名方式灵活,不限于 setup 和 teardown 这几个命名。
  • conftest.py 配置里可以实现数据共享,不需要 import 就能自动找到一些配置。
  • scope="module" 可以实现多个.py 跨文件共享前置
  • scope=“session以实现多个.py 跨文件使用一个 session 来完成多个用例。

5、参数解析

  • fixture(scope="function", params=None, autouse=False,ids=None, name=None):
  • scope 有四个级别参数:function, class、Module、session
  • params: 一个可选的参数列表,它将导致多个参数调用fixture 功能和所有测试使用它。
  • fixture(scope="function", params=None, autouse=False,ids=None, name=None):
  • autouse: 如果为 True,则为所有测试激活 fixture func 可以看到它。 如果为 False(默认值)则显式需要参考来激活 fixture
  • fixture(scope="function", params=None, autouse=False,ids=None, name=None):
  • 每个字符串 id 的列表,每个字符串对应于 params 这样他们就是测试 ID 的一部分。 如果没有提供 ID 它们将从 params 自动生成。
  • fixture(scope="function", params=None, autouse=False,ids=None, name=None):
  • name: fixture 的名称。 这默认为装饰函数的名称。

例:scope="function" 

例:scope="module" 

 

 

6、conftest.py 配置

  • conftest.py 配置脚本名称是固定的,不能改名称
  • conftest.py 和运行的用例要在同一个 pakage 下,并且有__init__.py 文件
  • 不需要 import 导入 conftest.py, pytest 用例会自动查找

7、yield 执行 teardown

  • yield:提供
  • fixture 里面的 teardown 用 yield 来唤醒teardown的执行
import pytest
@pytest.fixture(scope="module")
def open():
    print("打开浏览器,并且打开百度首页")
    yield
    print("执行 teardown!")
    print("最后关闭浏览器")
def test_s1(open):
    print("用例 1:搜索 python-1")
def test_s2(open):
    print("用例 2:搜索 python-2")
if __name__ == "__main__":
    pytest.main()

yield 遇到异常

  • 如果其中一个用例出现异常,不影响 yield 后面的 teardown 执行,运行结果互不影响,并且全部用例执行完成后, yield 呼唤 teardown操作。
  • 如果在 setup 就异常了,那么是不会去执行 yield 后面的teardown 内容了。
  • yield 也可以配合 with 语句使用。

8、参数化

parametrize

pytest.mark.parametrize 装饰器可以实现测试用例参数化。

import pytest
@pytest.mark.parametrize("test_input,expected",[ ("3+5", 8),("2+4", 6),("6 * 9", 42),])
def test_eval(test_input, expected):
    assert eval(test_input) == expected

它也可以标记单个测试实例在参数化 

import pytest

@pytest.mark.parametrize("test_input,expected",
   [ ("3+5", 8),("2+4", 6),
     pytest.param("6 * 9", 42,
    marks=pytest.mark.xfail)   #符合条件标记为失败
  ,]) def test_eval(test_input, expected): assert eval(test_input) == expected

9、参数组合

import pytest

@pytest.mark.parametrize("x", [0, 1])
@pytest.mark.parametrize("y", [2, 3])
def test_foo(x, y):
    print("测试数据组合: x->%s, y->%s" % (x, y))

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

10、HTML报告(pytest-html) 

安装

pytest-HTML 是一个插件, pytest 用于生成测试结果的 HTML 报告。

pip 安装

> pip install pytest-html

执行方法

> pytest --html=report.html

此方法生成的报告, css 是独立的,分享报告的时候样式会丢失,为了更好的分享发邮件展示报告,可以把 css 样式合并到 html 里。

pytest --html=report.html --self-contained-html 

 

 

 

 

 

posted @ 2020-03-08 21:51  Delta.Farce  阅读(369)  评论(0编辑  收藏  举报