前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Selenium 自动化综合实践

Selenium 自动化综合实践

作者头像
清风穆云
发布2021-08-09 11:16:16
3610
发布2021-08-09 11:16:16
举报
文章被收录于专栏:QA一隅

项目背景

http://localhost/news/ 新闻子页面登录

功能实现

  • 自动运行用例
  • 自动生成测试报告
  • 自动断言与截图
  • 自动将最新测试报告发送到指定邮箱
  • PageObject+Unittest

项目架构

浏览器driver定义

driver.py

代码语言:javascript
复制
from selenium import webdriver

#启动浏览器驱动
def browser():
    driver = webdriver.Firefox()
    # driver = webdriver.Chrome()
    # driver = webdriver.Ie()
    # driver=webdriver.PhantomJS()

    # driver.get("http://www.baidu.com")

    return driver

#调试运行
if __name__ == '__main__':
    dr = browser()
用例运行前后的环境准备工作

myunit.py

代码语言:javascript
复制
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()
工具方法模块

主要封装一些公共的方法如:截图,查找最新报告、邮件发送 function.py

代码语言:javascript
复制
from  selenium import webdriver
import os
import smtplib
from email.mime.text import MIMEText
from email.header import Header

#截图方法
def inser_img(driver,filename):

    #获取当前模块所在路径
    func_path=os.path.dirname(__file__)
    # print("func_path is %s" %func_path)

    #获取test_case目录
    base_dir=os.path.dirname(func_path)
    # print("base_dir is %s" %base_dir)

    #将路径转化为字符串
    base_dir=str(base_dir)

    #对路径的字符串进行替换
    base_dir=base_dir.replace('\\','/')
    # print(base_dir)

    #获取项目文件的根目录路径
    base=base_dir.split('/Website')[0]
    # print(base)

    #指定截图存放路径
    filepath=base+'/Website/test_report/screenshot/'+filename
    # print(filepath)
    driver.get_screenshot_as_file(filepath)

#查找最新的测试报告
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

#将测试报告发送到邮件
def send_mail(latest_report):
    f=open(latest_report,'rb')
    mail_content=f.read()
    f.close()

    smtpserver = 'smtp.163.com'

    user = 'yuexiaolu2015@163.com'
    password = '...'

    sender = 'yuexiaolu2015@163.com'
    receives = ['yuexiaolu2015@126.com', 'yuexiaolu2015@sina.com']

    subject = 'Web Selenium 自动化测试报告'

    msg = MIMEText(mail_content, 'html', 'utf-8')
    msg['Subject'] = Header(subject, 'utf-8')
    msg['From'] = sender
    msg['To'] = ','.join(receives)

    smtp = smtplib.SMTP_SSL(smtpserver, 465)
    smtp.helo(smtpserver)
    smtp.ehlo(smtpserver)
    smtp.login(user, password)

    print("Start send email...")
    smtp.sendmail(sender, receives, msg.as_string())
    smtp.quit()
    print("Send email end!")


if __name__ == '__main__':
    driver=webdriver.Firefox()
    driver.get("http://www.sogou.com")
    inser_img(driver,"sogou.png")
    driver.quit()
Pageobject页面对象封装

BasePage.py —— 基础页面类

代码语言:javascript
复制
from  time import sleep

class Page():

    def __init__(self,driver):
        self.driver=driver
        self.base_url="http://localhost"
        self.timeout=20

    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 ont land on %s' % url_

    def open(self):
        self._open(self.url)

    def find_element(self,*loc):
        return self.driver.find_element(*loc)

LoginPage.py —— 新闻登录页面

代码语言:javascript
复制
from  PageBase import *
from selenium import webdriver
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()


    LoginPass_loc = (By.LINK_TEXT, '我的空间')
    loginFail_loc = (By.NAME, 'username')

    def type_loginPass_hint(self):
        return self.find_element(*self.LoginPass_loc).text


    def type_loginFail_hint(self):
        return self.find_element(*self.loginFail_loc).text

test_login.py ——unittest组织测试用例

  • 用户名密码正确点击登录
  • 用户名正确,密码错误点击登录
  • 用户名和密码为空点击登录
代码语言:javascript
复制
import unittest
from model import function,myunit
from page_object.LoginPage import *
from time import sleep

class LoinTest(myunit.StartEnd):
    # @unittest.skip('skip this case')
    def test_login1_normal(self):
        '''username password is normal'''
        print("test_login1_normal is start run...")
        po=LoginPage(self.driver)
        po.Login_action('51zxw',123456)
        sleep(3)

        #断言与截屏
        self.assertEqual(po.type_loginPass_hint(),'我的空间')
        function.inser_img(self.driver,"51zxw_login1_normal.jpg")
        print("test_login1_normal is test end!")


    def test_login2_PasswdError(self):
        '''username is ok,passwd is error!'''
        print("test_login2_PasswdError is start run...")
        po=LoginPage(self.driver)
        po.Login_action("51zxw",12342)
        sleep(2)

        self.assertEqual(po.type_loginFail_hint(),'')
        function.inser_img(self.driver,"51zxw_login2_fail.jpg")
        print("test_login2_PasswdError is test end!")
    #
    # @unittest.skip
    def test_login3_empty(self):
        '''username password is empty'''
        print("test_login3_empty is start run...")
        po=LoginPage(self.driver)
        po.Login_action('','')
        sleep(2)

        #断言与截屏
        self.assertEqual(po.type_loginFail_hint(),'')
        function.inser_img(self.driver,"51zxw_login3_empty.jpg")
        print("test_login3_empty is test end!")

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

run_test.py 执行测试用例

代码语言:javascript
复制
mport unittest
from  function import *
from BSTestRunner import BSTestRunner
import time

report_dir = './test_report'
test_dir = './test_case'

print("start run testcase...")
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...")
# 运行前记得把BSTestRunner.py 120行‘unicode’ 换成‘str’
with open(report_name, 'wb') as f:
    runner = BSTestRunner(stream=f, title="Test Report", description="localhost login test")
    runner.run(discover)
f.close()

print("find latest report...")
# 查找最新的测试报告
latest_report = latest_report(report_dir)
# 邮件发送报告

print("send email report...")
send_mail(latest_report)
print("test end!")

无头浏览器

无头浏览器即headless browser,是一种没有界面的浏览器。既然是浏览器那么浏览器该有的东西它都应该有,只是看不到界面而已。

浏览器内核

Webkit:目前最主流的浏览器内核,webkit是苹果公司开源的浏览器内核,其前身是KHTML。基于Webkit的浏览器很多,比如Safari,Chrome,Opera

Gecko:是Firefox浏览器的内核

Trident:是IE浏览器的内核

Blink:是webkit的一个分支版本,由google开发

Webkit内核

Webkit无疑是目前最流行的浏览器内核,以Webkit为核心存在很多移植(port),包括Safari、iPhone、Chrome、Android、QTWebKit等。不同的port专注于不同的领域。

PhantomJS

PhantomJS is a headless WebKit scriptable with a JavaScript API. It has fast and native support for various web standards: DOM handling, CSS selector, JSON, Canvas, and SVG.

PhantomJS可以说是目前使用最为广泛,也是最被认可的无头浏览器。由于采用的是Webkit内核,因此其和目前的Safari,Chrome等浏览器兼容性十分好。

为什么要使用PhantomJS?

PhantomJS 是一个无界面, 基于Webkit 的javascript 引擎. 一般来说我们的自动化脚本是需要运行在服务器上的, 往往这个时候系统并没有图形界面(如liunx服务器), 或者配置太低跑个浏览器实在是浪费. 而不需要图形界面的 PhantomJS 可谓是我们的不二之选.

PhantomJS安装配置

下载地址:http://phantomjs.org/download.html

下载完成后将phantomjs.exe文件放置Python安装目录即可。

运行使用

代码语言:javascript
复制
driver=webdriver.PhantomJS()
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-08-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 QA一隅 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 项目背景
  • 功能实现
  • 项目架构
    • 浏览器driver定义
      • 用例运行前后的环境准备工作
        • 工具方法模块
          • Pageobject页面对象封装
          • 无头浏览器
          • 浏览器内核
          • Webkit内核
          • PhantomJS
          • 为什么要使用PhantomJS?
          • PhantomJS安装配置
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档