1. 程式人生 > >unittest單元測試框架總結

unittest單元測試框架總結

unittest單元測試框架不僅可以適用於單元測試,還可以適用WEB自動化測試用例的開發與執行,該測試框架可組織執行測試用例,並且提供了豐富的斷言方法,判斷測試用例是否通過,最終生成測試結果。今天筆者就總結下如何使用unittest單元測試框架來進行WEB自動化測試。

目錄

一、unittest模組的各個屬性說明

二、使用unittest框架編寫測試用例思路

三、使用unittest框架編寫測試用例例項

一、unittest模組的各個屬性說明

點選返回目錄

先來聊一聊unittest模組的各個屬性,所謂知己知彼方能百戰百勝,瞭解unittest的各個屬性,對於後續編寫用例有很大的幫助。

1.unittest的屬性如下:

[‘BaseTestSuite’, ‘FunctionTestCase’, ‘SkipTest’, ‘TestCase’, ‘TestLoader’, ‘TestProgram’, ‘TestResult’, ‘TestSuite’, ‘TextTestResult’, ‘TextTestRunner’, ‘_TextTestResult’, ‘all‘, ‘builtins‘, ‘doc‘, ‘file‘, ‘name‘, ‘package‘, ‘path‘, ‘__unittest’, ‘case’, ‘defaultTestLoader’, ‘expectedFailure’, ‘findTestCases’, ‘getTestCaseNames’, ‘installHandler’, ‘loader’, ‘main’, ‘makeSuite’, ‘registerResult’, ‘removeHandler’, ‘removeResult’, ‘result’, ‘runner’, ‘signals’, ‘skip’, ‘skipIf’, ‘skipUnless’, ‘suite’, ‘util’]

說明:

unittest.TestCase:TestCase類,所有測試用例類繼承的基本類。

class BaiduTest(unittest.TestCase):

unittest.main():使用她可以方便的將一個單元測試模組變為可直接執行的測試指令碼,main()方法使用TestLoader類來搜尋所有包含在該模組中以“test”命名開頭的測試方法,並自動執行他們。執行方法的預設順序是:根據ASCII碼的順序載入測試用例,數字與字母的順序為:0-9,A-Z,a-z。所以以A開頭的測試用例方法會優先執行,以a開頭會後執行。

unittest.TestSuite():unittest框架的TestSuite()類是用來建立測試套件的。

unittest.TextTextRunner():unittest框架的TextTextRunner()類,通過該類下面的run()方法來執行suite所組裝的測試用例,入參為suite測試套件。

unittest.defaultTestLoader(): defaultTestLoader()類,通過該類下面的discover()方法可自動更具測試目錄start_dir匹配查詢測試用例檔案(test*.py),並將查詢到的測試用例組裝到測試套件,因此可以直接通過run()方法執行discover。用法如下:

discover=unittest.defaultTestLoader.discover(test_dir, pattern=’test_*.py’)

unittest.skip():裝飾器,當執行用例時,有些用例可能不想執行等,可用裝飾器暫時遮蔽該條測試用例。一種常見的用法就是比如說想除錯某一個測試用例,想先遮蔽其他用例就可以用裝飾器遮蔽。

@unittest.skip(reason): skip(reason)裝飾器:無條件跳過裝飾的測試,並說明跳過測試的原因。

@unittest.skipIf(reason): skipIf(condition,reason)裝飾器:條件為真時,跳過裝飾的測試,並說明跳過測試的原因。

@unittest.skipUnless(reason): skipUnless(condition,reason)裝飾器:條件為假時,跳過裝飾的測試,並說明跳過測試的原因。

@unittest.expectedFailure(): expectedFailure()測試標記為失敗。

2.TestCase類的屬性如下:

[‘call‘, ‘class‘, ‘delattr‘, ‘dict‘, ‘doc‘, ‘eq‘, ‘format‘, ‘getattribute‘, ‘hash‘, ‘init‘, ‘module‘, ‘ne‘, ‘new‘, ‘reduce‘, ‘reduce_ex‘, ‘repr‘, ‘setattr‘, ‘sizeof‘, ‘str‘, ‘subclasshook‘, ‘weakref‘, ‘addSkip’, ‘_baseAssertEqual’, ‘_classSetupFailed’, ‘_deprecate’, ‘_diffThreshold’, ‘_formatMessage’, ‘_getAssertEqualityFunc’, ‘_truncateMessage’, ‘addCleanup’, ‘addTypeEqualityFunc’, ‘assertAlmostEqual’, ‘assertAlmostEquals’, ‘assertDictContainsSubset’, ‘assertDictEqual’, ‘assertEqual’, ‘assertEquals’, ‘assertFalse’, ‘assertGreater’, ‘assertGreaterEqual’, ‘assertIn’, ‘assertIs’, ‘assertIsInstance’, ‘assertIsNone’, ‘assertIsNot’, ‘assertIsNotNone’, ‘assertItemsEqual’, ‘assertLess’, ‘assertLessEqual’, ‘assertListEqual’, ‘assertMultiLineEqual’, ‘assertNotAlmostEqual’, ‘assertNotAlmostEquals’, ‘assertNotEqual’, ‘assertNotEquals’, ‘assertNotIn’, ‘assertNotIsInstance’, ‘assertNotRegexpMatches’, ‘assertRaises’, ‘assertRaisesRegexp’, ‘assertRegexpMatches’, ‘assertSequenceEqual’, ‘assertSetEqual’, ‘assertTrue’, ‘assertTupleEqual’, ‘assert‘, ‘countTestCases’, ‘debug’, ‘defaultTestResult’, ‘doCleanups’, ‘fail’, ‘failIf’, ‘failIfAlmostEqual’, ‘failIfEqual’, ‘failUnless’, ‘failUnlessAlmostEqual’, ‘failUnlessEqual’, ‘failUnlessRaises’, ‘failureException’, ‘id’, ‘longMessage’, ‘maxDiff’, ‘run’, ‘setUp’, ‘setUpClass’, ‘shortDescription’, ‘skipTest’, ‘tearDown’, ‘tearDownClass’]

說明:

setUp():setUp()方法用於測試用例執行前的初始化工作。如測試用例中需要訪問資料庫,可以在setUp中建立資料庫連線並進行初始化。如測試用例需要登入web,可以先例項化瀏覽器。

tearDown():tearDown()方法用於測試用例執行之後的善後工作。如關閉資料庫連線。關閉瀏覽器。

assert*():一些斷言方法:在執行測試用例的過程中,最終用例是否執行通過,是通過判斷測試得到的實際結果和預期結果是否相等決定的。

assertEqual(a,b,[msg=’測試失敗時列印的資訊’]):斷言a和b是否相等,相等則測試用例通過。

assertNotEqual(a,b,[msg=’測試失敗時列印的資訊’]):斷言a和b是否相等,不相等則測試用例通過。

assertTrue(x,[msg=’測試失敗時列印的資訊’]):斷言x是否True,是True則測試用例通過。

assertFalse(x,[msg=’測試失敗時列印的資訊’]):斷言x是否False,是False則測試用例通過。

assertIs(a,b,[msg=’測試失敗時列印的資訊’]):斷言a是否是b,是則測試用例通過。

assertNotIs(a,b,[msg=’測試失敗時列印的資訊’]):斷言a是否是b,不是則測試用例通過。

assertIsNone(x,[msg=’測試失敗時列印的資訊’]):斷言x是否None,是None則測試用例通過。

assertIsNotNone(x,[msg=’測試失敗時列印的資訊’]):斷言x是否None,不是None則測試用例通過。

assertIn(a,b,[msg=’測試失敗時列印的資訊’]):斷言a是否在b中,在b中則測試用例通過。

assertNotIn(a,b,[msg=’測試失敗時列印的資訊’]):斷言a是否在b中,不在b中則測試用例通過。

assertIsInstance(a,b,[msg=’測試失敗時列印的資訊’]):斷言a是是b的一個例項,是則測試用例通過。

assertNotIsInstance(a,b,[msg=’測試失敗時列印的資訊’]):斷言a是是b的一個例項,不是則測試用例通過。

3.TestSuite類的屬性如下:(組織用例時需要用到)

[‘call‘, ‘class‘, ‘delattr‘, ‘dict‘, ‘doc‘, ‘eq‘, ‘format‘, ‘getattribute‘, ‘hash‘, ‘init‘, ‘iter‘, ‘module‘, ‘ne‘, ‘new‘, ‘reduce‘, ‘reduce_ex‘, ‘repr‘, ‘setattr‘, ‘sizeof‘, ‘str‘, ‘subclasshook‘, ‘weakref‘, ‘_addClassOrModuleLevelException’, ‘_get_previous_module’, ‘_handleClassSetUp’, ‘_handleModuleFixture’, ‘_handleModuleTearDown’, ‘_tearDownPreviousClass’, ‘_tests’, ‘addTest’, ‘addTests’, ‘countTestCases’, ‘debug’, ‘run’]

說明:

addTest(): addTest()方法是將測試用例新增到測試套件中,如下方,是將test_baidu模組下的BaiduTest類下的test_baidu測試用例新增到測試套件。

suite = unittest.TestSuite()
suite.addTest(test_baidu.BaiduTest(‘test_baidu’))

4.TextTextRunner的屬性如下:(組織用例時需要用到)

[‘class‘, ‘delattr‘, ‘dict‘, ‘doc‘, ‘format‘, ‘getattribute‘, ‘hash‘, ‘init‘, ‘module‘, ‘new‘, ‘reduce‘, ‘reduce_ex‘, ‘repr‘, ‘setattr‘, ‘sizeof‘, ‘str‘, ‘subclasshook‘, ‘weakref‘, ‘_makeResult’, ‘buffer’, ‘descriptions’, ‘failfast’, ‘resultclass’, ‘run’, ‘stream’, ‘verbosity’]

說明:

run(): run()方法是執行測試套件的測試用例,入參為suite測試套件。

runner = unittest.TextTestRunner()
runner.run(suite)

二、使用unittest框架編寫測試用例思路

點選返回目錄

設計基本思路如下:
複製程式碼

coding=utf-8

1.先設定編碼,utf-8可支援中英文,如上,一般放在第一行

2.註釋:包括記錄建立時間,建立人,專案名稱。

”’
Created on 2016-7-27
@author: Jennifer
Project:使用unittest框架編寫測試用例思路
”’

3.匯入unittest模組

import unittest

4.定義測試類,父類為unittest.TestCase。

可繼承unittest.TestCase的方法,如setUp和tearDown方法,不過此方法可以在子類重寫,覆蓋父類方法。

可繼承unittest.TestCase的各種斷言方法。

class Test(unittest.TestCase):

5.定義setUp()方法用於測試用例執行前的初始化工作。

注意,所有類中方法的入參為self,定義方法的變數也要“self.變數”

注意,輸入的值為字元型的需要轉為int型

def setUp(self):
    self.number=raw_input('Enter a number:')
    self.number=int(self.number)

6.定義測試用例,以“test_”開頭命名的方法

注意,方法的入參為self

可使用unittest.TestCase類下面的各種斷言方法用於對測試結果的判斷

可定義多個測試用例

最重要的就是該部分

def test_case1(self):
    print self.number
    self.assertEqual(self.number,10,msg='Your input is not 10')

def test_case2(self):
    print self.number
    self.assertEqual(self.number,20,msg='Your input is not 20')

@unittest.skip('暫時跳過用例3的測試')
def test_case3(self):
    print self.number
    self.assertEqual(self.number,30,msg='Your input is not 30')

7.定義tearDown()方法用於測試用例執行之後的善後工作。

注意,方法的入參為self

def tearDown(self):
    print 'Test over'

8如果直接執行該檔案(name值為main),則執行以下語句,常用於測試指令碼是否能夠正常執行

if name==’main‘:

8.1執行測試用例方案一如下:

unittest.main()方法會搜尋該模組下所有以test開頭的測試用例方法,並自動執行它們。

執行順序是命名順序:先執行test_case1,再執行test_case2

unittest.main()

”’

8.2執行測試用例方案二如下:

8.2.1先構造測試集

8.2.1.1例項化測試套件

suite=unittest.TestSuite()

8.2.1.2將測試用例載入到測試套件中。

執行順序是安裝載入順序:先執行test_case2,再執行test_case1

suite.addTest(Test('test_case2'))
suite.addTest(Test('test_case1'))

8.2.2執行測試用例

8.2.2.1例項化TextTestRunner類

runner=unittest.TextTestRunner()

8.2.2.2使用run()方法執行測試套件(即執行測試套件中的所有用例)

runner.run(suite)

”’

”’

8.3執行測試用例方案三如下:

8.3.1構造測試集(簡化了方案二中先要建立測試套件然後再依次載入測試用例)

執行順序同方案一:執行順序是命名順序:先執行test_case1,再執行test_case2

test_dir = './'
discover = unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')

8.3.2執行測試用例

8.3.2.1例項化TextTestRunner類

runner=unittest.TextTestRunner()

8.3.2.2使用run()方法執行測試套件(即執行測試套件中的所有用例)

runner.run(discover)   

”’

複製程式碼

使用方案一執行測試用例結果如下:

Enter a number:10
10
Test over
Enter a number:.10
Fs

Ran 3 tests in 6.092s

FAILED (failures=1, skipped=1)
10
Test over

因為先執行test_case1,再執行test_case2,所以第一次輸入10時,執行通過,返回. 第二次輸入10時,執行不通過,返回F,最終一個用例通過,一個用例失敗,還有一個用例是直接跳過的(裝飾器)。

使用方案二執行測試用例結果如下:

Enter a number:10
10
Test over
Enter a number:F10
.

Ran 2 tests in 4.973s

FAILED (failures=1)
10
Test over

因為先執行test_case2,再執行test_case1,所以第一次輸入10時,執行不通過,返回F , 第二次輸入10時,執行通過,返回. ,最終一個用例通過,一個用例失敗。

使用方案三執行測試用例結果如下(執行測試用例順序同方案一):

Enter a number:10
10
Test over
Enter a number:.10
Fs

Ran 3 tests in 6.092s

FAILED (failures=1, skipped=1)
10
Test over

因為先執行test_case1,再執行test_case2,所以第一次輸入10時,執行通過,返回. 第二次輸入10時,執行不通過,返回F,最終一個用例通過,一個用例失敗,還有一個用例是直接跳過的(裝飾器)。

三、使用unittest框架編寫測試用例例項

點選返回目錄

目錄結構:

百度搜索測試用例Test Case:
複製程式碼

coding=utf-8

”’
Created on 2016-7-22
@author: Jennifer
Project:登入百度測試用例
”’
from selenium import webdriver
import unittest, time

class BaiduTest(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(30) #隱性等待時間為30秒
self.base_url = “https://www.baidu.com

def test_baidu(self):
    driver = self.driver
    driver.get(self.base_url + "/")
    driver.find_element_by_id("kw").clear()
    driver.find_element_by_id("kw").send_keys("unittest")
    driver.find_element_by_id("su").click()
    time.sleep(3)
    title=driver.title
    self.assertEqual(title, u"unittest_百度搜索") 

def tearDown(self):
    self.driver.quit()

if name == “main“:
unittest.main()

複製程式碼

有道翻譯測試用例Test Case:
複製程式碼

coding=utf-8

”’
Created on 2016-7-22
@author: Jennifer
Project:使用有道翻譯測試用例
”’
from selenium import webdriver
import unittest, time

class YoudaoTest(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(30) #隱性等待時間為30秒
self.base_url = “http://www.youdao.com

def test_youdao(self):
    driver = self.driver
    driver.get(self.base_url + "/")
    driver.find_element_by_id("translateContent").clear()
    driver.find_element_by_id("translateContent").send_keys(u"你好")
    driver.find_element_by_id("translateContent").submit()
    time.sleep(3)
    page_source=driver.page_source
    self.assertIn( "hello",page_source) 

def tearDown(self):
    self.driver.quit()

if name == “main“:
unittest.main()

複製程式碼

web測試用例:通過測試套件TestSuite來組裝多個測試用例。
複製程式碼

coding=utf-8

”’
Created on 2016-7-26
@author: Jennifer
Project:編寫Web測試用例
”’
import unittest
from test_case import test_baidu
from test_case import test_youdao

構造測試集

suite = unittest.TestSuite()
suite.addTest(test_baidu.BaiduTest(‘test_baidu’))
suite.addTest(test_youdao.YoudaoTest(‘test_youdao’))

if name==’main‘:
#執行測試
runner = unittest.TextTestRunner()
runner.run(suite)

複製程式碼

測試結果:

說明:.代表用例執行通過,兩個點表示兩個用例執行通過。F表示用例執行不通過。