已登录网站为例,运用页面-对象-模型(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