Web UI自动化测试实例(登入网易云音乐账户)——(四)Python+Unittest+selenium_POM模式

(三)Python+unittest+selenium+ddt数据驱动_优化版

POM模式

四层结构:基础封装层、页面对象层、测试用例层、数据层

  1. 基础层:封装一些常用的方法,提高代码的复用。
    (如:继承了selenium常用的webdriver操作,并对部分操作进行了封装; 封装日志功能;将所有界面共用的方法进行封装 等)(本次仅将 定位元素、等待元素显示、元素是否显示、点击、输入 等等作为基础层一些方法,对于其他,如日志功能,未加入进去,后续可以考虑优化)
  2. 页面对象层:页面对象就是将每个界面当成一个对象,将界面中的元素当成对象的属性或者方法 (首页、多个不同pop框形式的登入页面)
  3. 测试用例层:uniittest框架来管理和执行用例 (此处:仅一个测试用例,即手机号码登入网易云账号)
  4. 数据层:传入的测试数据(账号,密码)

实例:
代码结构

1.基础层:

common.py

#coding=utf-8
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By

class Common():
    def __init__(self,driver):
        self.driver = driver

    def open_url(self,url):
        self.driver.get(url)

    def click(self,locator):
        #self.find_element(locator).click()
        self.driver.find_element(*locator).click()

    def input_text(self,locator,text):
        self.driver.find_element(*locator).send_keys(text)

    def wait_for_element_displayed(self,locator,timeout=None,message=None):
        return WebDriverWait(self.driver,10).until(lambda m:m.find_element(*locator).is_displayed(),message=message)

    def is_element_displayed(self,locator,message=None):
        try:
            return self.driver.find_element(*locator).is_displayed
        except Exception:
            return False

    def element_text(self,locator):
        return self.driver.find_element(*locator).text

2.页面对象层

  • page
    • homePage.py
    • scanOrOtherPage.py
    • loginModePage.py
    • phoneNumberLoginPage.py
  1. homePage.py,如下
#coding=utf-8
from pom.common.common import Common
from selenium.webdriver.common.by import By
class HomePage(Common):

    _login_locator = (By.CSS_SELECTOR, 'a.link.s-fc3')

    def __init__(self,driver):
        self.driver = driver

    def click_login(self,url):
        self.open_url(url)
        self.click(self._login_locator)
  1. scanOrOtherPage.py,如下:
#coding=utf-8
from pom.common.common import Common
from selenium.webdriver.common.by import By

class ScanOrOtherPage(Common):

    _other_login_mode_locator =(By.CSS_SELECTOR ,'a.u-btn2.other')

    def __init__(self,driver):
        self.driver= driver

    def select_other_login_mode(self):
        self.click(self._other_login_mode_locator)

  1. loginModePage.py, 如下:
#coding=utf-8
from pom.common.common import Common
from selenium.webdriver.common.by import By

class LoginModePage(Common):

    _privacy_policy_checkout_loactor = (By.CSS_SELECTOR ,'input#j-official-terms')
    _phone_number_login_locator = (By.CSS_SELECTOR ,'a.u-btn2.u-btn2-2')

    def __init__(self,driver):
        self.driver = driver

    def check_privacy_policy_checkout(self):    
        if not self.driver.find_element(*self._privacy_policy_checkout_loactor).is_selected():
            self.click(self._privacy_policy_checkout_loactor)

    def select_phone_number_login(self):
        self.check_privacy_policy_checkout()
        self.click(self._phone_number_login_locator)
  1. phoneNumberLoginPage.py 如下:
#coding= utf-8
from pom.common.common import Common
from selenium.webdriver.common.by import By
import time

class PhoneNumberLoginPage(Common):

    _input_phone_number_locator = (By.CSS_SELECTOR , 'input.j-phone.txt.u-txt')
    _input_password_locator = (By.CSS_SELECTOR , 'input#pw.j-pwd.u-txt')
    _login_button_locator = (By.CSS_SELECTOR, 'a.j-primary.u-btn2.u-btn2-2')
    _locate_mark_locator = (By.CSS_SELECTOR, 'i.u-icn.u-icn-25')
    _get_login_failed_reason_locator = (By.CSS_SELECTOR,'div.j-err.u-err span')

    def __init__(self,driver):
        self.driver= driver

    def input_phone_number_account(self,phone_number):
        self.input_text(self._input_phone_number_locator,phone_number)
    
    def input_password(self,password):
        self.input_text(self._input_password_locator,password)
    
    def click_login_button(self):
        self.click(self._login_button_locator)
        return self.get_actual_login_status()


    def get_login_failed_reason(self):#查看页面上登入失败的原因
        #self.driver.implicitly_wait(5)
        time.sleep(2)
        #return self.driver.find_element(self._get_login_failed_reason_locator).text.encode('utf-8')
        return self.element_text(self._get_login_failed_reason_locator)

    def get_actual_login_status(self): #主要是看账户登入真实情况
        if self.is_element_displayed(self._locate_mark_locator):
        #if self.driver.find_element(*self._locate_mark_locator).is_displayed: #如果页面上显示出!
            return self.get_login_failed_reason() #打印登入失败的原因
        else:
            return '登入成功' #否则登入成功

3.测试用例层

test_login.py

#coding:utf-8
import sys
sys.path.append('../../') #调用不同目录下的包中的方法,需要添加环境变量
import unittest
from ddt import ddt,data,unpack,file_data
from selenium import  webdriver
from pom.data.load_data import GetTestData,TestResult
from pom.common.common import Common
from pom.page.homePage import HomePage
from pom.page.scanOrOtherPage import ScanOrOtherPage
from pom.page.loginModePage import LoginModePage
from pom.page.phoneNumberLoginPage import PhoneNumberLoginPage

get_test_data = GetTestData()
write_test_result = TestResult()
test_data_list = get_test_data.get_test_data

@ddt
class TestLogin(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(4)
        self.driver.maximize_window()
        self.home_page = HomePage(self.driver)
        self.scan_or_other_login_page = ScanOrOtherPage(self.driver)
        self.login_mode_page = LoginModePage(self.driver)
        self.phone_number_login_page = PhoneNumberLoginPage(self.driver)
        
    def tearDown(self):
        self.driver.quit()


    @data(*test_data_list) 
    @unpack
    def test_login_wangyiyun(self,url,phone_number,password,expext_result):
        try:
            self.home_page.click_login(url)
            self.scan_or_other_login_page.select_other_login_mode()
            self.login_mode_page.select_phone_number_login()
            self.phone_number_login_page.input_phone_number_account(phone_number)
            self.phone_number_login_page.input_password(password)
            actual_login_result = self.phone_number_login_page.click_login_button()
            if expext_result.encode('utf-8') == actual_login_result.encode('utf-8'):
                write_test_result.write_test_result('Pass')
            else:
                write_test_result.write_test_result('Fail')
        except Exception as e:
            print e
            actual_login_result = 'Fail,something wrong'
            write_test_result.write_test_result('Fail:{}'.format(actual_login_result))
        write_test_result.write_actual_result(actual_login_result)
        self.driver.quit()

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

4.测试数据与报告

#coding=utf-8
import xlrd
import openpyxl

#负责读取数据
class GetTestData():

    def __init__(self):
        self.excel = xlrd.open_workbook('../test_report/test_report.xlsx')
        self.sheet = self.excel.sheet_by_name('test_data')
        self.rows = self.sheet.nrows
        self.cols = self.sheet.ncols

    @property
    def get_test_data(self):
        data_list = []
        data = []
        for row in range(1,self.rows):
            for i in self.sheet.row_values(row,1,5):
                if type(i) == float: #表格中输入的手机号码是float类型,需要转换成int,不然会报错
                    data.append(int(i)) #用data列表存放转换后的每组测试数据
                else:
                    data.append(i)
            data_list.append(data)
            data =[] #移除测试数据
        return  data_list
    
    def test_result(self):
        for row in range(1,self.rows):
            self.sheet.cell_value(row,7)


# testr= GetTestData()
# print testr.get_test_data
         

class TestResult():
    def __init__(self):
        self.excel = openpyxl.load_workbook('../test_report/test_report.xlsx')
        self.sheet = self.excel['test_data']
        self.num = 2
        self.result = 2

    def write_actual_result(self,actual_result):
        self.sheet.cell(row=self.num,column=6,value=actual_result)
        self.num +=1
        self.close_excel()


    def write_test_result(self,test_result):
        self.sheet.cell(row=self.result,column=7,value=test_result)
        self.result +=1
        self.close_excel()
    def close_excel(self):
        self.excel.save('../test_report/test_report.xlsx')

运行完test_login.py 文件去test_report.xlsx 文件中查看相应的测试结果:
test_report.xlsx
在这里插入图片描述
当执行发生异常时,故需要添加logging,去看具体异常原因,定位异常的地方。
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值