自动化进阶
一、python邮件发送
import smtplib # 发送邮件模块 from email.mime.text import MIMEText # 定义邮件内容 from email.header import Header # 定义邮件标题 # 发送邮箱服务器 smtpserver = "smtp.163.com" # 发送邮箱用户名密码 username = "n18604459833@163.com" password = "123456" # 发送和接收邮箱 sender = "n18604459833@163.com" receive = "li17802929732@126.com" #发送邮件主题和内容 subject = "Web Selenium 自动化测试报告" content = '<html><h1 style="color:red">我要自学网,自学成才</h1></html>' #HTML邮件正文 msg = MIMEText(content, 'html', 'utf-8') msg['Subject'] = Header(subject, 'utf-8') msg['From'] = 'n18604459833@163.com' msg['To'] = 'li17802929732@126.com' #SSL协议端口使用465 smtp = smtplib.SMTP_SSL(smtpserver, 465) #向服务器标适识用户身份 smtp.helo(smtpserver) #服务器返回结果确认 smtp.ehlo(smtpserver) #登录邮箱服务器用户名和密码 smtp.login(username, password) print("Start send Email...") smtp.sendmail(sender, receive, msg.as_string()) smtp.quit() print("Send Email end")
二、邮件同时发送给多人
import smtplib # 发送邮件模块 from email.mime.text import MIMEText # 定义邮件内容 from email.header import Header # 定义邮件标题 # 发送邮箱服务器 smtpserver = "smtp.163.com" # 发送邮箱用户名密码 username = '' password = '' # 发送和接收邮箱 sender = '' receives = ['', ''] # 发送邮件主题和内容 subject = "Web Selenium 自动化测试报告" content = '<html><h1 style="color:red">我要自学网,自学成才</h1></html>' # HTML邮件正文 msg = MIMEText(content, 'html', 'utf-8') msg['Subject'] = Header(subject, 'utf-8') msg['From'] = sender msg['To'] = '.'.join(receives) # SSL协议端口使用465 smtp = smtplib.SMTP_SSL(smtpserver, 465) # 向服务器标适识用户身份 smtp.helo(smtpserver) # 服务器返回结果确认 smtp.ehlo(smtpserver) # 登录邮箱服务器用户名和密码 smtp.login(username, password) print("Start send Email...") smtp.sendmail(sender, receives, msg.as_string()) smtp.quit() print("Send Email end")
三、发送带附件的邮件
''' 发送logo.png图片文件到指定到邮箱 ''' import smtplib # 发送邮件模块 from email.mime.text import MIMEText # 定义邮件内容 from email.mime.multipart import MIMEMultipart # 用于传送附件 # 发送邮箱服务器 smtpserver = "smtp.163.com" # 发送邮箱用户名密码 username = '' password = '' # 发送和接收邮箱 sender = '' receives = ['', ''] # 发送邮件主题和内容 subject = "Web Selenium 自动化测试报告" content = '<html><h1 style="color:red">我要自学网,自学成才</h1></html>' # 构造附件内容 send_file = open(r'E:\python\logo.png', 'rb').read() att = MIMEText(send_file, 'base64', 'utf-8') att['Content-Type'] = 'application/octet-stream' att['Content-Disposition'] = 'attachment;filename="logo.png"' # 构建发送和接收信息 msgRoot = MIMEMultipart() msgRoot.attach(MIMEText(content, 'html', 'utf-8')) msgRoot['Subject'] = subject msgRoot['From'] = sender msgRoot['To'] = ','.join(receives) msgRoot.attach(att) # SSL协议端口使用465 smtp = smtplib.SMTP_SSL(smtpserver, 465) # 向服务器标适识用户身份 smtp.helo(smtpserver) # 服务器返回结果确认 smtp.ehlo(smtpserver) # 登录邮箱服务器用户名和密码 smtp.login(username, password) print("Start send Email...") smtp.sendmail(sender, receives, msgRoot.as_string()) smtp.quit() print("Send Email end")
四、整合测试报告发送
1、获取某目录下最新的测试报告
''' 获取某目录下最新的测试报告 ''' import os # 用于访问操作系统功能的模块 # 报告存放位置 report_dir = './test_report' lists = os.listdir(report_dir) # 方法用于返回指定的文件夹包含的文件或文件夹的名字列表 print(lists) # 按时间顺序对该目录文件夹下面的文件进行排序 lists.sort(key=lambda fn: os.path.getatime(report_dir + '\\' + fn)) print("the latest report is " + lists[-1]) # 输出最新报告的文件 file = os.path.join(report_dir, lists[-1]) print(file)
2、整合测试报告发送
import unittest from BSTestRunner import BSTestRunner import time import smtplib # 发送邮件模块 from email.mime.text import MIMEText # 定义邮件内容 from email.header import Header # 定义邮件标题 import os def send_mail(latest_report): f = open(latest_report, 'rb') mail_content = f.read() f.close() # 发送邮箱服务器 smtpserver = "smtp.163.com" # 发送邮箱用户名密码 username = '' password = '' # 发送和接收邮箱 sender = '' receives = ['', ''] # 发送邮件主题和内容 subject = "Web Selenium 自动化测试报告" # content = '<html><h1 style="color:red">我要自学网,自学成才</h1></html>' # HTML邮件正文 msg = MIMEText(mail_content, 'html', 'utf-8') msg['Subject'] = Header(subject, 'utf-8') msg['From'] = sender msg['To'] = '.'.join(receives) # SSL协议端口使用465 smtp = smtplib.SMTP_SSL(smtpserver, 465) # 向服务器标适识用户身份 smtp.helo(smtpserver) # 服务器返回结果确认 smtp.ehlo(smtpserver) # 登录邮箱服务器用户名和密码 smtp.login(username, password) print("Start send Email...") smtp.sendmail(sender, receives, msg.as_string()) smtp.quit() print("Send Email end") def latest_report(report_dir): lists = os.listdir(report_dir) # 方法用于返回指定的文件夹包含的文件或文件夹的名字列表 print(lists) # 按时间顺序对该目录文件夹下面的文件进行排序 lists.sort(key=lambda fn: os.path.getatime(report_dir + '\\' + fn)) print("the latest report is " + lists[-1]) # 输出最新报告的文件 file = os.path.join(report_dir, lists[-1]) print(file) return file if __name__ == '__main__': # 存放报告的文件夹 report_dir = './test_report' # 定义测试用例路径 test_dir = './test_case' discovery = unittest.defaultTestLoader.discover(test_dir, pattern="test*.py") # 报告命名时间格式化 now = time.strftime("%Y-%m-%d %H_%M_%S") # 报告文件完整路径 report_name = report_dir + '/' + now + 'result.html' # 打开文件在报告文件写入测试结果 with open(report_name, "wb") as f: runner = BSTestRunner(stream=f, title="Test Report", description="Test Case Result") runner.run(discovery) latest_report=latest_report(report_dir) send_mail(latest_report)
五、补充知识点
1、By方式定位元素
from selenium import webdriver from selenium.webdriver.common.by import By from time import sleep driver = webdriver.Firefox() driver.get("http://www.baidu.com") driver.implicitly_wait(5) driver.find_element(By.ID, "kw").clear() driver.find_element(By.NAME, 'wd').send_keys("selenium") driver.find_element(By.CLASS_NAME, 's_ipt').send_keys("自学网") driver.find_element(By.CSS_SELECTOR, '#kw').send_keys("python") sleep(3) driver.find_element(By.ID, 'su').click() sleep(2) driver.quit()
2、方法参数的个数
def fun_args1(args): print("args is %s" % args) def fun_args2(args1, args2): print("args1 is %s args2 is %s" % (args1, args2)) # 可变参数 def fun_var_args(*args): for value in args: print("args : %s" % value) print("================") if __name__ == '__main__': fun_args1('zxw') fun_args2('test', 'jiayou') print("-------------------") fun_var_args() fun_var_args("zxw") fun_var_args('zxw', 'test', 'jiayou')
六、自动化测试设计模式Page Object
Page Object是Selenium自动化测试项目开发实践的最佳设计模式之一,通过对界面元素和功能模块的封装减少冗余代码,同时在后期维护中,若元素定位或功能模块发生变化,只需要调整页面或功能模块封装的代码,提高测试用例的可维护性。
base_page.py
from time import sleep '''页面基础类''' class Page(): # 初始化 def __init__(self, driver): self.driver = driver self.base_url = 'http://localhost' self.timeout = 10 # 打开不同的子页面 def _open(self, url): url_ = self.base_url + url print("Test page is %s" % url_) self.driver.maximize_window() self.driver.get(url_) sleep(2) assert self.driver.current_url == url_, 'Did not land on %s' % url_ def open(self): self._open(self.url) # 元素定位方法封装 def find_element(self, *loc): return self.driver.find_element(*loc)
login_page.py
from base_page import * from selenium.webdriver.common.by import By class LoginPage(Page): '''首页登录页面''' url = '/' # 定位器 username_loc = (By.NAME, 'username') password_loc = (By.NAME, 'password') submit_loc = (By.NAME, 'Submit') # 用户名输入框元素 def type_username(self, username): self.find_element(*self.username_loc).clear() self.find_element(*self.username_loc).send_keys(username) # 密码输入框元素 def type_password(self, password): self.find_element(*self.password_loc).clear() self.find_element(*self.password_loc).send_keys(password) # 登录按钮元素 def type_submit(self): self.find_element(*self.submit_loc).click() # 登录功能模块封装 def test_user_login(driver, username, password): '''测试用户名密码是否可以登录''' login_page = LoginPage(driver) login_page.open() login_page.type_username(username) login_page.type_password(password) login_page.type_submit()
test_login.py
from login_page import * from selenium import webdriver driver = webdriver.Firefox() username = 'zxw' password = '123456' if __name__ == '__main__': test_user_login(driver, username, password) sleep(2) driver.quit()
七、自动化测试综合实战
项目背景:新闻子页面进行登录测试
功能实现:
自动运行用例
自动生成测试报告
自动断言与截图
自动将最新测试报告发送到指定邮箱
PageObject+Unittest
代码组织结构如下:
driver.py
from selenium import webdriver def browser(): driver = webdriver.Firefox() # driver = webdriver.Chrome() # driver = webdriver.Ie() driver = webdriver.IeOptions() # driver.get("http://www.baidu.com") return driver
function.py
from selenium import webdriver import os import smtplib # 发送邮件模块 from email.mime.text import MIMEText # 定义邮件内容 from email.header import Header # 定义邮件标题 def insert_img(driver, filename): func_path = os.path.dirname(__file__) print(func_path) base_dir = os.path.dirname(func_path) print(base_dir) base_dir = str(base_dir) # 绝对路径转换为相对路径 dir = base_dir.replace('\\', '/') print(dir) base = dir.split('/website') print(base) filepath = base + '/website/test_report/screenshot/' + filename driver.get_screenshot_as_file(filepath) def send_mail(latest_report): f = open(latest_report, 'rb') mail_content = f.read() f.close() # 发送邮箱服务器 smtpserver = "smtp.163.com" # 发送邮箱用户名密码 username = '' password = '' # 发送和接收邮箱 sender = '' receives = ['', ''] # 发送邮件主题和内容 subject = "Web Selenium 自动化测试报告" # content = '<html><h1 style="color:red">我要自学网,自学成才</h1></html>' # HTML邮件正文 msg = MIMEText(mail_content, 'html', 'utf-8') msg['Subject'] = Header(subject, 'utf-8') msg['From'] = sender msg['To'] = '.'.join(receives) # SSL协议端口使用465 smtp = smtplib.SMTP_SSL(smtpserver, 465) # 向服务器标适识用户身份 smtp.helo(smtpserver) # 服务器返回结果确认 smtp.ehlo(smtpserver) # 登录邮箱服务器用户名和密码 smtp.login(username, password) print("Start send Email...") smtp.sendmail(sender, receives, msg.as_string()) smtp.quit() print("Send Email end") def latest_report(report_dir): lists = os.listdir(report_dir) # 方法用于返回指定的文件夹包含的文件或文件夹的名字列表 print(lists) # 按时间顺序对该目录文件夹下面的文件进行排序 lists.sort(key=lambda fn: os.path.getatime(report_dir + '\\' + fn)) print("the latest report is " + lists[-1]) # 输出最新报告的文件 file = os.path.join(report_dir, lists[-1]) print(file) return file if __name__ == '__main__': driver = webdriver.Firefox() driver.get("http://www.sogou.com") insert_img(driver, 'sougou.jpg') driver.quit()
myunit.py
import unittest from driver import * class StartEnd(unittest.TestCase): def setUp(self): self.driver = browser() self.driver.implicitly_wait(10) self.driver.maximize_window() def tearDown(self): self.driver.quit()
base_page.py
from time import sleep '''页面基础类''' class Page(): # 初始化 def __init__(self, driver): self.driver = driver self.base_url = 'http://localhost' self.timeout = 10 # 打开不同的子页面 def _open(self, url): url_ = self.base_url + url print("Test page is %s" % url_) self.driver.maximize_window() self.driver.get(url_) sleep(2) assert self.driver.current_url == url_, 'Did not land on %s' % url_ def open(self): self._open(self.url) # 元素定位方法封装 def find_element(self, *loc): return self.driver.find_element(*loc)
login_page.py
from base_page import * from selenium.webdriver.common.by import By class LoginPage(Page): '''首页登录页面''' url = '/news/' # 定位器 username_loc = (By.NAME, 'username') password_loc = (By.NAME, 'password') submit_loc = (By.NAME, 'Submit') # 用户名输入框元素 def type_username(self, username): self.find_element(*self.username_loc).clear() self.find_element(*self.username_loc).send_keys(username) # 密码输入框元素 def type_password(self, password): self.find_element(*self.password_loc).clear() self.find_element(*self.password_loc).send_keys(password) # 登录按钮元素 def type_submit(self): self.find_element(*self.submit_loc).click() # 登录功能模块封装 def login_action(self, username, password): self.open() self.type_username(username) self.type_password(password) self.type_submit() # 断言元素定位 login_pass_loc = (By.LINK_TEXT, '我的空间') login_fail_loc = (By.NAME, 'username') def type_login_pass_hint(self): return self.find_element(*self.login_pass_loc).text def type_login_fail_hint(self): return self.find_element(*self.login_fail_loc).text
test_login.py
import unittest from model import function, myunit from page_object.login_page import * from time import sleep ''' unittest组织测试用例 1、用户名密码正确点击登录 2、用户名正确,密码错误点击登录 3、用户名和密码为空点击登录 ''' class LoginTest(myunit.StartEnd): @unittest.skip("skip normal login") def test_login1_normal(self): '''username and password is normal''' print("test_login_normal is start test...") po = LoginPage(self.driver) po.login_action('zxw', '123456') sleep(2) self.assertEqual(po.type_login_pass_hint(), "我的空间") function.insert_img(self.driver, "zxw_login1_normal.jpg") print("test_login1_normal test end") def test_login2_password_error(self): '''username is ok,password is error''' print("test_login2_password_error is start test...") po = LoginPage(self.driver) po.login_action('zxw', '666') sleep(2) self.assertEqual(po.type_login_fail_hint(), '') function.insert_img(self.driver, 'test_login2_password_error.jpg') def test_login3_empty(self): '''username and password is empty''' print('test_login3_empty is start test...') po = LoginPage(self.driver) po.login_action('', '') sleep(2) self.assertEqual(po.type_login_fail_hint(), '') function.insert_img(self.driver, 'test_login3_empty.jpg') print("test_login3_empty test end") if __name__ == '__main__': unittest.main()
run_test.py
import unittest from function import * from BSTestRunner import BSTestRunner import time report_dir = './test_report' test_dir = './test_case' print("start run test case") discover = unittest.defaultTestLoader.discover(test_dir, pattern="test_login.py") now = time.strftime('%Y-%m-%d %H_%M_%S') report_name = report_dir + '/' + now + 'result.html' print('start write report...') with open(report_name, 'wb') as f: runner = BSTestRunner(stream=f, title='Test Report', description='localhost login test') runner.run(discover) print('find latest report') latest_report = latest_report(report_dir) print("send email report...") send_mail(latest_report) print("Test end")