PageObject三层架构模式实现

1:PageObject三层架构分为:

 接下来用163邮箱的登录功能来举例说明三层架构的使用。

1:先创建目录结构,如下图

 2:在工具Util中,先封装查找元素定位的工具,创建一个find_ele.py文件。内容如下:

from selenium.webdriver.support.wait import WebDriverWait


def find_element(dirver, find_type, find_express):
    '''查找元素控件'''
    try:
        element = WebDriverWait(dirver, 20).until(lambda driver:driver.find_element(find_type, find_express))
        # 20秒内,每0.5秒去查找一次元素,直到找到为止,找到就返回,如果20秒还没找到,就抛异常
        return element
    except Exception as e:
        raise e

3:接下来在pageobject三层架构中的第一层对象层,封装登录页面的元素定位及操作

在Object文件夹下创建一个loginpage.py文件,内容如下:

# 对象层
from selenium import webdriver
from Util.find_ele import find_element
from Util.read_ini import ParseConfigFile


class LoginPage:

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

    def input_username(self, username):
        '''定位用户名输入控件,并输入用户名'''
        find_element(self.driver, 'name', 'email').send_keys(username)
        
    def input_password(self, password):
        '''定位密码输入控件,并输入密码'''
        find_element(self.driver, 'name', 'password').send_keys(password)
        
    def switch_frame(self):
        '''切换iframe'''
        frame = find_element(self.driver, 'tag name', 'iframe')
        self.driver.switch_to.frame(frame)

    def login_click(self):
        '''点击登录'''
        find_element(self.driver, 'id', 'dologin').click()
        

if __name__ == '__main__':
    driver = webdriver.Chrome()

    # 访问网址
    driver.get('https://mail.163.com/')

    login = LoginPage(driver)        # 初始化LoginPage类
    # 执行登录操作
    login.switch_frame()
    login.input_username('12345')
    login.input_password('123456')
    login.login_click()

4:下来是pageobject的第二层逻辑层,封装登录功能

在Module文件夹下,创建一个login.py文件,内容如下:

# 逻辑层
from Object.loginpage import LoginPage
from selenium import webdriver

class LoginModule:
    def __init__(self):
        print('------开始登录------')

    def login(self, driver, username, password):
        '''登录操作'''
        try:
            login_page = LoginPage(driver)        # 初始化对象层的LoginPage类
            login_page.switch_frame()
            login_page.input_username(username)
            login_page.input_password(password)
            login_page.login_click()
        except Exception as e:
            raise e

if __name__ == '__main__':
    driver = webdriver.Chrome()
    driver.get('https://mail.163.com/')
    login = LoginModule()
    login.login(driver, '12345', '123456')

5:pageobject第三层业务层,编写测试用例

在Scripts文件夹下创建一个以test开头的py文件,test_login.py文件内容如下:

# 业务层
from selenium import webdriver
from Moduel.login import LoginModule


def test_login():
    driver = webdriver.Chrome()
    driver.get('https://mail.163.com/')
    login = LoginModule()
    login.login(driver, '12345', '123456')

6:pageobject三层架构的核心逻辑已经写完了,但是可以发现,其中的元素定位方式和值是写死的,如果有变动,那么就要去修改对象层的每个元素的定位方式及值。

为了防止改动源文件,我们增加一个.ini文件来管理元素定位的方式及值,每次修改元素定位,就只用修改ini文件即可。

ini文件的格式为:

节[section1]
参数 name=value
参数 name=value
参数 name=value

节[section2]
参数 name=value
参数 name=value
参数 name=value

以节及它的参数来表达定位元素方式和值。section1和section2之间的参数,都是属于section1的。

登录页面的元素定位方式及值,用ini文件来表示,为:

在Setting文件夹下创建一个element_location.ini文件。

[login_page]
login_page.username = name:email
login_page.password = name:password
login_page.loginbutton = id:dologin
login_page.frame = tag name:iframe

7:ini配置文件已经完成,接下来就是要读取ini文件中的内容。

首先在Setting文件夹下,创建一个Config.py文件,用来获取文件路径。

# 获取文件地址
import os

Base_path = os.path.dirname(os.path.dirname(__file__))     # 获取根目录
print(Base_path)

# 元素定位文件
Element_Location_Path = os.path.join(Base_path, 'Setting/element_location.ini')
print(Element_Location_Path)


# 测试用例文件路径
Case_Path = os.path.join(Base_path, 'Scripts')
print(Case_Path)

然后再Util文件夹下,创建一个read_ini.py文件,来封装读取ini文件的工具类。

# 解析config.ini文件

import configparser
from Setting.Config import Element_Location_Path

class ParseConfigFile:

    def __init__(self):
        self.cf = configparser.ConfigParser()    # 初始化类
        self.cf.read(Element_Location_Path)      # 读取文件

    def getSection(self, section_name):
        '''获取section_name下的所有参数'''
        option_dict = dict(self.cf.items(section_name))
        return option_dict


if __name__ == '__main__':
    pf = ParseConfigFile()
    print(pf.getSection('login_page'))
输出:{'login_page.username': 'name:email', 'login_page.password': 'name:password', 
'login_page.loginbutton': 'id:dologin', 'login_page.frame': 'tag name:iframe'}

8:修改Object对象层中的获取元素定位的方式。

修改loginpage.py文件:

# 对象层
from selenium import webdriver
from Util.find_ele import find_element
from Util.read_ini import ParseConfigFile


class LoginPage:

    def __init__(self, driver):
        self.driver = driver
        self.pf = ParseConfigFile()
        self.option_dicts = self.pf.getSection('login_page')     # 获取定位元素的配置文件内容

    def input_username(self, username):
        '''定位用户名输入控件,并输入用户名'''
        # find_element(self.driver, 'name', 'email').send_keys(username)
        # 从读取的配置文件option_dict字典中,获取用户名输入框的定位方式及值
        location_name, location_type = self.option_dicts['login_page.username'].split(':')
        find_element(self.driver, location_name, location_type).send_keys(username)

    def input_password(self, password):
        '''定位密码输入控件,并输入密码'''
        # find_element(self.driver, 'name', 'password').send_keys(password)
        # 从读取的配置文件option_dict字典中,获取密码输入框的定位方式及值
        location_name, location_type = self.option_dicts['login_page.password'].split(':')
        find_element(self.driver, location_name, location_type).send_keys(password)

    def switch_frame(self):
        '''切换iframe'''
        # frame = find_element(self.driver, 'tag name', 'iframe')
        # 从读取的配置文件option_dict字典中,获取iframe的定位方式及值
        location_name, location_type = self.option_dicts['login_page.frame'].split(':')
        frame = find_element(self.driver, location_name, location_type)
        self.driver.switch_to.frame(frame)

    def login_click(self):
        '''点击登录'''
        # find_element(self.driver, 'id', 'dologin').click()
        # 从读取的配置文件option_dict字典中,获取登录按钮的定位方式及值
        location_name, location_type = self.option_dicts['login_page.loginbutton'].split(':')
        find_element(self.driver, location_name, location_type).click()

if __name__ == '__main__':
    driver = webdriver.Chrome()

    # 访问网址
    driver.get('https://mail.163.com/')

    login = LoginPage(driver)
    login.switch_frame()
    login.input_username('YM_yimin')
    login.input_password('yimin19960930')
    login.login_click()

9:最后,在run.py文件中,进行执行

# 执行入口
import pytest
from Setting.Config import Case_Path

if __name__ == '__main__':
    pytest.main(['-s', '-v', Case_Path])

整个PageObject三层架构框架就写完了。

C#三层架构是一种软件设计模式,旨在将应用程序分为三个主要部分:表示层、业务逻辑层和数据访问层。以下是一个简单的示例: 1. 表示层:用户界面和用户交互,包括用户输入和输出。在此层中,通常使用ASP.NET MVC或Windows Forms等技术。 2. 业务逻辑层:应用程序的核心部分,包括所有业务逻辑和规则。在此层中,通常包含C#类和方法。 3. 数据访问层:与数据存储交互的层,包括数据库或文件系统。在此层中,通常使用ADO.NET或Entity Framework等技术。 以下是一个简单的示例代码: 1. 表示层: ``` public partial class Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { BindData(); } } private void BindData() { EmployeeBL empBL = new EmployeeBL(); GridView1.DataSource = empBL.GetEmployees(); GridView1.DataBind(); } } ``` 2. 业务逻辑层: ``` public class EmployeeBL { public List<Employee> GetEmployees() { EmployeeDAL empDAL = new EmployeeDAL(); return empDAL.GetEmployees(); } } ``` 3. 数据访问层: ``` public class EmployeeDAL { public List<Employee> GetEmployees() { List<Employee> employees = new List<Employee>(); string connectionString = ConfigurationManager.ConnectionStrings["EmployeeDBConnection"].ConnectionString; using (SqlConnection con = new SqlConnection(connectionString)) { SqlCommand cmd = new SqlCommand("SELECT * FROM Employee", con); con.Open(); SqlDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { Employee emp = new Employee(); emp.Id = Convert.ToInt32(reader["Id"]); emp.Name = reader["Name"].ToString(); emp.Department = reader["Department"].ToString(); employees.Add(emp); } } return employees; } } ``` 这是一个简单的示例,仅用于演示C#三层架构的基本概念。实际应用中,可能会有更多的层和更复杂的业务逻辑和数据访问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值