已登录网站为例,运用页面-对象-模型(POM)实现用户登录。
以下开始介绍具体设计过程。
1.1设计基类,提高项目的代码重用性。设计基类主要是因为在元素定位的方法都很类似,所以设计基础类让其他的方法来继承这个类来实现代码的重用
#设置基类,很多事件都是重复的比如点击,文本输入。所以写下这个基类
class BasePage(object):
# 初始化方法
def __init__(self, driver):
# 传参driver,就不需要在导入驱动了
self.driver = driver
# 根据*loc(*代表可变参,一定是最后一个参数否则会报错)查找元素
def find_element(self, *loc):
return self.driver.find_element(*loc)
# 向某个元素输入内容text
def type_text(self, text, *loc):
self.find_element(*loc).send_keys(text)
# 对某个元素操作点击事件
def click(self, *loc):
print("----------", self.driver)
self.find_element(*loc).click()
# 清空某个元素内容
def clear(self, *loc):
self.find_element(*loc).clear()
# 获取页面的title
def get_title(self):
return self.driver.title
1.2设置项目页面对应的PO类
# POM 页面-对象-模型
from selenium.webdriver.common.by import By
from time import sleep
from testcases.pom_test.Pages.basePage import BasePage
class UserLoginPage(BasePage):
# 首先声明定位器
language = (By.XPATH, "//*[@id='app']/div[1]/div[2]/div/div/div/div[1]")
chinese = (By.XPATH, "//*[@id='app']/div[1]/div[2]/div/div/div/div[2]/ul/li[2]/div")
username_input = (By.XPATH, '/html/body/div/div[1]/div[2]/div/form/div[1]/div/div/input')
pwd_input = (By.XPATH, '/html/body/div/div[1]/div[2]/div/form/div[2]/div/div/input')
captcha_input = (By.XPATH, '/html/body/div/div[1]/div[2]/div/form/div[3]/div/div/input')
login_btn = (By.XPATH, "//*[@id='app']/div[1]/div[2]/div/button")
# 初始化方法传参driver驱动
def __init__(self, driver):
BasePage.__init__(self, driver)
# 得到登录的页面
def goto_login_page(self):
self.driver.get('http://*****.com/')
# self.driver.get('http://*****com/')
self.driver.maximize_window()
# 选择登录的语言
def choose_language(self):
self.click(*self.language)
def goto_chinese(self):
self.click(*self.chinese)
# 输入用户名并调用基类方法进行实现
def input_username(self, username):
self.clear(*self.username_input)
self.type_text(username, *self.username_input)
# 清空密码/输入密码
def input_pwd(self, password):
self.clear(*self.pwd_input)
self.type_text(password, *self.pwd_input)
# 输入验证码
def input_captcha(self, captcha):
self.clear(*self.captcha_input)
self.type_text(captcha, *self.captcha_input)
# 点击登录按钮
def click_login_btn(self):
self.click(*self.login_btn)
sleep(3)
1.3 测试用例设计
from selenium import webdriver
from time import sleep
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from testcases.pom_test.Pages.UserLoginPage import UserLoginPage
from util import verification_code
import pytest
class TestLogin(object):
# 只在类中运行前运行一次
def setup_class(self):
# self.driver = webdriver.Chrome(ChromeDriverManager().install())
self.driver = webdriver.Chrome()
print("***********执行到这里", self.driver)
# 调用UserLoginPage方法
self.login_page = UserLoginPage(self.driver)
# 打开网页链接,通过调用封装好的goto_login_page()来实现
self.login_page.goto_login_page()
# 断言模块
# self.logger = log_util.get_logger()
# 将登录页面选择为中文模式
sleep(3)
self.login_page.choose_language()
sleep(3)
self.login_page.goto_chinese()
login_data = [
('123', '1234', '5555', '验证码错误'),
('123', '1234', '6666', 'http://*****.com/#/homePage'),
]
@pytest.mark.flaky(reruns=1, reruns_delay=2)
@pytest.mark.dependency(name='admin_login')
@pytest.mark.parametrize('username,password,captcha,expect', login_data)
def test_login_ok(self, username, password, captcha, expect):
sleep(3)
self.login_page.input_username(username)
self.login_page.input_pwd(password)
if captcha != '6666':
self.login_page.input_captcha(captcha)
sleep(3)
# 点击登录
self.login_page.click_login_btn()
# 断言
WebDriverWait(self.driver, 5).until(EC.visibility_of_element_located((By.XPATH, "/html/body/div[2]")))
actual = self.driver.find_element(By.XPATH, "/html/body/div[2]").text
print(actual)
assert expect == actual
else:
# 调用方法获取正确的验证码
captcha = verification_code.verification(self.driver,
"//*[@id='app']/div[1]/div[2]/div/form/div[3]/div/img")
self.login_page.input_captcha(captcha)
sleep(3)
# 点击登录
self.login_page.click_login_btn()
# 断言
sleep(3)
assert expect == self.driver.current_url
print(self.driver.current_url)
3.由于我们的用例于用例之间可能会存在依赖关系,例如登录后的页面操作,都需要依赖登录。我们就可以通过以下方式来实现
# 在登录方法上设置依赖名
@pytest.mark.dependency(name='admin_login')
def login():
pass
# 需要依赖登录的方法
@pytest.mark.dependency(depends=["admin_login"], scope="module")
def add():
pass
import os
import time
import pytesseract
from PIL import Image
from selenium import webdriver
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
def verification(browser, xpath):
time.sleep(2)
# 获取当前时间作为存储图片的名字
t = time.time()
# 获取当前项目路径
path = os.path.dirname(os.path.dirname(__file__)) + "\\screenshots"
# 获取验证码图片,设置存放位置
pic_name1 = path + '\\' + str(t) + '.png'
browser.save_screenshot(pic_name1)
# 定位到验证码的位置
ce = browser.find_element(By.XPATH, xpath)
# 打印位置
print(ce.location)
# 设置需要截取的范围
left = ce.location['x']
top = ce.location['y']
right = ce.size['width'] + left
height = ce.size['height'] + top
im = Image.open(pic_name1) # 打开已经保存的图片
img = im.crop((left, top, right, height))
t = time.time()
pic_name2 = path + '\\' + str(t) + '.png'
img.save(pic_name2)
# login().driver.close()
# 读取截取到的图片中的文字
image = Image.open(pic_name2)
s = pytesseract.image_to_string(image).replace(" ", "")
# 读取出来的验证码有空格,所以我在这里去空格了
print(s)
return s