python自动化之selenium的PO设计模式

前言:做selenium自动化,肯定是要学习po模式的,它会让你的代码实现低耦合,数据与结构分离。
Page Object Model (POM)“页面对象模型”,讲元素定位和基本方法封装在一个页面对象中,只对外提供必要的操作接口

如何设计pom?
①首先要有一个BasePage类,用来封装浏览器基本操作,一些公共方法和关键字
②各个Page类是封装它这个页面的一些元素操作和方法,以及所需的参数值
③TestCase就是用unittest执行用例,并且加入断言判断用例是否成功
下面是我画的流程图
在这里插入图片描述
BasePage.py 这个类是封装浏览器基本操作方法的,比如driver,找寻元素定位,输入框输入,点击事件等,注意带的参数,包括找寻方法用显式等待

from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

class BasePage():
    '''
    封装浏览器基本操作
    公共方法:等待时间,截图,点击,日志,浏览器所有操作
    需求:任何点击,自动去加等待时间
    关键字驱动:
        公共方法关键字:
        业务关键字:操作经常绑定在一起的,封装成关键字
    '''
    def __init__(self,driver):
        self.driver=driver

    def find_ele(self,loc):
        '''
        找元素的方法,加上显式等待时间
        :param loc:
        :return: ele:webdriver对象
        '''
        try:
            ele=WebDriverWait(self.driver,10).until(EC.visibility_of_element_located(loc))
        except Exception as e:
            print(e)
        return ele

    def my_send_keys(self,loc,value):
        '''
        输入方法
        :param loc: 元素的定位
        :param value: 输入的值
        :return:
        '''
        self.find_ele(loc).send_keys(value)
    def my_click(self,loc):
        '''
        点击方法
        :param loc: 元素的定位
        :return: 
        '''
        self.find_ele(loc).click()

LoginPage.py 是登陆页面的一个类,主要是登陆的时候所需要的元素定位方法,这里用到的是By方式,自己可以决定是用ID,还是XPATH,还是CLASSNAME,最后封装成一个login方法

from selenium.webdriver.common.by import By
from po.BasePage import BasePage

class LoginPage(BasePage):

    username=(By.ID,'userName')
    pwd=(By.ID,'passWord')
    login_button=(By.XPATH,'/html/body/div/div/div/div[2]/div/form/div[4]/div/div/span/button')

    def username_input(self,value):
        self.my_send_keys(self.username,value)
    def pwd_input(self,value):
        self.my_send_keys(self.pwd,value)

    def click_button(self):
        self.my_click(self.login_button)

    def login(self,username,password):
        '''
        登陆方法
        :param username: 用户名
        :param password: 密码
        :return:
        '''
        self.username_input(username)
        self.pwd_input(password)
        self.click_button()

这只是登陆页面,还有首页啊,创建页面啊,都可以封装自己的class类

最后是testcase用例执行,注意这个类是怎么使用LoginPage里的参数的
首先是要继承LoginPage

因为在LoginPage.py文件里已经直接封装了登陆方法,所以可以直接调用login方法就行
在没有封装login之前,还要执行一个个输入框和点击方法
所以每个业务类能封装就封装,要保证testcase里只有输入数据值
TestCase.py 代码如下

import unittest
from selenium import webdriver
import time
from po.LoginPage import LoginPage
from ddt import ddt,data,unpack

@ddt
class testlogin(unittest.TestCase,LoginPage):

    def setUp(self) -> None:
        print('每个用例的前置')
        self.driver = webdriver.Chrome()
        self.driver.get("http://ip:port/")
    def tearDown(self) -> None:
        print('每个用例的后置')
        time.sleep(3)
        self.driver.quit()

    @data(('zhou','123456'),('admin','123456'))
    @unpack
    def test_login(self,username,pwd):

        # self.driver.find_element(*LoginPage.username).send_keys('zhou')
        # self.driver.find_element(*LoginPage.pwd).send_keys('123456')
        # self.driver.find_element(*LoginPage.login_button).click()
        # time.sleep(3)

        #封装用户名输入方法,密码输入方法,点击登陆按钮
        # self.username_input('zhou')
        # self.pwd_input('123456')
        # self.click_button()

        #直接调用LoginPage封装的登陆方法
        self.login(username,pwd)
        time.sleep(1)
        url=self.driver.current_url
        print(url)
        self.assertEqual(url,'http://ip:port/welcome',msg='判断url是否是欢迎页面')




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

上面test_login方法下面有两个注释掉的,是假设LoginPage里没有封装login方法而写的,一步步循序渐进,最后封装了login方法的话,在testcase里只需要调用login方法了,简单多了,最后还加了断言。
在用当前url做断言的时候有个坑,就是我明明登陆进去了,但是取得的driver.current_url一直是user/login,花费了半天时间,最后加了个等待时间就好了,真是太坑了,所以说做selenium的UI自动化,在定位元素或者断言的时候万能解决办法是先加个等待时间 time.sleep(1),不行的话再看其他办法

以上,就是PO设计模式的自己的见解,以及例子,记录一下也方便以后查找

猜你喜欢

转载自blog.csdn.net/shenshenruoxi/article/details/108503527