zoukankan      html  css  js  c++  java
  • Openstack_单元测试工具 tox

    目录

    扩展阅读

    Python Mock的入门

    Openstack 的单元测试工具

    • unittest: 是 Python 的标准库,提供了最基本的单元测试功能,包括 单元测试运行器(简称runner)单元测试框架。项目的单元测试代码的测试类可以继承 unittest.TestCase 类,那么这个类就能够被 runner 发现并且执行。同时, unittest.TestCase 这个类还定义了 setUp() , tearDown() , setUpClass() 和 tearDownClass() 方法,是用来运行 单元测试前的设置工作代码单元测试后的清理工作代码,可以使用 $ python -m unittest test_module 的命令来执行某个模块的单元测试。

    • mock: 用来模拟对象的行为,这样在进行单元测试的时候,可以指定任何对象的返回值,便于测试对外部接口有依赖的代码(导入型代码)。

    • testtools: 是个 unittest 的扩展框架,主要是在 unittest 的基础上提供了更好的 assert 功能,使得写单元测试更加方便。

    • fixtures: 的意思是固定装置,在 Python 的单元测试中,是指某段可以复用的单元测试 setUp() 和 tearDown() 代码组合。一个 fixture 一般用来实现某个组件的 setUp() 和 tearDown() 逻辑,比如: 测试前要先创建好某些数据,测试后要删掉这些数据,这些操作就可以封装到一个 fixture 中。这样不同的测试用例就不用重复写这些代码,只要使用 fixture 即可。fixtures 模块是一个第三方模块,提供了一种简单的创建 fixture 类和对象的机制,并且也提供了一些内置的 fixture。

    • testscenarios: 模块满足了场景测试的需求。它的基本用法是在测试类中添加一个类属性 scenarios ,该属性是一个元组,定义了每一种不同的场景下都会不同的变量值。比如说你测试一段数据访问代码,你需要测试该代码在使用不同的驱动时(MongoDB/MySQL/File)是否都能正常工作。最好的办法就是使用 testscenarios 模块,定义好会应场景而改变的 scenarios 变量,然后实现一个测试用例方法。testscenarios 模块在 OpenStack Ceilometer 中被大量使用。

    • subunit: 是一个用于传输单元测试结果的流协议。一般来说,运行单元测试的时候是把单元测试的结果直接输出到标准输出,但是如果运行大量的测试用例时,这些大量的测试结果将难以被分析。因此使用 python-subunit 模块来运行测试用例,并且把测试结果通过 subunit 协议输出,这样测试结果就可以被分析工具聚合并且分析。python-subunit 模块也自带了一些分析工具用来解析 subunit 协议,比如:$ python -m subunit.run test_module | subunit2pyunit , subunit2pyunit 指令会解析 subunit 协议,并且将结果输出到标准输出。

    • testrepository: 用于管理单元测试用例, 当一个项目中的测试用例很多时,如何更有效的处理单元测试用例的结果就变得很重要。testrepository 会使用 python-subunit 模块来运行测试用例,然后分析 subunit 协议的输出并将测试结果记录到本地文件. testrepository 能够让你:

      • 知道哪些用例运行时间最长
      • 显示运行失败的用例
      • 重新运行上次运行失败的用例
    • coverage: 是用来计算代码运行时的覆盖率的,也就是统计多少代码被执行了。它可以和testrepository一起使用,用来统计单元测试的覆盖率,在运行完单元测试之后,输出覆盖率报告。

    • tox: tox是用来管理和构建虚拟环境(virtualenv)的。对于一个项目,我们需要运行Python 2.7的单元测试,也需要运行Python 3.4的单元测试,还需要运行PEP8的代码检查。这些不同的任务需要依赖不同的库,所以需要使用不同的虚拟环境。使用tox的时候,我们会在tox的配置文件 tox.ini 中指定不同任务的虚拟环境名称,该任务在虚拟环境中需要安装哪些包,以及该任务执行的时候需要运行哪些命令。 tox 是本篇博文主要的研究对象, 所以我们会在下文继续深入的记录 tox 的具体内容.

    单元测试工具使用流程

    • 首先使用 unittest, mock, testtools, fixtures, testscenarios 等工具和模块来编写单元测试用例
    • 然后使用 tox 来管理单元测试运行时的虚拟环境
    • tox 再调用 testrepository 来管理这些测试用例
    • 其中 testrepository 会调用 subunit 来执行测试用例, 并且一同聚合和分析测试结果
    • 然后 testrepository 调用 coverage 来执行代码覆盖率的计算

    当我们执行 tox -e py27 时就是开始项目的单元测试, tox 首先会读取项目根目录下的 tox.ini 文件(/opt/stack/keystone/tox.ini ), 然后根据该文件来构建出相应的虚拟环境, 并将该虚拟环境保存在 .tox/ 目录下(以环境的名称来命名).

    fanguiju@fanguiju:/opt/stack/keystone/.tox$ ls
    log  pep8  py27

    除了 log 之外的 py27/pep8 都是 virtualenv 环境.

    tox

    一般 openstack 项目中的 tox 的功能包含了: 打源码包(sdist)、单元测试(UT)、测试覆盖率(coverage)、代码格式检查(pep8,flake) 等功能.

    tox 的官方对于 tox 的定义是这样的: 一个通用的虚拟环境管理和测试命令行工具。其中的虚拟环境, 相信使用过 virtualenv 的开发者来说都不会陌生, tox 能够让我们在同一个 Host 上自定义出多套相互独立且隔离的 Python 环境, 所套虚拟环境中可能使用了不同的 Python 拦截器/环境变量设置/第三方依赖包/… 所以 tox 最典型的应用就是用于测试 Python 程序的兼容性了.

    tox.ini

    [tox]
    minversion =1.6
    skipsdist = True
    envlist = py27,pep8,com    
    # envlist 表示 tox 中配置的环境都有哪些
    
    [testenv]   
    #  testenv 是默认配置,如果某个环境自身的 section 中没有定义这些配置, 那么就从这个 section 中读取
    
    setenv = VIRTUAL_ENV={envdir}
             PYTHONHASHSEED=0
             PYCURL_SSL_LIBRARY=openssl
    # setenv 列出了虚拟机环境中生效的环境变量,一些配色方案和单元测试标志
    
    usedevelop = True   
    # usedevelop 表示安装 virtualenv 时, 项目自身是采用开发模式安装的, 所以不会拷贝代码到 virtualenv 目录中, 只是做个链接
    
    install_command = pip install {opts} {packages}   
    # 表示构建环境的时候要执行的命令,一般是使用 pip 安装
    
    deps = -r{toxinidir}/requirements.txt
           -r{toxinidir}/test-requirements.txt
    # deps 指定构建环境时需要安装的第三方依赖包
    # 每个虚拟环境创建的时候, 会通过 pip install -r requirements.txt 和 pip install -r test-requirements.txt 安装依赖包到虚拟环境
    # 一般的项目会直接安装 requirements 和 test-requirements 两个文件中的所有依赖包
    
    commands = ostestr {posargs}
    # commands 表示构建好 virtualenv 之后要执行的命令
    # 这里调用了 ostestr 指令来调用 testrepository 执行单元测试用例
    # {posargs} 参数就是可以将 tox 指令的参数传递给 ostestr
    
    whitelist_externals = bash
    passenv = http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy NO_PROXY
    
    [testenv:py34]
    commands =
      python -m testtools.run
    # 这个 section 是为 py34 环境定制某些配置的,没有定制的配置,将会从 [testenv] 读取
    
    [testenv:pep8]
    commands =
      flake8 {posargs} ./egis egis/common
      # Check that .po and .pot files are valid:
      bash -c "find egis -type f -regex '.*.pot?' -print0|xargs -0 -n 1 msgfmt --check-format -o /dev/null"
      {toxinidir}/tools/config/check_uptodate.sh
      {toxinidir}/tools/check_exec.py {toxinidir}/egis
    # 执行 tox -e pep8 进行代码检查, 实际上是执行了上述指令来进行代码的语法规范检查
    
    [tox:jenkins]
    downloadcache = ~/cache/pip
    # 定义了 CI server jenkins 的集成配置
    # 指定了 pip 的下载 cache 目录,提高构建虚拟环境的速度
    
    [testenv:cover]
    # Also do not run test_coverage_ext tests while gathering coverage as those
    # tests conflict with coverage.
    commands =
      python setup.py testr --coverage 
        --testr-args='^(?!.*test.*coverage).*$'
    # 定义一个 cover 虚拟环境,使单元测试的时候,自动应用 coverage
    
    ...

    参考文章

    通过demo学习OpenStack开发——单元测试

    相关阅读:

  • 相关阅读:
    编程的核心思维
    对编程语言的一点总结
    End Poem
    linux下的errno对照表
    C++中的三个特殊宏:__FILE__,__FUNCTION__和__LINE__
    算法——从斐波那契数列谈起(一)
    [题解][HNOI2002][Luogu P2234] 营业额统计
    用STL水平衡树的题
    浅谈C++的智能指针
    cnblog代码高亮优化(tomorrow主题)
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13310717.html
Copyright © 2011-2022 走看看