四. 引入unittest單元測試框架


1.   安裝 SeleniumIDE(firefox

(1)下載地址:https://addons.mozilla.org/en-US/firefox/addon/selenium-ide/

(2) 教程:

(3) 可以直接將腳本到unittest

 

2.  unittest單元測試框架:

  2.1 定義

1)  單元測試負責對最小的軟件設計單元(模塊)進行驗證,它使用軟件設計文檔中對模塊的描述作為指南,對重要的程序分支進行測試以發現模塊中的錯誤。

2) unittest 框架(又名 PyUnit 框架)為 python 語言的單元測試框架,從 Python 2.1 及其以后的版本都將 PyUnit 作為一個標准模塊放入 python 開發包中。

  2.2 unittest模塊的各個屬性說明

  1. unittest的屬性很多,其中:

  • unittest.TestCase:TestCase類,所有測試用例類繼承的基本類
def class1(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類的屬性中:

  • 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類的屬性中:(組織用例時需要用到)

  • addTest(): addTest()方法是將測試用例添加到測試套件中,如下方,是將test_baidu模塊下的BaiduTest類下的test_baidu測試用例添加到測試套件。
suite = unittest.TestSuite()
suite.addTest(test_baidu.BaiduTest('test_baidu')) 

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

  • run(): run()方法是運行測試套件的測試用例,入參為suite測試套件。
runner = unittest.TextTestRunner()
runner.run(suite)

 

 

3.  生成HTMLTextRunner報告

1)  下載地址

http://tungwaiyip.info/software/HTMLTestRunner.html 

2)  保存地址

C:\Users\lesleysbw\AppData\Local\Programs\Python\Python35\Lib

3)  這是針對python2.7,針對python30需要修改

  • 問題一:No module named StringIO,解決方法:
    • 第94行,將import StringIO修改成import io 
    • 第539行,將self.outputBuffer = StringIO.StringIO()修改成self.outputBuffer= io.StringIO() 
  • 問題二:AttributeError: 'dict' object has no attribute 'has_key',解決方法:
    • 第642行,將if not rmap.has_key(cls):修改成if not cls in rmap: 
  • 問題三:'str' object has no attribute 'decode',解決方法:python3 里面對字符的操作中,decode已經拿掉了。
    • 第766行,將uo = o.decode(‘latin-1‘)修改成uo = e 
    • 第775行,將ue = e.decode(‘latin-1‘)修改成ue = e 
  • 問題四 :TypeError: can't concat bytes to str
    • 第778行,將output = saxutils.escape(uo+ue),修改成output = saxutils.escape(str(uo)+str(ue)),
  • 問題五:TypeError: unsupported operand type(s) for >>:

'builtin_function_or_method' and 'RPCProxy',解決方法:python2 和 python3 的print是很不同的,那么在3中,print 后面是不會跟>> 這樣的

    • 第631行,將print >> sys.stderr, ‘\nTime Elapsed: %s‘ %(self.stopTime-self.startTime)修改成print(sys.stderr, ‘\nTimeElapsed: %s‘ % (self.stopTime-self.startTime)) 

將上述幾處改動,保存成功后,再將HTMLTestRunner.py放到C:\Python34\Lib目錄中,檢驗是否加載成功,在Python IDLE 中輸入 import HTMLTestRunner ,若無報錯,那么加載成功。

 

4)  文件調用語句更改

python3 里面打開文件使用 open,不要再去用file了。即 fp = file(filename,'wb')替換成 fp = open(filename,'wb');關閉該文件可用fp.close()

 

5) HTMLTestRunner.py 的使用備注:

  • 問題: 執行測試用例的過程中,不會打印任何東西
  • 解決思路: 每次執行一個測試用例時,就打印該測試用例的名稱。
  • 解決方案: 找到536行的 “def startTest(self, test):” 函數,在函數第一行加入代碼“print("Start Test:",str(test))”。
  • 這樣每次執行一個測試用例,就可以從console看到該測試用例的名字被打印出來。
  • 其他問題(無法生成HTTPTextRunner報告):

http://blog.csdn.net/xie_0723/article/details/50825310

 

4.  結構:

  • 編寫測試用例(eg:baidu.py),放在test_case目錄下面
  • 測試用例獨立運行后,更名為start_baidu.py,在all_test.py中,引入discover方法

(1)百度搜索測試用例Test Case:

 1 # coding=utf-8
 2 '''
 3 Created on 2016-7-22
 4 @author: Jennifer
 5 Project:登錄百度測試用例
 6 '''
 7 from selenium import webdriver
 8 import unittest, time
 9 
10 class BaiduTest(unittest.TestCase):
11     def setUp(self):
12         self.driver = webdriver.Firefox()
13         self.driver.implicitly_wait(30) #隱性等待時間為30秒
14         self.base_url = "https://www.baidu.com"
15     
16     def test_baidu(self):
17         driver = self.driver
18         driver.get(self.base_url + "/")
19         driver.find_element_by_id("kw").clear()
20         driver.find_element_by_id("kw").send_keys("unittest")
21         driver.find_element_by_id("su").click()
22         time.sleep(3)
23         title=driver.title
24         self.assertEqual(title, u"unittest_百度搜索") 
25 
26     def tearDown(self):
27         self.driver.quit()
28 
29 if __name__ == "__main__":
30     unittest.main()

 

(2)有道翻譯測試用例Test Case

 1 # coding=utf-8
 2 '''
 3 Created on 2016-7-22
 4 @author: Jennifer
 5 Project:使用有道翻譯測試用例
 6 '''
 7 from selenium import webdriver
 8 import unittest, time
 9 
10 class YoudaoTest(unittest.TestCase):
11     def setUp(self):
12         self.driver = webdriver.Firefox()
13         self.driver.implicitly_wait(30) #隱性等待時間為30秒
14         self.base_url = "http://www.youdao.com"
15     
16     def test_youdao(self):
17         driver = self.driver
18         driver.get(self.base_url + "/")
19         driver.find_element_by_id("translateContent").clear()
20         driver.find_element_by_id("translateContent").send_keys(u"你好")
21         driver.find_element_by_id("translateContent").submit()
22         time.sleep(3)
23         page_source=driver.page_source
24         self.assertIn( "hello",page_source) 
25 
26     def tearDown(self):
27         self.driver.quit()
28 
29 if __name__ == "__main__":
30     unittest.main()

 

(3)通過discover()執行所有的測試用例,並發送測試報告

 1 # coding = utf-8
 2 import unittest
 3 import HTMLTestRunner
 4 import os, time
 5 
 6 list = "D:\\selenium_python\\test_case"
 7 def createsuit():
 8     testunit = unittest.TestSuite()
 9 
10     # discover()方法定義
11     discover = unittest.defaultTestLoader.discover(
12         list,
13         pattern='test_*.py',
14         top_level_dir=None
15     )
16     # 將discover()篩選出來的用例,循環添加到測試套件中
17     for test_suite in discover:
18         for test_case in test_suite:
19             testunit.addTest(test_case)
20             print(testunit)
21     return testunit
22 alltestnames = createsuit()
23 
24 # 創建測試報告文件
25 now = time.strftime('%Y-%m-%d_%H_M_S', time.localtime(time.time()))
26 filename = "D:\\selenium_python\\report\\" + now + 'report.html'
27 fp = open(filename,'wb')
28 
29 runner = HTMLTestRunner.HTMLTestRunner(
30     stream=fp,
31     title='測試報告',
32     description='用例執行情況:'
33 )
34 runner.run(alltestnames)

 


免責聲明!

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



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