六、UI自动化测试06--PO设计模式

一、PO 设计模式

1. v1 版本

说明: 通过测试执⾏框架 pytest, 可以整合所有的同⼀模块的测试⽤例脚本, 并且需要尽⼒符合⼿⼯测试的操作业务逻辑, 最终实现执⾏单个测试脚本, 执⾏同⼀模块的所有测试⽤例

1.1 v1.1

  • 通过测试⽅法整合测试脚本
"""
整合多个脚本⾄同⼀个测试⽤例中
"""
import pytest
from time import sleep
from selenium import webdriver
 
 
class TestLogin(object):
	"""登录测试类"""
 
 	def test_account_does_not_exist(self):
 		"""账号不存在测试⽅法"""
 		driver = webdriver.Chrome()
 		driver.get('http://127.0.0.1/')
	 	driver.maximize_window() # 窗⼝最⼤化
 		driver.implicitly_wait(10) # 隐式等待
 
 		# 1. 点击⾸⻚的‘登录’链接,进⼊登录⻚⾯
 		driver.find_element_by_link_text('登录').click()
 
 		# 2. 输⼊⼀个不存在的⽤户名
 		driver.find_element_by_id('username').send_keys('13811110001')
 		# 3. 输⼊密码
 
 		driver.find_element_by_id('password').send_keys('123456')
 		# 4. 输⼊验证码
 
 		driver.find_element_by_id('verify_code').send_keys('8888')
 		# 5. 点击登录按钮
 		driver.find_element_by_name('sbtbutton').click()
 
 		# 6. 获取错误提示信息
 		# 获取元素⽂本值: 元素对象.text
 		msg = driver.find_element_by_class_name('layui-layercontent').text

		print('错误信息为:', msg)
 
 		sleep(3)
 		driver.quit()

 	def test_wrong_password(self):
 		"""密码错误测试⽅法"""
 		driver = webdriver.Chrome()
 		driver.get('http://127.0.0.1/')
 		driver.maximize_window() # 窗⼝最⼤化
 		driver.implicitly_wait(10) # 隐式等待
 
 		# 1. 点击⾸⻚的‘登录’链接,进⼊登录⻚⾯
 		driver.find_element_by_link_text('登录').click()
 
 		# 2. 输⼊⽤户名
 
 		driver.find_element_by_id('username').send_keys('13800001111')
 		# 3. 输⼊错误密码
 		driver.find_element_by_id('password').send_keys('error')
 		# 4. 输⼊验证码
 
 		driver.find_element_by_id('verify_code').send_keys('8888')
 		# 5. 点击登录按钮
 		driver.find_element_by_name('sbtbutton').click()
 
 		# 6. 获取错误提示信息
 		# 获取元素⽂本值: 元素对象.text
	 	msg = driver.find_element_by_class_name('layui-layer-content').text

		print('错误信息为:', msg)
 
 		sleep(3)
 		driver.quit()
 
 
if __name__ == '__main__':
 pytest.main(['-s', 'tpshop_login_1.py'])

1.2 v1.2

  • 通过 setup() 和 teardown() ⽅法优化多个脚本相同的前置后后置操作
"""
整合多个脚本⾄同⼀个测试⽤例中
"""
import pytest
from time import sleep
from selenium import webdriver
 
 
class TestLogin(object):
 """登录测试类"""
 
 def setup(self):
 self.driver = webdriver.Chrome()
 self.driver.get('http://127.0.0.1/')
 self.driver.maximize_window() # 窗⼝最⼤化
 self.driver.implicitly_wait(10) # 隐式等待
 
 def teardown(self):
 sleep(3)
 self.driver.quit()
 
 def test_account_does_not_exist(self):
 """账号不存在测试⽅法"""
 # driver = webdriver.Chrome()
 # driver.get('http://127.0.0.1/')
  # driver.maximize_window() # 窗⼝最⼤化
 # driver.implicitly_wait(10) # 隐式等待
 
 # 1. 点击⾸⻚的‘登录’链接,进⼊登录⻚⾯
 self.driver.find_element_by_link_text('登录').click()
 
 # 2. 输⼊⼀个不存在的⽤户名
 
 self.driver.find_element_by_id('username').send_keys('13811110001')
 # 3. 输⼊密码
 
 self.driver.find_element_by_id('password').send_keys('123456')
 # 4. 输⼊验证码
 
 self.driver.find_element_by_id('verify_code').send_keys('8888')
 # 5. 点击登录按钮
 self.driver.find_element_by_name('sbtbutton').click()
 
 # 6. 获取错误提示信息
 # 获取元素⽂本值: 元素对象.text
 sleep(2)
 msg = self.driver.find_element_by_class_name('layui-layer-content').text

print('错误信息为:', msg)
 
 # sleep(3)
 # driver.quit()
 
 def test_wrong_password(self):
 """密码错误测试⽅法"""
 # driver = webdriver.Chrome()
 # driver.get('http://127.0.0.1/')
 # driver.maximize_window() # 窗⼝最⼤化
 # driver.implicitly_wait(10) # 隐式等待
 
 # 1. 点击⾸⻚的‘登录’链接,进⼊登录⻚⾯
 self.driver.find_element_by_link_text('登录').click()
 
 # 2. 输⼊⽤户名
 
 self.driver.find_element_by_id('username').send_keys('138000011
11')
 # 3. 输⼊错误密码
 
 self.driver.find_element_by_id('password').send_keys('error')
 # 4. 输⼊验证码
 
 self.driver.find_element_by_id('verify_code').send_keys('8888')
 # 5. 点击登录按钮
 self.driver.find_element_by_name('sbtbutton').click()
 
 # 6. 获取错误提示信息
 # 获取元素⽂本值: 元素对象.text
 sleep(2)
 msg = self.driver.find_element_by_class_name('layuilayer-content').text

print('错误信息为:', msg)
 
 # sleep(3)
 # driver.quit()
 
 
if __name__ == '__main__':
 pytest.main(['-s', 'tpshop_login_2.py'])

2. v2 版本

  • 通过 setup_class() 和 teardown_class() ⽅法使脚本的执⾏逻辑跟符合⼿⼯测试逻辑
"""
整合多个脚本⾄同⼀个测试⽤例中
"""
import pytest
from time import sleep
from selenium import webdriver
 
 
class TestLogin(object):
 """登录测试类"""
 
 def setup_class(self):
 self.driver = webdriver.Chrome()
 self.driver.get('http://127.0.0.1/')
 self.driver.maximize_window() # 窗⼝最⼤化
 self.driver.implicitly_wait(10) # 隐式等待
 
 def teardown_class(self):
 sleep(3)
 self.driver.quit()
 
 def setup(self):
 # self.driver = webdriver.Chrome()
 # self.driver.get('http://127.0.0.1/')
 # self.driver.maximize_window() # 窗⼝最⼤化
 # self.driver.implicitly_wait(10) # 隐式等待
 # 打开⾸⻚
 self.driver.get('http://127.0.0.1/')
 # 点击登录
 self.driver.find_element_by_link_text('登录').click()
 
 def teardown(self):
 # sleep(3)
 # self.driver.quit()
 pass
 
 def test_account_does_not_exist(self):
 """账号不存在测试⽅法"""
 
 # 1. 点击⾸⻚的‘登录’链接,进⼊登录⻚⾯
 # self.driver.find_element_by_link_text('登录').click()
 
 # 2. 输⼊⼀个不存在的⽤户名
 
 self.driver.find_element_by_id('username').send_keys('13811110001')
 # 3. 输⼊密码
 
 self.driver.find_element_by_id('password').send_keys('123456')
 # 4. 输⼊验证码
 
 self.driver.find_element_by_id('verify_code').send_keys('8888')
 # 5. 点击登录按钮
 self.driver.find_element_by_name('sbtbutton').click()
 
 # 6. 获取错误提示信息
 # 获取元素⽂本值: 元素对象.text
 sleep(2)
 msg = self.driver.find_element_by_class_name('layui-layer-content').text
  print('错误信息为:', msg)
 
 def test_wrong_password(self):
 """密码错误测试⽅法"""
 
 # 1. 点击⾸⻚的‘登录’链接,进⼊登录⻚⾯
 # self.driver.find_element_by_link_text('登录').click()
 
 # 2. 输⼊⽤户名
 
 self.driver.find_element_by_id('username').send_keys('13800001111')
 # 3. 输⼊错误密码
 
 self.driver.find_element_by_id('password').send_keys('error')
 # 4. 输⼊验证码
 
 self.driver.find_element_by_id('verify_code').send_keys('8888')
 # 5. 点击登录按钮
 self.driver.find_element_by_name('sbtbutton').click()
 
 # 6. 获取错误提示信息
 # 获取元素⽂本值: 元素对象.text
 sleep(2)
 msg = self.driver.find_element_by_class_name('layui-layer-content').text

print('错误信息为:', msg)
 
 
if __name__ == '__main__':
 pytest.main(['-s', 'tpshop_login_3.py'])

3. ⽅法封装套路

    1. 确定⽅法的存放位置: 找位置
    1. 给⽅法起个合适名字: 起名字
    1. 放⼊要封装的代码内容: 放代码
    1. 确认是否需要参数和返回值: 确必要
    1. 调⽤封装好的⽅法使⽤: 做调⽤

4. v3 版本

4.1 浏览器对象管理类的实现

"""
公共⽅法模块: 习惯命名 utils
"""
from selenium import webdriver
from time import sleep
 
 
class DriverUtil(object):
 """浏览器对象管理类"""
 driver = None # 浏览器对象变量初始化状态
 
 def get_driver(self):
 """获取浏览器对象⽅法"""
 # 说明: 为了防⽌在同⼀次测试过程中, 调⽤获取浏览器对象⽅法时,
 # 都会创建⼀个新的浏览器对象, 因此有必要先判断对象是否存在, 
不存在时在创建!
 if self.driver is None:
 self.driver = webdriver.Chrome()
 self.driver.get('http://127.0.0.1/')
 self.driver.maximize_window() # 窗⼝最⼤化
 self.driver.implicitly_wait(10) # 隐式等待
 return self.driver
 
 def quit_driver(self):
 """退出浏览器对象⽅法"""
 # 说明: 必须保证浏览器对象存在, 才能执⾏退出操作
 if self.driver: # 等价于: if self.driver is not None:
 sleep(3)
 self.driver.quit()
 self.driver = None # 保险⼿段: 移除对象后, 保留对象变量, 以备下⼀次使⽤
 
 
if __name__ == '__main__':
 my_driver = DriverUtil()
 my_driver.get_driver()
 sleep(2)
 my_driver.quit_driver()

4.2 浏览器对象管理类的优化

"""
公共⽅法模块: 习惯命名 utils
"""
from selenium import webdriver
from time import sleep
 
 
class DriverUtil(object):
 """浏览器对象管理类"""
 # 说明: 对象变量只需要在类定义内部使⽤, 因此定义为私有
 __driver = None # 浏览器对象变量初始化状态
 
 @classmethod
 def get_driver(cls):
 """获取浏览器对象⽅法"""
 # 说明: 为了防⽌在同⼀次测试过程中, 调⽤获取浏览器对象⽅法时,
 # 都会创建⼀个新的浏览器对象, 因此有必要先判断对象是否存在, 不存在时在创建!
 if cls.__driver is None:
 cls.__driver = webdriver.Chrome()
 cls.__driver.get('http://127.0.0.1/')
 cls.__driver.maximize_window() # 窗⼝最⼤化
 cls.__driver.implicitly_wait(10) # 隐式等待
 return cls.__driver
 
 @classmethod
 def quit_driver(cls):
 """退出浏览器对象⽅法"""
 # 说明: 必须保证浏览器对象存在, 才能执⾏退出操作
 if cls.__driver: # 等价于: if self.driver is not None:
 sleep(3)
 cls.__driver.quit()
 cls.__driver = None # 保险⼿段: 移除对象后, 保留对象变量, 以备下⼀次使⽤
 
 
if __name__ == '__main__':
 # my_driver = DriverUtil()
 # my_driver.get_driver()
 # sleep(2)
 # my_driver.quit_driver()
 # 说明: 定义为类⽅法, 可以直接由类对象调⽤, 省略实例化对象步骤
 DriverUtil.get_driver() # 获取浏览器对象
 sleep(2)
 DriverUtil.quit_driver() # 退出浏览器对象

4.3 浏览器对象管理类的使⽤

"""
整合多个脚本⾄同⼀个测试⽤例中
"""
import pytest
from time import sleep
from selenium import webdriver
 
from utils import DriverUtil
 
 
class TestLogin(object):
 """登录测试类"""
 
 def setup_class(self):
 # self.driver = webdriver.Chrome()
 # self.driver.get('http://127.0.0.1/')
 # self.driver.maximize_window() # 窗⼝最⼤化
 # self.driver.implicitly_wait(10) # 隐式等待
 self.driver = DriverUtil.get_driver() # 获取浏览器对象
 
 def teardown_class(self):
 # sleep(3)
 # self.driver.quit()
 DriverUtil.quit_driver() # 退出浏览器对象
 def setup(self):
 # 打开⾸⻚
 self.driver.get('http://127.0.0.1/')
 # 点击登录
 self.driver.find_element_by_link_text('登录').click()
 
 def teardown(self):
 pass
 
 def test_account_does_not_exist(self):
 """账号不存在测试⽅法"""
 
 # 2. 输⼊⼀个不存在的⽤户名
 
 self.driver.find_element_by_id('username').send_keys('13811110001')
 # 3. 输⼊密码
 
 self.driver.find_element_by_id('password').send_keys('123456')
 # 4. 输⼊验证码
 
 self.driver.find_element_by_id('verify_code').send_keys('8888')
 # 5. 点击登录按钮
 self.driver.find_element_by_name('sbtbutton').click()
 
 # 6. 获取错误提示信息
 # 获取元素⽂本值: 元素对象.text
 sleep(2)
 msg = self.driver.find_element_by_class_name('layui-layer-content').text

print('错误信息为:', msg)
 
 def test_wrong_password(self):
  """密码错误测试⽅法"""
 
 # 2. 输⼊⽤户名
 
 self.driver.find_element_by_id('username').send_keys('13800001111')
 # 3. 输⼊错误密码
 
 self.driver.find_element_by_id('password').send_keys('error')
 # 4. 输⼊验证码
 
 self.driver.find_element_by_id('verify_code').send_keys('8888')
 # 5. 点击登录按钮
 self.driver.find_element_by_name('sbtbutton').click()
 
 # 6. 获取错误提示信息
 # 获取元素⽂本值: 元素对象.text
 sleep(2)
 msg = self.driver.find_element_by_class_name('layui-layer-content').text

print('错误信息为:', msg)
 
 
if __name__ == '__main__':
 pytest.main(['-s', 'tpshop_login_3.py'])

4.4 获取弹窗信息⽅法的封装

from selenium import webdriver
from time import sleep
 
 
def get_alert_msg():
 """获取弹窗信息⽅法"""
 sleep(2)
 # msg = self.driver.find_element_by_class_name('layui-layercontent').text

# msg = driver.find_element_by_class_name('layui-layercontent').text

msg = 
DriverUtil.get_driver().find_element_by_class_name('layui-layer-content').text

return msg
 
 
class DriverUtil(object):
 """浏览器对象管理类"""
 __driver = None # 浏览器对象变量初始化状态
 
 @classmethod
 def get_driver(cls):
 """获取浏览器对象⽅法"""
 if cls.__driver is None:
 cls.__driver = webdriver.Chrome() # 浏览器类型
 cls.__driver.get('http://127.0.0.1/') # 项⽬地址
 cls.__driver.maximize_window() # 窗⼝最⼤化
 cls.__driver.implicitly_wait(10) # 隐式等待
 return cls.__driver
 
 @classmethod
 def quit_driver(cls):
 """退出浏览器对象⽅法"""
 if cls.__driver:
 sleep(3)
 cls.__driver.quit()
 cls.__driver = None
 
 
if __name__ == '__main__':
 DriverUtil.get_driver() # 获取浏览器对象
 sleep(2)
 DriverUtil.quit_driver() # 退出浏览器对象

5. PO 设计模式

  • 说明: PO 模式⼜可以叫 POM(P:Page O:Object), 是 UI ⾃动化测试中⼀个⾮常流⾏的设计模式(代码套路)

  • 核⼼: 将元素定位及操作和业务逻辑, 拆分三个层⾯(每个层⾯对应⼀个单独的类), 然后通过调⽤完成最终的测试执⾏⾏为的过程

  • 三个层⾯: 对象库层/操作层/业务层

在这里插入图片描述

6. v4 版本

6.1 PO⻚⾯元素封装步骤

    1. 对应⻚⾯创建⻚⾯ PO 代码⽂件, 命名规则: ⻚⾯功能_page.py, 例如⾸⻚: index_page.py
    1. 定义三个类: 对象层(XxxPage)/操作层(XxxHandle)/业务层(XxxTask)
    1. 对象层:
    • 1> init ⽅法中获取浏览器对象
    • 2> ⾃定义⽅法: 封装元素定位⽅法
    • 3> 封装元素定位⽅法需要添加返回值!
    1. 操作层:
    • 1> init ⽅法获取对象层对象, 根据类名写对象变量名
    • 2> ⾃定义⽅法: 封装元素操作⽅法
    1. 业务层:
    • 1> init ⽅法获取操作层对象, 根据类名写对象变量名
    • 2> ⾃定义⽅法: 封装测试业务逻辑
    1. 在测试⽤例⽂件中, 实例化业务层对象, 调⽤测试业务⽅法, 执⾏测试

代码示例: ⾸⻚⻚⾯

"""
⾸⻚⻚⾯
"""
from utils import DriverUtil
 
 
class IndexPage(object):
 """⾸⻚对象层"""
 
 def __init__(self):
 self.driver = DriverUtil.get_driver() # 获取浏览器对象
 
 def find_login(self):
 """定位登录⽅法"""
 # self.driver.find_element_by_link_text('登录')
 # self.driver = DriverUtil.get_driver() # 获取浏览器对象
 return self.driver.find_element_by_link_text('登录')
 
 
class IndexHandle(object):
 """⾸⻚操作层"""
 
 def __init__(self):
 self.index_page = IndexPage() # 获取对象层对象
 
 def click_login(self):
 """点击登录⽅法"""
 # element = IndexPage()
 # element.find_login().click()
 self.index_page.find_login().click()
 
 
class IndexTask(object):
 """⾸⻚业务层"""
 
 def __init__(self):
 self.index_handle = IndexHandle() # 获取操作层对象
 
 def go_to_login(self):
 """跳转登录⻚⾯⽅法"""
 self.index_handle.click_login()

代码示例: 登录⻚⾯

"""
登录⻚⾯
"""
from utils import DriverUtil
 
 
class LoginPage(object):
 """登录对象层"""
 
 def __init__(self):
 self.driver = DriverUtil.get_driver() # 获取浏览器对象
 
 def find_username(self):
 """定位⽤户名⽅法"""
 return self.driver.find_element_by_id('username')
 
 def find_password(self):
 """定位密码⽅法"""
 return self.driver.find_element_by_id('password')
 
 def find_verify_code(self):
 """定位验证码⽅法"""
 return self.driver.find_element_by_id('verify_code')
 
 def find_login_btn(self):
 """定位登录按钮⽅法"""
 return self.driver.find_element_by_name('sbtbutton')
 
 
class LoginHandle(object):
 """登录操作层"""
 def __init__(self):
 self.login_page = LoginPage() # 获取对象层对象
 
 def input_username(self, name):
 """输⼊⽤户名⽅法"""
 self.login_page.find_username().send_keys(name)
 
 def input_password(self, pwd):
 """输⼊密码⽅法"""
 self.login_page.find_password().send_keys(pwd)
 
 def input_verify_code(self, code):
 """输⼊验证码⽅法"""
 self.login_page.find_verify_code().send_keys(code)
 
 def click_login_btn(self):
 """点击登录按钮⽅法"""
 self.login_page.find_login_btn().click()
 
 
class LoginTask(object):
 """登录业务层"""
 
 def __init__(self):
 self.login_handle = LoginHandle() # 获取操作层对象
 
 def login_method(self, name, pwd, code):
 """登录⽅法"""
 self.login_handle.input_username(name) # 输⼊⽤户名
 self.login_handle.input_password(pwd) # 输⼊密码
 self.login_handle.input_verify_code(code) # 输⼊验证码
 self.login_handle.click_login_btn() # 点击登录按钮

6.2 测试⽤例的最终代码样式

"""
整合多个脚本⾄同⼀个测试⽤例中
"""
import pytest
from utils import DriverUtil, get_alert_msg
from v4.index_page import IndexTask
from v4.login_page import LoginTask
 
 
class TestLogin(object):
 """登录测试类"""
 
 def setup_class(self):
 self.driver = DriverUtil.get_driver() # 获取浏览器对象
 self.index_task = IndexTask() # 实例化⾸⻚业务层对象
 self.login_task = LoginTask() # 实例化登录⻚⾯业务层对象
 
 def teardown_class(self):
 DriverUtil.quit_driver() # 退出浏览器对象
 
 def setup(self):
 # 打开⾸⻚
 self.driver.get('http://127.0.0.1/')
 # 点击登录
 # self.driver.find_element_by_link_text('登录').click()
 self.index_task.go_to_login() # 跳转登录
 
 def teardown(self):
 pass
 
 def test_account_does_not_exist(self):
 """账号不存在测试⽅法"""
 
 # # 2. 输⼊⼀个不存在的⽤户名
 # 
self.driver.find_element_by_id('username').send_keys('13811110001')
 # # 3. 输⼊密码
 # 
self.driver.find_element_by_id('password').send_keys('123456')
 # # 4. 输⼊验证码
 # 
self.driver.find_element_by_id('verify_code').send_keys('8888')
 # # 5. 点击登录按钮
 # self.driver.find_element_by_name('sbtbutton').click()
 self.login_task.login_method('13811110001', '123456', '8888')
 
 # 6. 获取错误提示信息
 msg = get_alert_msg() # 获取弹窗信息
 print('错误信息为:', msg)
 
 def test_wrong_password(self):
 """密码错误测试⽅法"""
 
 # # 2. 输⼊⽤户名
 # 
self.driver.find_element_by_id('username').send_keys('13800001111')
 # # 3. 输⼊错误密码
  #self.driver.find_element_by_id('password').send_keys('error')
 # # 4. 输⼊验证码
 # 
self.driver.find_element_by_id('verify_code').send_keys('8888')
 # # 5. 点击登录按钮
 # self.driver.find_element_by_name('sbtbutton').click()
 self.login_task.login_method('13800001111', 'error', '8888')
 
 # 6. 获取错误提示信息
 msg = get_alert_msg() # 获取弹窗信息
 print('错误信息为:', msg)
 
 
if __name__ == '__main__':
 pytest.main(['-s', 'tpshop_login.py'])

7. v5 版本

7.1 PO ⽂件对象层代码优化

class LoginPage(object):
 """登录对象层"""
 
 def __init__(self):
 self.driver = DriverUtil.get_driver() # 获取浏览器对象
 # 说明: 将元素的定位⽅法及特征值封装成属性, 能够实现集中管理⽬标元素的定位⽅法及特征值
 self.name = (By.ID, 'username') # ⽤户名
 self.pwd = (By.ID, 'password') # 密码
 self.code = (By.ID, 'verify_code') # 验证码
 self.btn = (By.NAME, 'sbtbutton') # 登录按钮
 
 def find_username(self):
 """定位⽤户名⽅法"""
 # return self.driver.find_element_by_id('username')
 # return self.driver.find_element(By.ID, 'username')
 return self.driver.find_element(self.name[0], self.name[1])
 
 def find_password(self):
 """定位密码⽅法"""
 # return self.driver.find_element_by_id('password')
 return self.driver.find_element(self.pwd[0], self.pwd[1])
 
 def find_verify_code(self):
 """定位验证码⽅法"""
 # return self.driver.find_element_by_id('verify_code')
 return self.driver.find_element(self.code[0], self.code[1])
 
 def find_login_btn(self):
 """定位登录按钮⽅法"""
 # return self.driver.find_element_by_name('sbtbutton')
 return self.driver.find_element(self.btn[0], self.btn[1])

7.2 PO ⽂件操作层代码优化

class LoginHandle(object):
 """登录操作层"""
 
 def __init__(self):
 self.login_page = LoginPage() # 获取对象层对象
 
 def input_username(self, name):
 """输⼊⽤户名⽅法"""
 # 说明: 在执⾏输⼊操作前, 应该先执⾏清空操作
 self.login_page.find_username().clear()
 self.login_page.find_username().send_keys(name)
 
 def input_password(self, pwd):
 """输⼊密码⽅法"""
 self.login_page.find_password().clear()
 self.login_page.find_password().send_keys(pwd)
 
 def input_verify_code(self, code):
 """输⼊验证码⽅法"""
 self.login_page.find_verify_code().clear()
 self.login_page.find_verify_code().send_keys(code)
 
 def click_login_btn(self):
 """点击登录按钮⽅法"""
 self.login_page.find_login_btn().click()
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值