zoukankan      html  css  js  c++  java
  • 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 

     

     

     

     

     

  • 相关阅读:
    HDU 3374 String Problem(最小(大)表示 + KMP)
    HDU 1253 胜利大逃亡
    #include <cctype>
    HDU 4162 Shape Number(最小表示法)
    USACO section1.3 Mixing Milk 混合牛奶
    HDU 1572 下沙小面的(2)
    HDU 1969 Pie
    USACO section1.2 Milking Cows 挤牛奶(区间覆盖)
    HDU 2492 Ping pong (树状数组)
    筛选法打表:求某个数的素因子之和
  • 原文地址:https://www.cnblogs.com/070727sun/p/12444769.html
Copyright © 2011-2022 走看看