一、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:pythonlogo.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")