測試思路:單個測試集、單個測試匯成多個測試集、運行測試集、生成測試報告、發送至郵箱。
第一步:建立單個測試集,以cnblog登錄為例。
測試用例:
cnblog的登錄測試,簡單分下面幾種情況:
(1)用戶名、密碼正確
(2)用戶名正確、密碼不正確
(3)用戶名正確、密碼為空
(4)用戶名錯誤、密碼正確
(5)用戶名為空、密碼正確
頭文件:
import unittest
from selenium import webdriver
import time
1 #coding:utf-8 2 import unittest 3 from selenium import webdriver 4 import time 5 6 class Test(unittest.TestCase): 7 @classmethod 8 def setUpClass(cls): 9 print("開始測試") 10 @classmethod 11 def tearDownClass(cls): 12 print("結束測試") 13 def setUp(self): 14 print("開始單個測試用例") 15 def tearDown(self): 16 print("結束單個測試用例") 17 # 定義登錄方法 18 def login(self, username, password): 19 self.dr = webdriver.Firefox() 20 self.dr.get('https://passport.cnblogs.com/user/signin') # cnblog登錄頁面 21 self.dr.find_element_by_id('input1').send_keys(username) 22 self.dr.find_element_by_id('input2').send_keys(password) 23 self.dr.find_element_by_id('signin').click() 24 25 def test_login_success(self): 26 '''用戶名、密碼正確''' 27 self.login('木xxxx', 'sxxxxx') # 正確用戶名和密碼 28 time.sleep(10) #這里等待10秒的原因是由於cnblog存在驗證機制,不想在驗證碼上花過多時間寫代碼,博主在等待時間手動處理。 29 link = self.dr.find_element_by_id('lnk_current_user') 30 self.assertTrue('木秀於林' in link.text) # 用assertTrue(x)方法來斷言 bool(x) is True 登錄成功后用戶昵稱在lnk_current_user里 31 32 def test_login_pwd_error(self): 33 '''用戶名正確、密碼不正確''' 34 self.login('木秀xxx', 'pwerror') # 正確用戶名,錯誤密碼 35 time.sleep(10) #這里等待10秒的原因是由於cnblog存在驗證機制,不想在驗證碼上花過多時間寫代碼,博主在等待時間手動處理。 36 error_message = self.dr.find_element_by_id('tip_btn').text 37 self.assertIn('用戶名或密碼錯誤', error_message) # 用assertIn(a,b)方法來斷言 a in b '用戶名或密碼錯誤'在error_message里 38 self.dr.get_screenshot_as_file("F:\\login_pwd_error.jpg") 39 40 def test_login_pwd_null(self): 41 '''用戶名正確、密碼為空''' 42 self.login('木秀xxx', '') # 密碼為空 43 error_message = self.dr.find_element_by_id('tip_input2').text 44 self.assertEqual(error_message, '請輸入密碼') # 用assertEqual(a,b)方法來斷言 a == b 請輸入密碼等於error_message 45 self.dr.get_screenshot_as_file("F:\\login_pwd_null.jpg") 46 47 def test_login_user_error(self): 48 '''用戶名錯誤、密碼正確''' 49 self.login('usernameerror', 'sxxxxxxx') # 密碼正確,用戶名錯誤 50 time.sleep(10) #這里等待10秒的原因是由於cnblog存在驗證機制,不想在驗證碼上花過多時間寫代碼,博主在等待時間手動處理。 51 error_message = self.dr.find_element_by_id('tip_btn').text 52 self.assertIn('用戶名或密碼錯誤', error_message) # 用assertIn(a,b)方法來斷言 a in b 53 self.dr.get_screenshot_as_file("F:\\login_user_error.jpg") 54 55 def test_login_user_null(self): 56 '''用戶名為空、密碼正確''' 57 self.login('', 'sunsea1.') # 用戶名為空,密碼正確 58 error_message = self.dr.find_element_by_id('tip_input1').text 59 self.assertEqual(error_message, '請輸入登錄用戶名') # 用assertEqual(a,b)方法來斷言 a == b 60 self.dr.get_screenshot_as_file("F:\login_user_null.jpg") 61 62 if __name__=="__main__": 63 unittest.main()
第二步,建立多個測試用例集
test02.py為第一步建立的單個測試集
test01.py/test03.py/test04.py 為示例測試集
test01.py代碼如下:
1 #coding:utf-8 2 import unittest 3 import time 4 5 class Test(unittest.TestCase): 6 @classmethod 7 def setUpClass(cls): 8 print("開始測試") 9 def tearDown(self): 10 print("測試結束") 11 def test01(self): 12 '''測試0201''' 13 print("執行測試用例1") 14 def test02(self): 15 '''測試0202''' 16 print("執行測試用例02") 17 18 if __name__=="__main__": 19 unittest.main()
測試集結構圖如下
第三步 將所有多個測試集聯合起來,一起執行並生成測試報告html文檔
在logintest文檔下方建立run_all_case.py
頭文件:
import unittest
import HTMLTestRunner
from send_email import main2 #這是自己寫的發送郵件函數
1 #coding:utf-8 2 import unittest 3 import os 4 import HTMLTestRunner 5 from send_email import main2 6 #待執行用例的目錄 7 def allcase(): 8 case_dir=r"F:\logintest\case" 9 #case_path=os.path.join(os.getcwd(),"case") 10 testcase=unittest.TestSuite() 11 discover=unittest.defaultTestLoader.discover(case_dir, 12 pattern='test*.py', 13 top_level_dir=None) 14 #discover方法篩選出來的用例,循環添加到測試套件中 15 #print(discover) 16 for test_suite in discover: 17 for test_case in test_suite: 18 #添加用例到testcase 19 print(test_case) 20 testcase.addTest(test_case) 21 return testcase 22 23 24 if __name__=="__main__": 25 # runner=unittest.TextTestRunner() 26 # runner.run(allcase()) 27 report_path="F:\\result.html" 28 fp=open(report_path,"wb") 29 runner=HTMLTestRunner.HTMLTestRunner(stream=fp, 30 title="自動化測試unittest測試框架報告", 31 description="用例執行情況:") 32 33 runner.run(allcase()) 34 fp.close() 35 #main2() #from send_email import main2 發送郵件!
第四步:發送郵件,send_email.py
1 import smtplib 2 import os.path as pth 3 import time 4 from email.mime.text import MIMEText 5 from email.header import Header 6 7 def sendEmail(content, title, from_name, from_address, to_address, serverport, serverip, username, password): 8 msg = MIMEText(content, _subtype='html', _charset='utf-8') 9 msg['Subject'] = Header(title, 'utf-8') 10 # 這里的to_address只用於顯示,必須是一個string 11 msg['To'] = ','.join(to_address) 12 msg['From'] = from_name 13 try: 14 s = smtplib.SMTP_SSL(serverip, serverport) 15 s.login(username, password) 16 # 這里的to_address是真正需要發送的到的mail郵箱地址需要的是一個list 17 s.sendmail(from_address, to_address, msg.as_string()) 18 print('%s----發送郵件成功' % time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) 19 except Exception as err: 20 print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) 21 print(err) 22 #HEFEN_D = pth.abspath(pth.dirname(__file__)) 23 24 def main2(): 25 TO = ['864xxxxxxxxx2@qq.com'] 26 config = { 27 "from": "69xxxxxxxx2@qq.com", 28 "from_name": '自動化測試unittest測試框架報告:', 29 "to": TO, 30 "serverip": "smtp.qq.com", 31 "serverport": "465", 32 "username": "694xxxxxxx@qq.com", 33 "password": "xxxxxxxxxxxx" # QQ郵箱的SMTP授權碼 34 } 35 36 title = "自動化測試unittest測試框架報告" 37 f = open("F://result.html", 'rb') 38 mail_body = f.read() 39 f.close() 40 sendEmail(mail_body, title, config['from_name'], config['from'], config['to'], config['serverport'], config['serverip'], 41 config['username'], config['password']) 42 43 #main2()
最后,郵件效果圖和html報告如下:
咦!失敗了一個。查看截圖發現,博客園當用戶名錯誤時,提示的是:用戶名不存在,測試用例的預期值是:用戶名或密碼錯誤
分析:
用戶名或密碼錯誤時都不能直接提示用戶名錯誤、密碼錯誤。要含蓄的提示用戶名或密碼錯誤,cnblog當用戶名錯誤時提示:用戶名不存在,密碼錯誤時:提示 用戶名或密碼錯誤,當提示用戶名或密碼錯誤時,
也就是用戶名實際是正確的,再單方面通過破解密碼即可破解賬戶
提示算是一個安全漏洞,不寫了,博主得給cnblog提bug去了