­

細說unittest-2

  • 2020 年 1 月 16 日
  • 筆記

一、unittest模組官方文檔:

https://docs.python.org/3/library/unittest.html

二、一張圖看懂unittest:

三、Unittest主要方法屬性:

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

class myfunTest(unittest.TestCase):

       def setUp(self):

       print('每個用例執行前都會調用setUp準備環境')

2.unittest.main():使用它可以方便的將一個單元測試模組變為可直接運行的測試腳本,main()方法使用TestLoader類來搜索所有包含在該模組中以「test」命名開頭的測試方法,並自動執行它們。執行方法的默認順序是:根據ASCII碼的順序載入測試用例,數字與字母的順序為:0-9,A-Z,a-z.所以以A開頭的測試用例方法會優先執行,以a開頭會執行:

if __name=="__main__()":

      unittest.main()

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

 tests=myfunTest("test_is_prime")

    suite=unittest.TestSuite()

    suite.addTest(tests)

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

runner=unittest.TextTestRunner()

    runner.run(suite)

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

 discover=unittest.defaultTestLoader.discover(test_dir,pattern=』test*.py』):

    test_dir = r'D:CollectionOverviewwebzidonghu'

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

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

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

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

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

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

@unittest.skipUnless(sys.platform.startswith('linux'),'requires Linux') #跳過該測試用例

def test_divide(self):

        ''' test method divide '''

      print('divide')

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

def setUp(self):

        url='https://mail.yeah.net/'

      self.browser=webdriver.Firefox()

      self.browser.got(url)

      time.sleep(5)

8.tearDown():用於測試用例執行之後的善後工作。如關閉資料庫鏈接。關閉瀏覽器:

 def tearDown(self):

        self.browser.closet()

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

self.assertTrue(is_prime(5))

 self.assertFalse(is_prime(-3))

10.addTest():將測試用例添加到測試套件中,如下方,是將test_baidu模組下的BaiduTest類下的test_baidu測試用例添加到測試套件:

 suite=unittest.TestSuite()

    suite.addTest(test_baidu.BaiduTest(『test_baidu』))

11.run():運行測試套件的測試用例,入參為suite測試套件:

runner=unittest.Text.Text.Runner()

    runner.run(suite)

四、框架如何解決自動化需求的4個問題:

1.如何控制用例執行順序?

在unittest中,用例是以test開頭的方法定義的,默認執行順序是根據用例名稱的ASCII碼升序進行如上面的用例,實際執行順序為:test_add->test_divide->test_is_prime,而不是用例定義的先後順序。在unittest中解決用例執行順序的問題是使用TestSuite,程式碼如下:

#使用TestSuite控制用例順序,用例的執行順序是由添加到TestSuite的順序決定的 tests=[myfunTest("test_is_prime"),myfunTest("test_add"),myfunTest("test_divide")] suite=unittest.TestSuite() #suite.addTest() suite.addTest(tests) #將測試用例實例增加到測試套件中 runner=unittest.TextTestRunner() runner.run(suite)

 2.如何讓多個用例共用setUp,tearDown?

Unittest的setUp、tearDown會在每個用例執行前後執行一次,如上面測試用例類中有3個測試用例,那麼每個用例執行前會執行setUp,執行後會執行tearDown,即setUp、tearDown總共會調用三次,但考慮實際自動化測試場景,多個用例只需執行一次setUp,全部用例執行完成後,執行一次tearDown,針對該種場景,unittest的處理方法是使用setupclass、teardownclass,注意@classmethod的使用,程式碼如下:

@classmethod def setUpClass(cls): print('所有用例執行前會調用一次setUp準備環境') @classmethod def tearDownClass(cls): print('所有用例執行後會調用一次tearDown進行環境清理')

 3.如何跳過用例:

在自動化測試中,經常會遇到挑選用例的清況,在unittest中的解決方法是使用skip裝飾器,其中skip裝飾器主要有3種:

unittest.skip(reason),

unittst.skipif(condition,reason),

unittest.skipUnless(condition,reason),

即在滿足conditiong條件下跳過該用例,reason用於描述跳過的原因,實例程式碼如下:

@unittest.skipUnless(sys.platform.startswith('linux'),'requires Linux') #跳過該測試用例 def test_divide(self): ''' test method divide ''' print('divide') self.assertEqual(2,divide(6,3)) self.assertNotEqual(2,divide(5,2))

 4.如何生成html格式的測試報告:

Unittest中默認生成的報告格式為txt,如果想生成html格式的報告,可以使用HtmlTestRunner模組,安裝後導入該模組,使用HTMLTestRunner代替默認的TextTestRunner()執行測試用例即可。實例程式碼如下:

suite=unittest.TestSuite() suite.addTest(unittest.TestLoader().loadTestFromTest(myfunTest)) #使用TestLoader載入測試用例 runner=HTMLTestRunner(output="result") runner.run(suite)

五、完整程式碼如下:

 1 import unittest   2 #https://pypi.org/project/html-testRunner   3 from HtmlTestRunner import HTMLTestRunner    #導入第三方模組,執行結果生成html報告:pip install html-testRunner   4   5 class myfunTest(unittest.TestSuite):   6     ''' test myfunTest: test fixture only once '''   7   8   9     @classmethod  10     def setUpClass(cls):  11         print('所有用例執行前會調用一次setUp準備環境')  12  13  14     @classmethod  15     def tearDownClass(cls):  16         print('所有用例執行後會調用一次tearDown進行環境清理')  17  18  19     def test_add(self):  20         ''' test method add(a,b) '''  21         print('add')  22         self.assertEqual(3,add(1,2))  23         self.assertNotEqual(3,add(2,2))  24  25  26     @unittest.skipUnless(sys.platform.startswith('linux'),'requires Linux')    #跳過該測試用例  27     def test_mul(self):  28         ''' test method mul '''  29         print('mul')  30         self.assertEqual(2,mul(6,3))  31         self.assertNotEqual(13,mul(7,2))  32  33  34 if __name__=='__main__':  35     suite=unittest.TestSuite()  36     suite.addTest(unittest.TestLoader().loadTestFromTest(myfunTest))    #使用TestLoader載入測試用例  37  38     runner=HTMLTestRunner(output="result")  39     runner.run(suite)
 1 #coding=utf-8   2   3 import unittest   4   5   6 class myfunTest(unittest.TestCase):   7      '''Test myfunTes'''   8   9  10     def setUp(self):  11         print('每個用例執行前都會調用setUp準備環境')  12  13  14     def is_prime(number):  15         if number<0 or number in (0,2):  16             return False  17         for element in range(2,number):  18             if number%element==0:  19                 return False  20         return True  21  22  23     def add(a,b):  24         return a+b  25  26  27     def mul(a,b):  28         return a*b  29  30  31     def test_is_prime(self):  32         '''  33         Test method is_prime(number)  34         '''  35         print('is_prime')  36         self.assertTrue(is_prime(5))  37         self.assertFalse(is_prime(8))  38         self.assertFalse(is_prime(-3))  39  40  41     def test_add(self):  42         '''  43         Test method add(a,b)  44         '''  45         print('add')  46         self.assertEqual(3,add(1,2))  47         self.assertNotEqual(3,add(2,2))  48  49  50     def test_mul(self):  51         '''  52         Test method mul  53         '''  54         print ('mul')  55         self.assertEqual(18,mul(6,3))  56         self.assertNotEqual(6,mul(3,2))  57  58  59     def tearDown(self):  60         print('每個用例執行完都會調用tearDown進行環境清理')  61  62  63 if __name__='__main__':  64     #使用TestSuite控制用例順序,用例的執行順序是由添加到TestSuite的順序決定的  65     tests=[myfunTest("test_is_prime"),myfunTest("test_add"),myfunTest("test_mul")]  66  67     suite=unittest.TestSuite()  68     #suite.addTest()  69     suite.addTest(tests)    #將測試用例實例增加到測試套件中  70  71     runner=unittest.TextTestRunner()  72     runner.run(suite)