python3+selenium3+unittest+HTMLTestRunner完整163登录自动化测试实战

最近学习所写的是简单的163自动化登录测试。但是真正实际的项目不可能那么简单的,经过最近的学习和简单的实战项目的操作,整理了一下思路,大致框架结构为:浏览器,页面基础类的封装—》定位元素的封装—》自动截图,发送附件,获取最新报告,发送邮件的封装—》测试用例的封装—》最后整合完成自动化测试并获取生成报告与截取图片发送到指定邮箱,下面贴上代码。

框架结构:

python3+selenium3+unittest+HTMLTestRunner完整163登录自动化测试实战_第1张图片
python3+selenium3+unittest+HTMLTestRunner完整163登录自动化测试实战_第2张图片
BrowserApi.py(浏览器封装,使用隐式界面模式很大几率被退信)

from selenium import webdriver

def browser():
    """
    系统常量类
    """
    
    driver = webdriver.Chrome()
    
    """设置浏览器隐式启动,减少页面渲染元素所占的cpu内存"""
    # options = webdriver.ChromeOptions()     # 创建chrome参数对象
    # options.add_argument("headless")        # 启动无界面模式,消除页面渲染引发的cpu、内存过高
    # options.add_argument("blink-settings=imagesEnabled=false")      # 不加载图片
    # driver = webdriver.Chrome(options=options)  # 创建chrome无界面参数
    
    return driver   # 返回浏览器


if __name__ == '__main__':
    browser()

Page_contsant.py(页面基础类封装)

from time import sleep


class SysConstant():
    """
    系统常量页面基础类
    """

    """初始化"""
    def __init__(self,driver):
        self.driver = driver
        self.base_url = "https://mail.163.com"
        self.timeout = 10

    """私有方法"""
    def open_dir(self):
        self.driver.maximize_window()
        self.driver.get(self.base_url)
        sleep(2)

    """内嵌网页frame封装定位"""
    def frame_url(self):
        self.driver.switch_to_frame(0)

    """元素定位方法封装"""
    def find_element(self,*loc):  # 形参,参数数量不固定,加*
        return self.driver.find_element(*loc)

TestEnvironmental.py(环境准备)

import unittest
from BrowserApi import *


class StarEnd(unittest.TestCase):
    """
    系统常量类
    """

    """封装用例开始与结束环境"""
    def setUp(self) -> None:
        self.driver = browser()
        self.driver.implicitly_wait(10)
        self.driver.maximize_window()

    def tearDown(self) -> None:
        self.driver.delete_all_cookies()    # 清除cookie
        self.driver.close()
        self.driver.quit()

function.py(截图,获取报告,获取所截图,发送邮件封装)

import os
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication



def inser_img(driver,image):
    """
    封装自动截图保存的方法
    :param image:
    :param driver: 浏览器
    :param splice: 截图存放路径
    :return:
    """
    current_path = os.path.dirname(__file__)       # 获取当前目录下的路径
    # print(current_path)
    upper_level_path = os.path.dirname(current_path)     # 获取当前目录下的上级路径
    # print(upper_level_path)
    upper_level_path = str(upper_level_path)  # 转换成字符串
    upper_level_path = upper_level_path.replace("\\","/")    # 转换相对路径
    # print(upper_level_path)
    upper_level = upper_level_path.split("/Features")[0]
    # print(upper_level)
    # now = time.strftime("%Y-%m-%d %H-%M-%S")
    filename = upper_level + "/TestReport/screenshot/" + image
    driver.get_screenshot_as_file(filename)   # 进行截图


def latest_report(report_dir):
    """
    获取最新报告
    :param report_dir:  报告路径
    :return: file 最新的测试报告的绝对路径
    """
    lists = os.listdir(report_dir)  # 获取当前路径下的所有内容
    lists.sort(key=lambda fn:os.path.getatime(report_dir + "//"+fn))
    # print("new report is:" + lists[-1])
    file = os.path.join(report_dir,lists[-1])
    # print(file)
    return file


def get_image(img_list,keyword='.png'):
	"""
    :param img_list: 获取到的图片
    :param keyword:     扩展名
    :return: 返回获取到的图片
    """
    files = os.listdir("D:\\auto-selenium\\UIautomation\\TestReport\\screenshot")   # 获取此目录下文件
    path_img = "D:\\auto-selenium\\UIautomation\\TestReport\\screenshot\\"  # 路径文件
    keyword = keyword   # 扩展名
    filelist = []
    for file in files:
        if keyword in file:
            filelist.append(file)
    for filenm in filelist:
        filename = filenm
        part = MIMEApplication(open(path_img + filename, 'rb').read())
        part.add_header('Content-Disposition', 'attachment', filename=filename)
        img_list.attach(part)
    return img_list


def send_email(latest_report):
    """
    封装发送邮件的方法
    :param latest_report:   最新报告
    :return: file   报告路径
    """
    unfold = open(latest_report,"rb")
    mail_content = unfold.read()
    unfold.close()
    smtpserver = "smtp.163.com"     # 邮箱服务器
    username = ""  # 邮箱账号
    password = ""   # 邮箱授权码
    sender = ""    # 发送邮箱
    ricipients = ["多个邮箱为列表形式"]  # 收取邮箱账号
    subject = "python+selenium+unittest完整的163自动化测试实战"    # 报告主题
    msg = MIMEMultipart()
    att = MIMEText(mail_content,"html","utf-8")
    msg["Subject"] = Header(subject,"utf-8")
    msg["Form"] = sender
    msg["To"] = ",".join(ricipients) 
    msg.attach(att)
    msg = get_image(msg)
    smtp = smtplib.SMTP_SSL(smtpserver,465)         # SSL协议端口
    smtp.helo()
    smtp.ehlo()
    smtp.login(username,password)
    #print("Start send email...")
    smtp.sendmail(sender,ricipients,msg.as_string())
    #print("Send email end...")

element_pkg.py(元素封装)

from common.Page_constant import *
from selenium.webdriver.common.by import By


class LoginPage(SysConstant):
    """继承页面基础类,设计网站登陆模型并对相应元素进行封装"""


    """元素定位"""
    lbNormal_loc = (By.ID, "lbNormal")
    username_loc = (By.NAME, "email")
    password_loc = (By.NAME, "password")
    dologin_loc = (By.ID, "dologin")
    quit_loc = (By.LINK_TEXT,"退出")
    send_loc = (By.LINK_TEXT,"退出")
    login_failed_loc = (By.NAME,"email")

    def type_password_login(self):
        self.find_element(*self.lbNormal_loc).click()

    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_dologin(self):
        self.find_element(*self.dologin_loc).click()

    def type_quit(self):
        self.find_element(*self.quit_loc).click()

    def login_action(self,username,password):
        """登录步骤封装"""
        self.open_dir()
        self.type_password_login()
        self.frame_url()
        self.type_username(username)
        self.type_password(password)
        self.type_dologin()

    def login_success(self):
        """断言登录成功封装"""
        return self.find_element(*self.send_loc).text

    def login_failure(self):
        """断言登录失败封装"""
        return self.find_element(*self.login_failed_loc).text

testcase_login.py(测试用例,断言,截图)

import unittest
from Features import function
from common import TestEnvironmental
from Element_pkg import *
from time import sleep


class LoginTest(TestEnvironmental.StarEnd):
    #@unittest.skip("skip this case")
    def test_login1_success(self):
        """username and password is normal"""
        success = LoginPage(self.driver)  # 用例执行前调用准备环境
        success.login_action("正确账号","正确密码")
        sleep(2)
        self.assertEqual(success.login_success(),"退出")      # 断言
        function.inser_img(self.driver,"test_login1_success.png")  # 调用封装截图方法

    #@unittest.skip("skip this case")
    def test_login2_username_null(self):
        """username is null and password is correct"""
        username_null = LoginPage(self.driver)
        username_null.login_action("","正确密码")
        sleep(2)
        self.assertEqual(username_null.login_failure(),"")
        function.inser_img(self.driver,"test_login2_username_null.png")

    #@unittest.skip("skip this case")
    def test_login3_username_error(self):
        """username is error and password is correct"""
        username_error = LoginPage(self.driver)
        username_error.login_action("错误账号","错误密码")
        sleep(2)
        self.assertEqual(username_error.login_failure(),"")
        function.inser_img(self.driver,"test_login3_username_error.png")

    @unittest.skip("skip this case")
    def test_login4_password_null(self):
        """username is correct and password is null"""
        password_null = LoginPage(self.driver)
        password_null.login_action("正确账号","")
        sleep(2)
        self.assertEqual(password_null.login_failure(),"")
        function.inser_img(self.driver,"test_login4_password_null.png")

    @unittest.skip("skip this case")
    def test_login5_password_error(self):
        """username os correct and password is error"""
        password_error = LoginPage(self.driver)
        password_error.login_action("正确账号","错误密码")
        sleep(2)
        self.assertEqual(password_error.login_failure(),"")
        function.inser_img(self.driver,"test_login5_password_error.png")

    @unittest.skip("skip this case")
    def test_login6_userpass_null(self):
        """username and password is null"""
        userpass_null = LoginPage(self.driver)
        userpass_null.login_action("","")
        sleep(2)
        self.assertEqual(userpass_null.login_failure(),"")
        function.inser_img(self.driver,"test_login6_userpass_null.png")

    @unittest.skip("skip this case")
    def test_login7_userpass_error(self):
        """username and password is error"""
        userpass_error = LoginPage(self.driver)
        userpass_error.login_action("错误账号","错误密码")
        sleep(2)
        self.assertEqual(userpass_error.login_failure(),"")
        function.inser_img(self.driver,"test_login7_userpass_error.png")

if __name__ == '__main__':
    unittest.main()

RunTest.py(整合发送邮件)

from Features.function import *
import time
import os
import unittest
from HTMLTestRunner import HTMLTestRunner

report_dir = "D:\\auto-selenium\\UIautomation\\TestReport"    # 报告路径
test_dir = "D:\\auto-selenium\\UIautomation\\TEST-CASE"        # case路径
print("Start run test......")
run_case = unittest.defaultTestLoader.discover(test_dir,"testcase_login.py")    # 用例脚本获取
now = time.strftime("%Y-%m-%d %H-%M-%S")
report_name = report_dir + str(os.altsep) + now + "result.html"  # 报告存放路径与报告名称

print("Start write report.....")
with open(report_name,"wb")as f:
    runner = HTMLTestRunner(stream=f,title="Test Report",description="163mailbox login test")  # 报告主题与描述
    runner.run(run_case)    # 执行用例
    f.close()

print("find latest report.....")
newReport = latest_report(report_dir)   # 调用function中的获取最新报告的方法
print("send email report......")
send_email(newReport)   # 调用function中的发送邮件的方法
print("test end!")

唯一未解决的问题是发送到邮箱之后Detail不展示详细信息,修改HTMLTestRunner中的一些代码后展示是展示,但是样式丑到爆。希望有大神能指导一下!!!

python3+selenium3+unittest+HTMLTestRunner完整163登录自动化测试实战_第3张图片python3+selenium3+unittest+HTMLTestRunner完整163登录自动化测试实战_第4张图片

你可能感兴趣的:(python,selenium,unittest)