自动化进阶
一、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")