python nose

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/Test 開頭
(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模塊更高級。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章