Python 自動化測試框架unittest

weixin_33797791發表於2019-01-09

最近工作中向同事學習了用Python作自動化測試,另外簡單查些資料做些補充。

測試的通用規則
  • 測試單元應該集中於小部分的功能,並且證明它是對的。
  • 每個測試單元應該完全獨立,它們都能夠單獨執行,也可以在測試套件中執行,而不用考慮被呼叫的順序。

unittest

unittest 是Python內建的單元測試測試框架,具備編寫用例,組織用例, 執行用例,輸出報告等自動化框架的條件。即 test fixture,test case,test suite,test Loader,test runner 。

  • test fixture
    一個測試用例的初始化準備及環境還原,主要是 setUp() 和 setDown() 方法。

  • test case
    一個完整的測試單元,執行該測試單元可以完成對某一個問題的驗證。完整體現在:測試前環境準備,執行測試程式碼,及測試後環境還原。

  • test suite
    多個測試用例的集合,測試套件或測試計劃。

  • test Loader
    載入 TestCase 到 TestSuite 中的。

  • test runner
    執行測試用例,並將測試結果儲存到TextTestResult例項中,包括執行了多少測試用例, 成功了多少,失敗了多少等資訊。


unittest的工作原理

通過unittest類呼叫分析,


unittest實戰
  • 待測模組
    def is_prime(number):
        if number < 0 or number in (0, 1):
            return False;
        for element in range(2, number):
            if number % element == 0:
                return False;
        return True
    
    def add(a, b):
        return a + b;
    
    def divide(a, b):
        return a / b; 
    
  • 使用unittest編寫測試用例
    import unittest
    class TestMyFunc(unittest.TestCase):
      def setup(self):
          print("每個用例執行前後會呼叫setUp方法準備環境")
      def tearDown(self):
          printf("每個用例執行前後會呼叫tearDown方法進行環境清理");
    
      def test_is_prime(self):
          '''test method is_prime'''
          self.assertEqual(is_prime(5))
          self.assertEqual(is_prime(0))
          self.assertEqual(is_prime(-1))
    
      def test_add(self)
          '''test method divide'''
          self.assertEqual(3, add(1, 2))
          self.assertEqual(3, add(2, 2))      
    
      def test_divide(self):
           '''test method divide''' 
           self.assertEqual(3, divide(6, 3))
           self.assertEqual(3, divide(5, 2))      
    
    if __name == '__main__':
        unittest.main()
    

框架解決自動化需求的4個問題
  • 如何控制用例執行順序
    在unittest中,用例是以test開頭的方法定義的,預設執行順序是根據用例名稱升序進行,為不是用例定義的先後順序。在unittest中解決順序的問題是使用TestSuite。程式碼如下:

    if __name__ == '__main__':
        tests = [TestMyFunc("test_is_prime"), TestMyFunc("test_add"), TestMyFunc("test_divide")]
    
        suite = unittest.TestSuite()
        suite.addTest(tests);
      
        runner = unittest.TextTestRunner()
        runner.run(suite)
    
  • 如何讓多個用例共用setup,teardown
    unitest 的 setup,teardown 會在用例執行前後執行一次,如上面測試用例類中有3個測試用例,那麼每個用例執行前後執行 setup,執行後會執行teardown,即 setup,teardown 總過呼叫三次。但考慮實際自動化測試場景,多個用例只需執行一次setup,全部用例執行完成後,執行一次teardown,針對該種場景,unittest的處理方法是使用setupclassteardownclass,注意如下:

    class TestMyFunc(unittest.TestCase):
        @classmethod
        def setUpClass(cls):
            print('所有用例執行前會呼叫一次setUp準備環境')
        @classmethod
        def tearDownClass(cls):
            print('所有用例執行後會呼叫一次tearDown進行環境清理')
        
        def test_is_prime(self):
            ''' test method divide'''
            self.assertEqual(2, divide(6, 3))
            slef.assertNotEqual(2, divide(5, 2))
    
    if __name__ == '__main__':
        unittest.main()
    
  • 如何跳過用例
    在自動化測試中,可能會用到選擇性執行用例的情況,在unittest中解決的方法是使用skip裝飾器,其中skip裝飾器主要有3種:unittest.skip(reason)unittest.skipif(condition, reason)unittest.skipUnless(condition, reason),即在滿足condition條件下跳過改用例,reason用於描述跳過的原因。

    ...
    @unittest.skipUnless(sys.platform.startwith('linux'), 'requires Linux')
    def test_devide(self):
        self.assertEqual(2, divide(6, 3))
        self.assertEqual(2, divide(5, 2))
           
    if __name__=='__main__':
        unittest.main()
    
  • 如何生成自動化測試報告
    unittest中模組生成的報告格式為txt,如果想生成html格式的報告,可以使用HtmlTestRunner模組,安裝後匯入該模組,使用HTMLTestRunner代替預設的TextTestRunner()執行測試用例即可。

    from HtmlTestRunner import HTMLTestRunner
    suite = unittest.TestSuite()
    suite.addTest(unittest.TestLoader().loadTestFromTestCase(TestMyfunc))
    sunner.run(suite)
    

參考資料

  1. https://www.jianshu.com/p/0b04cb0450ee
  2. https://www.jianshu.com/p/e0f74e54290d
  3. https://docs.python.org/3/library/unittest.html

相關文章