PO设计模式

PO模式全称Page Object Model ,是一种试用于UI自动化层面的分层设计模型。

page:存放页面元素的操作步骤

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from tools.display_wait import display_wait
from page_locator.login.login_page_locator import LoginPageLocator as loc


class LoginPage():
    '''登录界面'''

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

    def login(self, username, pwd, remember_user=False):
        WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located((loc.zt_protocol)))
        # # 点击组团推推广者规范
        self.driver.find_element(*loc.zt_protocol).click()
        # 输入用户名
        self.driver.find_element(*loc.input_usernane).send_keys(username)
        # 输入密码
        self.driver.find_element(*loc.input_pwd).send_keys(pwd)
        # 点击登录
        self.driver.find_element(*loc.click_button).click()

    def get_error_info(self):
        '''获取异常登录的错误提示信息'''
        xpath = "//div[@class='button']/span"
        display_wait(self.driver, By.XPATH, xpath)
        return self.driver.find_element_by_xpath(xpath).text

page_locator:存放定位元素的方式和元素对应的值,以元祖形式存储

'''存放定位元素的方式和值'''
from selenium.webdriver.common.by import By


class LoginPageLocator():
    # 点击组团推推广者规范
    zt_protocol = (By.XPATH,'//*[@id="agreement"]/div/div[3]')
    # 输入用户名
    input_usernane = (By.CLASS_NAME,'userName')
    # 输入密码
    input_pwd = (By.XPATH,'//input[@type="password"]')
    # 点击登录
    click_button = (By.XPATH,'//div[@class="button"]')

由此可见:page = 页面操作步骤+页面元素

test_data:存放测试数据,正常场景数据和异常场景数据分开存放,分别数据类型是列表和字典

# 正常登录数据
normal_data = {"username":"1489088761@qq.com","pwd":"mg123456"}

# 异常场景数据
exception_data = [
    {"username":"148908876@qq.com","pwd":"mg123456","expected":"该邮箱尚未注册,请先注册"},
    {"username":"1489088761@qq.com","pwd":"mg12345","expected":"用户名与密码不匹配,请重新输入"},
    {"username":"1","pwd":"1","expected":"请输入正确的邮箱号"},
]

testcase:存放测试用例,testcase=测试页面+测试数据,测试用例里面只有方法的调用和断言,体现一种出,高内聚低偶和。

import unittest
from selenium import webdriver
from page.login.login_page import LoginPage
from page.home.home_page import HomePage
from test_data.common.common_data import login_url
from test_data.login.login_data import normal_data, exception_data
from ddt import ddt, data


@ddt
class TestLogin(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()
        self.driver.get(login_url)
        self.lg = LoginPage(self.driver)

    def test_login_success(self):
        '''正常登录'''
        try:
            # 输入用户名,密码,登录
            self.lg.login(normal_data['username'], normal_data['pwd'])
            # 断言首页是否有退出这个元素
            self.assertTrue(HomePage(self.driver).isEcist_logout_ele())
        except Exception as e:
            print('出现异常是:{}'.format(e))

    @data(*exception_data)
    def test_error_format_login(self, data):
        '''异常用例3条:未注册的邮箱,密码错误,错误的邮箱号'''
        try:
            self.lg.login(data['username'], data['pwd'])
            print(data['expected'])
            self.assertEqual(self.lg.get_error_info(), data['expected'], '测试失败')
            print(self.lg.get_error_info())
        except Exception as e:
            print('出现异常是:{}'.format(e))

    def tearDown(self):
        self.driver.quit()


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

tools:里面存放一些公共方法:

如上传文件的方法:

'''实现非input标签上传文件,调用此方法需要打开windows上传文件的系统窗口再调用'''
import win32gui
import win32con


def upload_file(file_path):
    '''
    :param file_path:上传文件的路径
    :return:
    '''
    dialog = win32gui.FindWindow("#32770", "打开")
    comboxex32 = win32gui.FindWindowEx(dialog, 0, "ComboBoxEx32", None)
    combox = win32gui.FindWindowEx(comboxex32, 0, "ComboBox", None)
    edit = win32gui.FindWindowEx(combox, 0, "Edit", None)
    button = win32gui.FindWindowEx(dialog, 0, "Button", "打开(&0)")
    win32gui.SendMessage(edit, win32con.WM_SETTEXT, None, file_path)
    win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button)


upload_file(r'C:UsersadminDesktopScreenshotmvcSnipaste_2019-12-26_20-59-19.png')

显示等待的方法:

'''显示等待,等待元素可见'''
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By


def display_wait(driver, location_mthod, value):
    '''
    :param driver: driver对象
    :param location_mthod: 定位方式,如:By.XPATH
    :param value: 对应的元素,如:id = 'TANGRAM__PSP_10__footerULoginBtn'
    :return:
    '''
    WebDriverWait(driver, 10).until(EC.visibility_of_element_located((location_mthod, value)))

全部详细文件夹规划如图:

原文地址:https://www.cnblogs.com/xiamaojjie/p/12157346.html