python3+selenium实现Web自动化9:basePage.py、loginPage.py

封装selenium库的一些基础操作方法,如:元素定位、截图、元素通用操作、切换frame、警示框处理等等,basePage是最底层操作页面的方法,只要是web页面一些常用的操作都可以写在该基类中,后面有需要的地方直接调用即可。
basePage.py
代码参考:

# _*_ coding:utf-8 _*_
import time,os
from selenium.webdriver.support.ui import WebDriverWait             #导入显示等待等待
from selenium.webdriver.support import expected_conditions as EC    #导入判断方法
from Public import getPathInfo,log

log_info =log.logger                                                #log方法

class BasePage(object):
    """
    基本类,用于所有页面的继承
    """
    def __init__(self, driver):
        self.driver = driver

    def _open(self, url, pagetitle):
        """
        打开网页
        :param url: 网址
        :param pagetitle: 关键字
        """
        self.driver.maximize_window()               #浏览器最大化
        self.driver.implicitly_wait(30)             #显示等待
        self.driver.get(url)                        #打开指定网站
        assert pagetitle in self.driver.title, log_info.error("页面源码中不存在该关键字!")   #断言打开页面是否正确

    def find_element(self, *loc):
        """
        重写定位元素
        """
        try:
            #WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(loc))                   #判断元素是否存在
            WebDriverWait(self.driver, 10).until(lambda driver: driver.find_element(*loc).is_displayed())  #判断元素是否存在
            return self.driver.find_element(*loc)                   #返回定位元素
        except Exception as e:
            log_info.error('%s页面未找到%s元素' % (self, loc))
            self.get_windows_img()                                  #截图

    def switch_frame(self, loc):
        """
        切换frame
        """
        return self.driver.switch_to.frame(loc)

    def script(self, src):
        """
        定义script方法,用于执行js脚本
        """
        self.driver.execute_script(src)

    def get_windows_img(self):
        """
        截图
        """
        image_path=getPathInfo.join_cwd('Report\\Images\\')             #拼接截图存放目录
        if not os.path.exists(image_path):                              #判断目录是否存在
            os.mkdir(image_path)                                        #创建目录文件
        nowtime=time.strftime("%Y%m%d%H%M%S")                           #当前时间变量
        image_name=image_path +nowtime+ '.png'                          #截图路径
        try:
            self.driver.get_screenshot_as_file(image_name)              #截图
            log_info.info("截图保存地址:%s" % image_name)
            print('screenshot:', nowtime+'.png')                        #打印screenshot关键字,报告中显示截图
        except NameError as e:
            log_info.error("截图保存失败! %s" % e)
            #self.get_windows_img()

loginPage.py
以网易企业邮箱登录页面为案例,封装的方法主要有:登录页面元素、输入账号、输入密码、登录成功、登录失败等登录相关的步骤,loginPage是继承了basePage类,相当于中间层,以后页面元素变动,主要也是修改loginPage内容。

# _*_ coding:utf-8 _*_
from selenium.webdriver.common.by import By
from Page.basePage import BasePage                          #导入基本类
from Public import log

log_info =log.logger                                        #log方法

class Login_page(BasePage):
    """
    登录页面操作步骤
    """
    #元素定位器
    login_way =(By.ID,"switchNormalCtrl")
    username = (By.ID, "accname")
    password = (By.ID, "accpwd")
    login_btn = (By.XPATH, "//*[@id='loginBlock']/div[2]/form[1]/div[5]/button")
    logout = (By.XPATH, "//*[@id='top']/div/div[2]/div[3]/div/a[5]")
    login_msg = (By.ID, 'msgpid')
    user_air=(By.XPATH,"//*[@id='loginBlock']/div[2]/form[1]/div[1]/div")
    pw_air=(By.XPATH,"//*[@id='loginBlock']/div[2]/form[1]/div[2]/div")

    #打开页面
    def open(self, url, pagetitle):
        self._open(url, pagetitle)

    #登录方式选择
    def click_loginway(self):
        log_info.info("点击密码登录")
        self.find_element(*self.login_way).click()

    #输入账号
    def input_username(self, username):
        log_info.info("输入账号")
        self.find_element(*self.username).clear()
        self.find_element(*self.username).send_keys(username)

    #输入密码
    def input_password(self, password):
        log_info.info("输入密码")
        self.find_element(*self.password).clear()
        self.find_element(*self.password).send_keys(password)

    #点击登录
    def click_login(self):
        log_info.info("点击登录")
        self.find_element(*self.login_btn).click()

    #登录成功文本
    def show_userid(self):
        exit_text=self.find_element(*self.logout).text
        log_info.info("登录成功")
        return exit_text

    #账号注销
    def click_exit(self):
        self.find_element(*self.logout).click()
        log_info.info("账号注销")

    #登录失败提示
    def Mismatch(self):
        msg_text=self.find_element(*self.login_msg).text
        #log_info.info(msg_text)
        return msg_text

    #帐号为空
    def username_air(self):
        user_air=self.find_element(*self.user_air).text
        #log_info.info(user_air)
        return user_air

    #密码为空
    def password_air(self):
        password_text=self.find_element(*self.pw_air).text
        #log_info.info(password_text)
        return password_text

excel测试用例(UI_TestCase.xlsx)、unittest组织登录测试用例,其中需要用到读取UI_TestCase.xlsx测试数据、paramunittest(参数化)、调用loginPage类、断言等方法。

详细如下:

一、UI_TestCase.xlsx

image

二、test_login.py
self.login_page = Login_page(self.driver) #初始化loginPage对象
后续需要用self.login_page调用已封装的函数。

# _*_ coding:utf-8 _*_
from selenium import webdriver                                  #导入浏览器模块
from Page.loginPage import Login_page                           #导入登录对象类
from Public import log,readConfig,readExcel                     #导入封装的Log方法、GetPath方法
import unittest,time,paramunittest

excel= readExcel.readExcel('UI_TestCase.xlsx')                  #获取excel文件
names=excel.get_sheetnames()                                    #获取sheel
testcase=excel.get_xlsx(names[0])                               #获取指定shell的case
baseurl = readConfig.Read_Config().get_info('HTTP','baseurl')   #获取配置文件的baseurl
log_info =log.logger                                            #log方法

@paramunittest.parametrized(*testcase)
class TestLogin(unittest.TestCase):
    """
    网易企业邮箱登录测试
    """
    def setParameters(self,NO,case_name,path,username,password,result):
        """
        从 excel 中获取用例
        :param NO: 用例编号
        :param case_name: 用例名称
        :param username: 账号
        :param password: 密码
        :param result: 预期结果
        """
        self.no =NO
        self.case_name = str(case_name)
        self.path = baseurl+str(path)
        self.username = username
        self.password = password
        self.result=result

    @classmethod
    def setUpClass(self):
        """执行类之前运行一次"""
        self.driver = webdriver.Chrome()              #启动浏览器
        self.login_page = Login_page(self.driver)     #初始化loginPage对象

    @classmethod
    def tearDownClass(self):
        """执行完类后执行一次"""
        time.sleep(3)                                 #等待时间
        self.driver.close()                           #关闭浏览器窗口

    def setUp(self):
        """执行每个测试用例前执行一次"""
        self.login_page.open(self.path, '网易企业邮箱 - 登录入口')            #打开首页,并断言title是否正确
        log_info.info('---%s %s测试用例 测试开始---' % (names[0], self.case_name))

    def tearDown(self):
        """执行完每个测试用例后执行一次"""
        log_info.info('---%s %s测试用例 测试结束---' % (names[0], self.case_name))

    #@unittest.skip("无条件跳过该测试")
    def test_login(self):
        """登录成功测试"""
        #self._testMethodName = self.case_name                   #当前函数方法+测试用例测试函数名称
        self._testMethodDoc = self.case_name                     # 测试函数文档
        self.login_page.click_loginway()
        self.login_page.input_username(self.username)             #输入用户名
        self.login_page.input_password(self.password)               #输入密码
        self.login_page.click_login()                               #点击登录按钮

        if self.case_name in ['登录成功']:
            try:
                self.assertEqual(self.result, self.login_page.show_userid(), msg='断言失败')  # 断言
                self.login_page.click_exit()                                # 点击退出按钮
                log_info.info('***断言成功***')
            except Exception as e:
                log_info.info('***断言失败***')
                self.login_page.get_windows_img()
                raise e

        elif self.case_name in ['登录失败-账号为空']:
            try:
                self.assertEqual(self.result, self.login_page.username_air(), msg='断言失败')  # 断言
                log_info.info('***断言成功***')
            except Exception as e:
                log_info.info('***断言失败***')
                self.login_page.get_windows_img()
                raise e

        elif self.case_name in ['登录失败-密码为空']:
            try:
                self.assertEqual(self.result, self.login_page.password_air(), msg='断言失败')  # 断言
                log_info.info('***断言成功***')
            except Exception as e:
                log_info.info('***断言失败***')
                self.login_page.get_windows_img()
                raise e
        else:
            try:
                self.assertEqual(self.result, self.login_page.Mismatch(), msg='断言失败')  # 断言
                log_info.info('***断言成功***')
            except Exception as e:
                log_info.info('***断言失败***')
                self.login_page.get_windows_img()
                raise e

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

参考链接:
https://www.cnblogs.com/airb/p/13490299.html

--参考链接:
Selenium Python 框架之 BasePage页面封装写法
https://blog.csdn.net/wuyoudeyuer/article/details/102685903

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容