python selenium po_selenium 实战二_PO代码重构

## 重构页面类

### PO(Page Objects)设计模式

PO设计模式,旨在为每个待测网页创建一个对象。通过这样的设计,**将业务逻辑代码与测试代码分离**。其中业务逻辑都封装在页面类中。

根据这个设计思路,我们可将页面登录过程定义在登录页面类方法中。

在测试代码中,直接引用登录页面类中的登录方法,即可完成登录操作。

编写一个`page.py`模块,其中定义一个基类与登录页面类

~~~

#!/usr/bin/env python

# -*- coding: utf-8 -*-

from selenium.webdriver.common.by import By

from selenium.webdriver.support.wait import WebDriverWait

from selenium.webdriver.support import expected_conditions as EC

class BasePage(object):

""" 定义所有页面类的基类 """

def __init__(self, driver):

self.driver = driver

def get_source(self):

"""

获取页面源码

:return:

"""

return self.driver.page_source

def accept_alert(self):

"""

切换到alert窗口,并且点击确定

:return: 返回alert信息

"""

wait = WebDriverWait(self.driver, 10, 0.5)

wait.until(EC.alert_is_present())

alert = self.driver.switch_to.alert

return alert

class LoginPage(BasePage):

""" 登录页面类 """

# 定义第一个待测页面

url = "http://a.4399en.com/"

def login(self, user, pwd):

# 打开首页

self.driver.get(LoginPage.url)

# 点击右上角登录按钮打开登录窗口

self.driver.find_element_by_class_name("CNlogin").click()

# 输入用户名

wait = WebDriverWait(self.driver, 20, 0.5)

account = wait.until(EC.visibility_of_element_located((By.ID, "modify-account")))

account.clear()

account.send_keys(user)

# 输入密码

password = self.driver.find_element_by_id("modify-password")

password.clear()

password.send_keys(pwd)

# 点击登录按钮

self.driver.find_element_by_xpath("//input[@type='submit'][@value='Login']").click()

if __name__ == '__main__':

from selenium import webdriver

options = webdriver.ChromeOptions()

options.add_argument('User-Agent=Mozilla/5.0 (Linux; U; Android 4.0.2; en-us; Galaxy Nexus Build/ICL53F) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30')

driver = webdriver.Chrome(chrome_options=options)

login_page = LoginPage(driver)

login_page.login("gfc@qq.com", "123456")

~~~

主要关注`BasePage`和`LoginPage`这两个类的代码。`if __name__ == '__main__'`中的代码不是非必要的,主要是调试当前页面类的代码,不会在其他模块调用时运行。

## 重构测试代码

### 使用pytest测试框架来组织用例

> 如果你还不懂得如何使用pytest测试框架,请先阅读我的另外一本python入门书中的测试框架《[接口测试框架](https://www.kancloud.cn/guanfuchang/python_start/703690)》

下面直接演示我的例子:

首先,定义公共的fixture,新建一个fixture文件`conftest.py`:

~~~

#!/usr/bin/python

#coding=utf-8

from selenium import webdriver

import pytest

@pytest.fixture()

def get_driver():

# 创建Chrome驱动实例,这里创建driver时,传入chrome_options参数,告诉服务器,我是用移动端浏览器访问的。

options = webdriver.ChromeOptions()

options.add_argument('User-Agent=Mozilla/5.0 (Linux; U; Android 4.0.2; en-us; Galaxy Nexus Build/ICL53F) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30')

driver = webdriver.Chrome(chrome_options=options)

# 设置浏览器大小,让它看起来跟手机的样式差不多。

driver.set_window_size("380", "680")

# 设置一个全局的等待超时时间 10s

driver.implicitly_wait(10)

yield driver

driver.quit()

~~~

我为什么会将fixture抽离出来,放到公共文件中呢?那是因为考虑到一个项目,后续会有很多测试类,会在各个测试类中共用fixture。

下面以前面的登录测试类为例,新建一个测试文件`test_login.py`:

~~~

#!/usr/bin/python

#coding=utf-8

import pytest

from page import LoginPage

class TestLogin(object):

def test_login_succss(self, get_driver):

"""登录成功用例"""

login_page = LoginPage(get_driver)

login_page.login("gfc@qq.com","123456")

assert "gfc@qq.com" in login_page.get_source()

def test_login_fail(self, get_driver):

"""登录失败用例"""

login_page = LoginPage(get_driver)

login_page.login("gfc@123.com","123456")

alert = login_page.accept_alert()

assert "User does not exist!" in alert.text

if __name__ == '__main__':

pytest.main()

~~~

运行效果如

![](https://box.kancloud.cn/5f2d4e1b0bbe8546be0c58e9fbcb443c_936x772.gif)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值