当前位置: 首页 > 工具软件 > Nose > 使用案例 >

python nose

卢俭
2023-12-01

1、为什么使用nose?

nose是对Pyunit的扩展,使用nose的优势:
(1)writing is easier: nose also supplies a number of helpful functions for writing timed tests, testing for exceptions, and other common use cases
(2)running is easier:nose collects tests automatically, as long as you follow some simple guidelines for organizing your library and test code
(3)Setting up your test environment is easier:nose supports fixtures at the package, module, class, and test case level
(4)plugins:nose supply plugins for code coverage etc. you can also wirte your own plugins

2、case discover

(1)testMatch:可配置的正则表达式,dir module class function 会和testMatch比较,看是否作为test case(符合testMatch 的 module中,unittest.TestCase的子类可以不符合命名规则)。默认值: ((?:^|[\b_\.-])[Tt]est,这个正则表达式看起来有点复杂,记个简单规则吧:目录、文件、函数以 test_开头,class以TestClassName开头,验证有效。
(2)package:package的命名规则不必符合testMatch,但为便于统一管理,还是符合testMatch规则比较好

3、setup / teardown:

package level:定义在 __inti__.py 中,只为package执行一次,不会为每个case都执行。
module level:定义在module中,只为module执行一次。
class level:定义在class内(类函数或实例函数都可以,试用貌似没有区别),不同于package/module level,为class内每个test 执行一次
function level:需要通过装饰器定义

def setup_func():
    "set up test fixtures"

def teardown_func():
    "tear down test fixtures"

@with_setup(setup_func, teardown_func)
def test():
    "test ..."

4、nose.tools

(1)nose.tools 提供unittest所有功能的断言,只是命名方式遵循PEP 8,名称会有变化。

from nose import tools

class TestClassOne(object):
    def test_1_in_One(self):
        tools.assert_false(False, 'shuld be flase')

(2)nose.tools 提供一些装饰器函数,比如限定case应该抛出的异常,限定case执行时间等(提供的装饰器函数没几个,基本都在tool文档里

from nose import tools
import time

class TestClassOne(object):
    @tools.raises(ZeroDivisionError)
    def test_1_in_One(self):
        1/0

    # tools.timed(s)
    @tools.timed(2)
    def test_2_in_One(self):
        time.sleep(1)

5、builtin plugins

命令行中,很多option的功能都是由plugin提供的,部分常用plugin如下:
(1)nosetests -s :nose不要捕获标准输出,使得stdout可以在shell窗口输出
(2)nosetests -a:运行指定标签的case。
举例:
nosetests -s -a speed=‘slow’,tag=‘new’,运行 tag=new 且 speed=slow 的case
nosetests -s -a speed=‘slow’ -a ‘!ok’,运行 speed=slow 且 没有’ok‘属性的case

from nose.plugins.attrib import attr
import time

class TestClassOne(object):
    @attr(speed='slow')
    def test_1_in_One(self):
        print 'slow test'

    # tools.timed(s)
    @attr(speed='slow', tag='new') # nose.plugins.attrib.attr 可以多层使用
    @attr('ok')   
    def test_2_in_One(self):
        print 'slow test'
        time.sleep(0.1)

(3)nosetests --collect-only:不实际运行,可以看到case总数。输出看起来像实际运行了case。。 一般与–with-id, -v 联合使用,可以输出具体的case名称,及每个case的执行id(第几个执行)

$ nosetests --collect-only
......
----------------------------------------------------------------------
Ran 6 tests in 0.019s

(4)nosetests --processes=NUM --process-timeout=SECONDS:启动多个进程并发执行case,processes一般设置为cpu核数
(5)testid plugin
case集不变的情况下,nose执行case的顺序是不变的。实际上每个case都有一个id,表示第几个执行。可以运行指定id的case,或只运行上次测试失败的case(不需要自己指定id,通过–failed参数)
(6)case中抛SkipTest异常即可。感觉使用unittest.skip的装饰器标记比较明显,以防忘记case是skip的

from nose.plugins.skip import SkipTest

class TestClassOne(object):
    def test_1_in_One(self):
        raise SkipTest

(7)nosetests --with-xunit:提供XUnit XML 格式的测试结果,并存储在nosetests.xml文件中。主要为jenkins等能理解xnuit格式文件的集成测试环境准备。
6、代码覆盖率
要使用coverage官方提供的覆盖率统计模块,比nose builtin code coverage模块更高级。

 类似资料:

相关阅读

相关文章

相关问答