Web端自动化测试--Python+selenium+unitt

2021-02-03  本文已影响0人  巴鶴

Page Object 是 Selenium 自动化测试项目开发实践的最佳设计模式之一,Page Object 的主要体现于对界面交互细节的封装,这样可以使测试案例更关注与业务而非界面细节,提高测试案例的可读性。

认识 Paget Object

一、Page object 简称POM框架

二、Page object设计模式的优点

  1. 减少代码的重复;
  2. 提高测试用例的可读性;
  3. 提高测试用例的可维护性,特别是针对 UI 频繁变化的项目;

实战--博客园登录自动化测试发送测试报告

思路分析:

代码参考

myunit.py

# 浏览器驱动封装
'''
@author: Yvon_早安阳光
'''
from selenium import webdriver
import unittest 
class MyTest(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()  
    def tearDown(self):
        self.driver.quit()

function.py

'''
@author: Yvon_早安阳光
'''
import time
from selenium import webdriver
 
#封装截图函数
def insert_img(driver,filename):
    file_path = 'insert_img/'
    now = time.strftime("%Y-%m-%d %H_%M_%S")
    screen_name = file_path + '\\' + now + filename
    driver.get_screenshot_as_file(screen_name)
     
# 登录成功截图
def success_img(driver,file_name):
    filepath = 'success_img/'
    now = time.strftime("%Y-%m-%d %H_%M_%S")
    screenname = filepath + '\\' + now + file_name
    driver.get_screenshot_as_file(screenname)    
        
if __name__ == '__main__':
    driver = webdriver.Firefox()
    driver.quit()

Base.py

# 页面元素基础类操作封装
'''
@author: Yvon_早安阳光
'''
class Page(object):

  #BasePage封装所有页面都公用的方法,例如driver, url ,FindElement等
    login_url = "https://passport.cnblogs.com/user/signin"
    #实例化BasePage类时,最先执行的就是__init__方法,该方法的入参,其实就是BasePage类的入参。
    #__init__方法不能有返回值,只能返回None,self只实例本身,相较于类Page而言

    def __init__(self,selenium_driver,base_url = login_url,parent = None):
        self.base_url = base_url
        self.driver = selenium_driver
        self.timeout =10
        self.parent = parent

    '''通过title断言进入的页面是否正确。使用title获取当前窗口title,检查输入的title是否在当前title中,返回比较结果(True 或 False)'''  

    def on_page(self):
        return self.driver.current_url == (self.base_url + self.url)

    '''#打开页面,并校验页面链接是否加载正确,以单下划线_开头的方法,在使用import *时,该方法不会被导入,保证该方法为类私有的。'''

    def _open(self,url):
        #使用get打开访问链接地址
        url = self.base_url + url
        self.driver.get(url)
        #使用assert进行校验,打开的窗口title是否与配置的title一致。调用on_page()方法
       # assert self.on_page(), u"打开开页面失败 %s"%url
      '''定义open方法,调用_open()进行打开链接'''

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

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

    '''重写switch_frame方法'''
    def switch_frame(self, loc):
        return self.driver.switch_to_frame(loc)

    '''script方法,用于执行js脚本,范围执行结果'''
    def script(self, src):
        self.driver.execute_script(src)

    '''重写定义send_keys方法'''
    def send_keys(self, loc, vaule, clear_first=True, click_first=True):
        try:
            loc = getattr(self,"_%s"% loc)  #getattr相当于实现self.loc
            if click_first:
                self.find_element(*loc).click()
            if clear_first:
                self.find_element(*loc).clear()
                self.find_element(*loc).send_keys(vaule)         
        except AttributeError:
            print (u"%s 页面中未能找到 %s 元素"%(self, loc))

LoginPage.py

登录元素操作封装
'''
@author: Yvon_早安阳光
'''
from selenium.webdriver.common.by import By
from Base import Page
from time import sleep

class login(Page):
    '''博客园登录页面模型'''
    url = '/'
    # 定位器
    '''用户名'''
    username_loc = (By.ID,"input1")
    '''密码'''
    password_loc = (By.ID,"input2")
    '''登陆按钮'''
    submit_loc = (By.ID,"signin")

  '''输入用户名:调用send_keys对象,输入用户名'''
    def input_username(self,username):
        self.find_element(*self.username_loc).clear()
        self.find_element(*self.username_loc).send_keys(username)        
             
 '''输入密码:调用send_keys对象,输入密码'''
    def input_password(self,password):
        self.find_element(*self.password_loc).clear()
        self.find_element(*self.password_loc).send_keys(password)
 
  '''点击登录:调用send_keys对象,点击登录''' 
    def click_submit(self):
        self.find_element(*self.submit_loc).click()
         
   # 定义统一登录入口
    def user_login(self,username = '123',password = '123'):
        '''获取用户的用户名和密码'''
        self.open()
        self.input_username(username)
        self.input_password(password)
        self.click_submit()
        sleep(2)
         
    '''用户为空'''
    user_error_hint_loc = (By.XPATH,".//*[@id='tip_input1']")
    '''密码为空'''
    pawd_error_hint_loc = (By.XPATH,".//*[@id='tip_input2']")
    '''用户名和密码不匹配'''
    user_pawd_error_hint_loc = (By.XPATH,".//*[@id='tip_btn']")
    '''登陆成功ID校验'''
    user_login_success_loc = (By.ID,"lnk_current_user")
   
    #用户名错误提示
    def user_error_hint(self):
        return self.find_element(*self.user_error_hint_loc).text
     
    #密码错误提示
    def pawd_error_hint(self):
        return self.find_element(*self.pawd_error_hint_loc).text
     
    #用户名和密码不匹配错误提示
    def user_pawd_error_hint(self):
        return self.find_element(*self.user_pawd_error_hint_loc).text
    #登录成功用户名
    def user_login_success(self):
        return self.find_element(*self.user_login_success_loc).text

Login_sta.py

登录测试用例
'''
@author: Yvon_早安阳光
'''
from time import sleep
import unittest,random
from Login1 import myunit
from LoginPage import login
from Login1 import function

class LoginTest(myunit.MyTest):
    '''博客园登录'''
     
    #测试用户登录
    def user_login_verify(self,username = "",password = ""): 
        login(self.driver).user_login(username,password)
         
    def test_login1(self):
        '''用户名、密码为空'''
        self.user_login_verify()
        po = login(self.driver)
        self.assertEqual(po.user_error_hint(),'请输入登录用户名')    
        print(po.user_error_hint())
        sleep(1)
#         '''单个截图'''
#         screen_name = 'insert_img/' + '\\' + time.strftime("%Y-%m-%d %H_%M_%S")
#         self.driver.get_screenshot_as_file(str(screen_name ) + "请输入登录用户名.jpg")
        u"""封装函数截图"""
        function.insert_img(self.driver,"用户名和密码为空.jpg")
  
    def test_login2(self):
        '''用户名正确、密码为空'''
        self.user_login_verify(username='a2036')
        po = login(self.driver)
        self.assertEqual(po.pawd_error_hint(),'请输入密码')       
        print(po.pawd_error_hint())
        sleep(1)
        function.insert_img(self.driver,"用户名正确-密码为空.jpg") 
                       
    def test_login3(self):
        '''用户名为空、密码正确'''
        self.user_login_verify(password ='123456')
        po = login(self.driver)
        self.assertEqual(po.user_error_hint(),'请输入登录用户名')      
        print(po.user_error_hint())
        sleep(1)
        function.insert_img(self.driver,"用户名为空-密码正确.jpg")
                
    def test_login4(self):
        '''用户名和密码不匹配'''
        character = random.choice('zyxwvutsrqponmlkjihgfedcba')
        user_name = 'zhangsan' + character
        self.user_login_verify(username=user_name,password ='123456')
        sleep(2)
        po = login(self.driver)
        self.assertEqual(po.user_pawd_error_hint(),'该用户不存在\n\n联系 contact@cnblogs.com')
        print(po.user_pawd_error_hint())
        sleep(1)
        function.insert_img(self.driver,"用户名和密码不匹配.jpg")
          
    def test_login5(self):
        '''用户名、密码正确登录'''
        self.user_login_verify(username='a2036', password ='20A3d4p43W36#20')
        sleep(1)
        po = login(self.driver)
        sleep(1)
        self.assertEqual(po.user_login_success(),'a2036')
        print(po.user_login_success())
        function.success_img(self.driver,"登录成功.jpg")
         
if __name__ == '__main__':
    unittest.main()

Send_mail_report.py

发送邮件包含测试报告、邮件标题、邮件正文,附件(图片、PDF)
'''
@author: Yvon_早安阳光
'''
import unittest,time,os,smtplib
from HTMLTestRunner import HTMLTestRunner
from email.mime.multipart import MIMEMultipart
from email.header import Header
from email.mime.application import MIMEApplication
from email.mime.text import MIMEText
#======================定义发送邮件======================
def send_mail(file_new):
    #测试报告
    '''file_new是指最新的测试报告'''
    f = open(file_new,'rb')
    mail_body = f.read()
    f.close()
     
    msg = MIMEMultipart()
    '''邮件标题'''
    msg['Subject'] = Header('博客园登录测试报告' ,'utf-8')
     
    '''邮件正文'''
    zhengwen = "各位,详情测试结果请见附件文档"
    msg.attach(MIMEText(zhengwen, 'plain')) 
     
    '''附件测试报告 '''
    att= MIMEText(mail_body,'html','utf-8')
    att.add_header('Content-Disposition', 'attachment', filename='New_TestReport.html')
    msg.attach(att)
     
    '''附件图片'''
    jpgpart = MIMEApplication(open('fujian/测试计划.jpg','rb').read())
    jpgpart.add_header('Content-Disposition', 'attachment', filename='测试计划.jpg')
    msg.attach(jpgpart)
     
    '''附件PDF'''
    pdfpart = MIMEApplication(open('fujian/功能需求.pdf','rb').read())
    pdfpart.add_header('Content-Disposition', 'attachment', filename='功能需求.pdf')
    msg.attach(pdfpart)
 
    #发送邮件
    smtp = smtplib.SMTP()
    smtp.connect('smtp.exmail.qq.com')
    smtp.login('fajin@bertadata.com','36#20qa20A')
    smtp.sendmail('fajin@bertadata.com','huiselanse@yeah.net',msg.as_string())
    print('email has send out !')
    smtp.quit()
#======================查找测试报告的目录,找到最新生成的测试报告======================
def new_report(testreport):
    lists = os.listdir(testreport)
    lists.sort(key = lambda fn: os.path.getatime(testreport + '\\' + fn))
    file_new = os.path.join(testreport,lists[-1])
    print(file_new)
    return file_new
 
if __name__ == '__main__':
    #指定测试用例为当前文件夹下的目录
    test_dir = './'
    discover = unittest.defaultTestLoader.discover(test_dir, pattern='login_sta*.py')
    
    #定义报告存放的路径
    result_report_dir= 'result_report/'
    '''实时当前的时间'''
    now = time.strftime("%Y-%m-%d %H_%M_%S")
    file_name = result_report_dir + '\\' + now +'result.html'
    fp = open(file_name,'wb')    
    #定义测试报告
    runner =HTMLTestRunner(stream = fp,title ='自动化测试报告',
                           description='用例执行情况:')
    runner.run(discover)
    fp.close() #关闭报告文件
     
    new_report = new_report(result_report_dir)
    send_mail(new_report)

脚本目录

1.本地文件目录.png
2.图片和文档附件存放目录.png
3.测试用例测试结果截图目录.png
4.测试报告目录.png
5.登录成功附件目录.png
6.邮件接收附件和测试报告.png
7.自动化详细测试报告.png
上一篇下一篇

猜你喜欢

热点阅读