python中更人性化的一個單元測試框架:nose2


如果你學過 python 進行自動化測試,你一定使用過 unittest。今天我們要講的 nose2 是一個高級版本的 unittest。他比 unittest 更容易理解,用起來也更加方便一些。

快速開始

nose2 在 unittest 的基礎上開發的,所以如果你之前是用 unittest 做測試,但是有想使用 nose2 的新特性,你可以在不改變原有代碼的情況下直接使用 nose2。

import unittest
import nose2

class TestAdd(unittest.TestCase):
    def test_add(self):
        self.assertEqual(1+1, 3)

if __name__ == '__main__':
    # 只需要替換這一行
    # unittest.main()
    nose2.main()

安裝

nose2 是第三方庫,需要自己安裝,直接在 cmd 運行 pip 指令安裝:

pip install nose2

運行測試用例

在快速開始當中,我們使用了在 python 代碼中用 nose2.main() 的方式去運行測試用例,這樣是完全 OK 的。

還有另外一種運行方式:直接在命令行通過 nose2 命令運行。他會在python文件中查找名稱以 test 開頭的測試文件,並運行它發現的每個以 test 開頭的測試函數名稱。比如說我的項目當中有 test_add.py, test_minus.py 這些文件,如果我想運行所有的測試用例,只需要在當前文件下輸入 cmd 命令,他就會自動去查找所有的測試用例,然后去執行:

nose2

運行指定文件夾下的測試用例

nose2 -s 文件夾名稱

我把登錄相關的用例都放到一個叫 login_case 的文件夾當中,當我執行 nose2 -s login_case 的時候,其他的用例是不會執行的, nose2 只會去找 login_case 文件夾下面的用例。

 

 

運行指定的測試用例

nose2 login_case.test_nose2_dir.test_login

在這個例子當中:

  • login_case 是存儲的文件夾
  • test_nose2_dir 是文件名稱
  • test_login 是測試用例方法的名稱

每一個層級之間,用 . 號隔開。

如果想測試 test_nose2_dir.py 文件下的所有用例:

nose2 login_case.test_nose2_dir

如果想測試 login_case 文件夾下的所有用例:

nose2 login_case

測試用例的命名

為什么 nose2 可以自動查找用例並且執行呢?是因為他在內部制定了規則,然后根據規則去判定。

比如首先他規定,你所有的測試用例文件名稱應該以 test 開頭,如果你不這么做,那這個文件就不是測試用例文件。以下的文件名都會被判定為測試用例文件:

test.py
test_add.py
testRegister.py

而這一些不會被判定為測試用例文件,從而被忽略:

add_test.py
a_test.py
register_test_file.py

高級特性

測試用例方法的編寫

與unittest不同的是,nose2 的測試用例並不一定要以類的形式存在,也可以使用函數。任何函數和類,只要名稱匹配一定的條件(例如,以test開頭或以test結尾等),都會被自動識別為測試用例。

def test_add():
    assert 1 == 2


if __name__ == '__main__':
    nose2.main()

參數化

類似於 unittest 當中的 ddt 模塊,不過比 ddt 模塊使用起來簡潔一些。在測試過程當中,通常會有多組測試用例數據,多組測試用例會共用一個測試用例的方法,從而實現數據驅動。在 nose2 當中你可以這樣使用:

import nose2
from nose2.tools import params

def add(a, b):
    return a + b

test_data = [
    {"data": (1, 2), "expected": 3},
    {"data": (2, 2), "expected": 4},
    {"data": (3, 2), "expected": 6},
]

@params(*test_data)
def test_add(data):
    assert add(*data["data"]) == data["expected"]

1, @params(*test_data) 會接收外部傳進來的多組測試數據;

2,test_add(data) 當中的 data 每次取出一組數據運行,所以,data 其實就是 {“data”: (1, 2), “expected”: 3} 這樣的一組數據。

3,這里因為有 3 組數據,所以運行的時候會有 3 個測試用例。

測試夾具

測試夾具是為了給測試用例准備前置條件和后置條件。

  • @with_setup(before_test) 表示在測試用例執行之前要執行的前置條件
  • @with_teardown(after_test) 表示在測試用例執行之后的后置條件
  • before_test 和 after_test 是自己定義的函數
from nose2.tools.decorators import with_setup, with_teardown

def before_test():
    print("before test")

def after_test():
    print("after test")

@with_setup(before_test)
@with_teardown(after_test)
def test_add(data):
    assert add(*data["data"]) == data["expected"]

 

總結

本篇我們介紹了 nose2 的簡單入門:

  • nose2 是在 unittest 的基礎上實現的,可以和 unittest 兼容,如果你沒有接觸過 unittest, 建議先從 unittest 學起,很多同學在網上看到一些說 unittest 過時或者是說 unittest 不高級的言論就開始批判,不對。 unittest 是 其他 python 單元測試框架的基礎,沒學好 unittest , 其他的框架你也學不好。
  • nose2 可以自動發現測試用例,你只需要運行 nose2 命令就可以,用起來非常簡單。
  • nose2 的測試用例名稱要符合規范,以 test 開頭,否則不會被判定為用例。
  • 你可以通過 -s 運行指定文件下的用例,也可以通過 . 號去運行單個用例。

 

nose2 vs unittest

nose2 上手會比 unittest 更簡單,使用 unittest, 需要同時掌握 testrunner, testsuite, testcase 等基本概念,還需要熟悉類和對象。 nose2 隱藏了這些細節設計,難度會更低一些。

nose2 可以直接運行 unittest 的測試用例,可以實現無縫切換。

但是並不是說 unittest 就不好。 unittest 做為一個 python 標准庫,和 python 版本綁定,非常穩定,不用擔心兼容性的問題。

如果要學習一個單元測試框架,建議從 unittest 開始,因為你可以接觸到 loader, suite, runner 這樣的組件,對理解測試框架更有幫助,學習好 unittest 以后,再學習 nose2 或者 pytest 這樣更高級的框架,能有效提升編程效率。

nose2 vs pytest

如果你只想學習一個高級單元測試框架,建議你學 pytest, 而不是 nose2。

nose2 足夠好,甚至看上去他的設計比 pytest 更加清晰,更容易理解。但是社區沒有 pytest 活躍,因此使用的人也比較少。

實際上,nose2 和 pytest 的用法很多都是非常類似的,學習了一個,另外一個也能輕松上手。nose2 對於加深對測試框架的理解有很大的好處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM