首先仍旧先来介绍目录结构,见表1所示。
表1 Playwright语句的封装目录结构
目录 | 文件 | 含义 |
|---|---|---|
basepage | 基础操作目录 | |
base.py | 封装基本操作 | |
db.py | 封装数据库操作 | |
page.py | 封装Playwright的page对象 | |
data | 测试数据目录 | |
data.yaml | 数据yaml文件 | |
data.py | 封装对data.yaml数据的获取操作 | |
pageobject | 页面封装和业务封装目录 | |
flowobject.py | 封装业务操作 | |
pageobject.py | 封装页面操作 | |
test | 测试目录 | |
test.py | 封装测试 | |
basepage目录封装基础操作,包括base.py、db.py和page.py
base.py对Playwright专门做了调整,包括base、judge、WaitUtils和myexception四个类。分别封装定位操作元素、断言、等待和异常方法。
函数说明
PlayWright的定位操作方法比Selenium丰富,但常用的也不多,对常用的定位操作方法进行封装,包括下面几个方法。
•find_element_by_label(page,label_str):通过label查找元素。
•find_element_by_text(page,text_str):通过text查找元素。
•find_element_by_string(page,string):通过location查找元素。
•find_element_by_xpath(page,xpath):通过xpath表达式查找元素。
•find_element_by_id(page,id):通过id查找元素。
•find_element_by_input_name(page,name):通过input/name查找元素。
•find_element_by_type_value(page,mytype,value):通过type和value查找元素。
•find_element_by_name_value(page,name,value):通过name和value查找元素。
•find_element_by_name(page,name):通过name查找元素。
•find_element_by_classname(page,classname):通过classname查找元素。
•find_element_by_role(page,role,value):通过role查找元素。
•find_element_by_placeholder(page,string):通过placeholder查找元素。
•get_text_value(page,mytype):获得input值。
•fill(element,str):输入,每次输入都需要清除元素。
•save_cookies(page):保存Cookies和Local Storage到文件。
•load_cookies(page,url):从文件恢复Cookies和Local Storage。
•execute_js_script(page,script):执行JavaScript语句。
代码如下。
base.py
import pickle,re
from playwright.sync_api import expect
class base:
@staticmethod
def find_element_by_label(page,label_str):
"""通过label查找元素"""
return page.get_by_label(label_str)
@staticmethod
def find_element_by_text(page,text_str):
"""通过text查找元素"""
return page.get_by_text(text_str)
@staticmethod
def find_element_by_string(page,string):
"""通过location查找元素"""
return page.locator(string)
@staticmethod
def find_element_by_xpath(page,xpath):
"""通过表达式查找元素"""
return page.locator("xpath="+xpath)
@staticmethod
def find_element_by_id(page,id):
"""通过id查找元素"""
return page.locator("#"+id)
@staticmethod
def find_element_by_input_name(page,name):
"""通过input/name查找元素"""
return page.locator("input[name="+name+"]")
@staticmethod
def find_element_by_type_value(page,mytype,value):
"""通过type和value查找元素"""
return page.locator('input[type="'+mytype+'"][value="'+value+'"]')
@staticmethod
def find_element_by_name_value(page,name,value):
"""通过name和value查找元素"""
return page.locator('input[name="'+name+'"][value="'+value+'"]')
@staticmethod
def find_element_by_name(page,name):
"""通过name查找元素"""
return page.locator('input[name="'+name+'"]')
@staticmethod
def find_element_by_classname(page,classname):
"""通过classname查找元素"""
return page.locator(".="+classname)
@staticmethod
def find_element_by_role(page,role,value):
"""通过role查找元素"""
return page.get_by_role(role,name=value)
@staticmethod
def find_element_by_placeholder(page,string):
"""通过placeholder查找元素"""
return page.get_by_placeholder(string)
@staticmethod
def get_text_value(page,mytype):
"""获得input值"""
return page.input_value('input[type='+mytype+']')
@staticmethod
def fill(element,str):
"""输入,每次输入都需要清除元素"""
element.fill("")
element.fill(str)
@staticmethod
def save_cookies(page):
"""保存 Cookies 和 Local Storage 到文件"""
cookies=page.context.cookies()#1. 保存 Cookies
with open("cookies.pkl","wb") as f:
pickle.dump(cookies,f)
#2. 保存 Local Storage
localStorage=page.evaluate("()=>JSON.stringify(window.localStorage)")
with open("localstorage.pkl","wb") as f:
pickle.dump(localStorage,f)
@staticmethod
def load_cookies(page,url):
"""从文件恢复 Cookies 和 Local Storage"""
try:
with open("cookies.pkl","rb") as f: #1. 加载 Cookies
cookies=pickle.load(f)
page.context.add_cookies(cookies)
with open("localstorage.pkl","rb") as f: #2. 加载 Local Storage
localStorageStr=pickle.load(f)
script=f"""
(function(storage){{
try {{
const entries=JSON.parse(storage);
for (const [key,value] of Object.entries(entries)){{
window.localStorage.setItem(key,value);
}}
}} catch(e){{
console.error('LocalStorage 恢复失败:',e);
}}
}})({localStorageStr});
"""
page.evaluate(script)
page.goto(url) #3. 刷新页面使状态生效
page.reload()
page.goto("http://127.0.0.1:8000/goods_view/")
except Exception as e:
myexception.my_exception(page,f"状态恢复失败:{str(e)}","error_page.png")
@staticmethod
def execute_js_script(page,script):
"""执行JavaScript程序"""
return page.evaluate(script)•judge_link_in_td_exists(page,string,lable):使用CSS选择器查找所有<td>下的<a>标签。
•judge_by_xpath(page,string):通过xpath判断元素是否存在。
•judge_by_text(page,field,text):通过页面是否含有text判断。
•judge_by_part_text(page,field,text):通过页面是否部分含有text判断。
•judge_element_is_visible(page,field):通过元素是否可见。
•judge_type_value(page,mytype,values):断言type的值为values。
base.py
class judge:
@staticmethod
def judge_link_in_td_exists(page,string,lable):
"""使用 CSS 选择器查找所有 <td> 下的 <a> 标签"""
elements=page.query_selector_all("td a")
found=False
for el in elements:
text=el.text_content().strip()
href=el.get_attribute("href")
if text==lable and re.match(string,href):
found=True
break
return found
@staticmethod
def judge_by_xpath(page,string):
"""通过xpath判断元素是否存在"""
element=base.find_element_by_xpath(page,string)
assert element.count()>0,"没有找到xpath="+string
@staticmethod
def judge_by_text(page,field,text):
"""通过页面是否含有text判断"""
assert page.text_content(field)==text
@staticmethod
def judge_by_part_text(page,field,text):
"""通过页面是否部分含有text判断"""
all_text=page.text_content(field)
if text in all_text:
assert 1==1
else:
assert 0==1
@staticmethod
def judge_element_is_visible(page,field):
"""通过元素是否可见"""
element=page.locator(field)
is_visible=element.is_visible()
assert is_visible,field+"元素不可见"
@staticmethod
def judge_type_value(page,mytype,values):
"""断言type的值为value"""
i=0
for value in(values):
expect(page.locator('input[type="'+mytype+'"]').nth(i)).to_have_value(value)
i+=1base.py
class WaitUtils:
@staticmethod
def wait_for_selector(page,sign,state="attached"):
"""等待元素状态(默认attached)"""
page.wait_for_selector(sign,state=state)base.py
class myexception:
def my_exception(page,info,image):
print(info)
page.screenshot(path=image)db.py封装对数据库的操作,对于selenium基本没有发生变化,用于tearDown()清理数据库操作。
import pymysql
import sys
sys.path.append("../data")
from data import Config
class ClassDB:
def connect_db(self):
"""连接数据库"""
host='localhost'
user='root'
password='123456'
database='ebusiness'
return pymysql.connect(host=host,user=user,password=password,database=database,charset='utf8')
def close_db(self,conn):
"""关闭数据库"""
try:
conn.close()
except MySQLError as e:
print(f"数据库关闭失败:{e}")
def init_db(self,conn):
"""测试初始化"""
config=Config('default')
self.execute_query("DELETE FROM goods_order ORDER BY id DESC LIMIT 1",conn)
self.execute_query("DELETE FROM goods_orders ORDER BY id DESC LIMIT 1",conn)
self.execute_query("DELETE FROM goods_address WHERE address='"+config.address+"'",conn)
self.execute_query("DELETE FROM goods_user WHERE username='"+config.username+"'",conn)
def execute_query(self,query,conn,params=None):
"""执行SQL语句"""
with conn.cursor() as cursor:
cursor.execute(query,params)
conn.commit()
return cursor.fetchall()
def finsh_test(self):
"""结束测试"""
connection=self.connect_db()
self.init_db(connection)
self.close_db(connection)page.py作用类似于selenium中的driver.py。
import sys
sys.path.append("../data")
from playwright.sync_api import sync_playwright
class mypages:
def __init__(self,config):
self.config=config
browser=self.config.browser
headless=self.config.headless
self.playwright=sync_playwright().start()
if browser.lower()=="chrome":
self.browser=self.playwright.chromium.launch(headless=headless)
if browser.lower()=="firefox":
self.browser=self.playwright.firefox.launch(headless=headless)
if browser.lower()=="webkit":
self.browser=self.playwright.WebKit.launch(headless=headless)
if browser.lower()=="edge":
self.browser=self.playwright.chromium.launch(channel="msedge")
self.page=self.browser.new_page()
headless的值取值与data目录中的data.yaml中,表示是否已有头还是无头方式启动:headless=False表示有头,headless=True表示无头。environments:
default:
browser:"chrome"#以什么浏览器运行chrome、firfox、edge
url:"http://127.0.0.1:8000"#首页URL
headless:False#有头还是无头方式运行,headless=False表示有头,headless=True表示无头
username:"xixi"#用户名
password:"654321"#密码
repassword:"123456"#重置密码
email:"a@b.com"#Email
address:"首体南路1号"#配货地址
phone:"15434564455"#配货电话
number:"3"#选择商品数量data.py对于data.yaml中的每个字段定义一个读取的方法。
data.py
import yaml
import os
class TestConfig:
def __init__(self,env='default'):
current_dir=os.path.dirname(os.path.abspath(__file__))
config_path=os.path.join(current_dir,'data.yaml')
with open(config_path,'r',encoding='utf-8')as f:
data=yaml.safe_load(f)
self.config=data['environments'][env]
@property
def browser(self):
return self.config['browser']
@property
def url(self):
return self.config['url']
@property
def headless(self):
return self.config['headless']
@property
def username(self):
return self.config['username']
@property
def password(self):
return self.config['password']
@property
def email(self):
return self.config['email']
@property
def address(self):
return self.config['address']
@property
def phone(self):
return self.config['phone']
@property
def repassword(self):
return self.config['repassword']
@property
def number(self):
return self.config['number']pageobject.py封装页面操作,在flowobject.py中采用XXXPage.XXXAction()的操作形式。包括。
•class login_page:登录类。
•class register_page:注册类。
•class goods_list_page:商品列表页类。
•class goods_detail_page:商品详情页类。
•class chart_page:购物车页类。
•class order_page:订单页类。
•class user_info_page:用户信息页类。
•class add_address_page:添加收货地址页类。
•class reset_password_page:重置密码页类。
每个类包括元素定位,元素操作,动态等待和断言四类方法。由于某个操作后的定位往往在另外一个页类中,动态等待和断言往往结合成一个方法中,先动态等待,等到后再断言,这个方法定义在另一类中,在本类中调用。比如注册成功后需要在登录界面中断言(注册成功页面跳转到登录页面),在登录页面定义断言方法。
pageobject.py
import sys,time
sys.path.append("../basepage")
from base import base,WaitUtils,judge
class login_page:#登录类
def login(page,username,password):
'''登录'''
username_field=base.find_element_by_label(page,"用户名:")
password_field=base.find_element_by_label(page,"密码:")
login_button=base.find_element_by_role(page,"button","登录")
base.fill(username_field,username)
base.fill(password_field,password)
login_button.click()
#判断进入商品列表页面
goods_list_page.judge_enter_goods_list_page(page,username)
def enter_register_page(page):
'''进入注册页面'''
register_link=base.find_element_by_text(page,"注册")
register_link.click()
register_page.judge_enter_register_page(page) #判断进入注册页面
def judge_enter_login_page(page):
'''判断进入登录页面'''
WaitUtils.wait_for_selector(page,"#id_username")
judge.judge_by_text(page,'a[href="/register/"]',"注册")
class register_page:#注册类
def register(page,username,password,email):
'''注册'''
username_field= base.find_element_by_label(page,"用户名:")
password_field= base.find_element_by_label(page,"密码:")
email_field= base.find_element_by_label(page,"电子邮件:")
submit_field= base.find_element_by_role(page,"button","注册")
base.fill(username_field,username)
base.fill(password_field,password)
base.fill(email_field,email)
submit_field.click()
login_page.judge_enter_login_page(page) #验证是否进入登录页面
def judge_enter_register_page(page):
'''验证是否进入注册页面'''
WaitUtils.wait_for_selector(page,"#id_username")
judge.judge_by_text(page,'a[href="/index/"]',"登录")
class goods_list_page: #商品列表页面类
def put_into_chart(page):
'''把商品放入购物车'''
input_link=base.find_element_by_xpath(page,"/html/body/div/div[2]/div/table/tbody/tr[1]/td[5]/a")
input_link.click()
goods_list_page.judge_put_into_chart_success(page) #验证把商品放入购物车成功
def serch_good(page,goods):
'''查询商品'''
search_input=base.find_element_by_placeholder(page,"名称")
search_button=base.find_element_by_role(page,"button","搜索")
base.fill(search_input,goods)
search_button.click()
goods_list_page.judge_serch_good_success(page) #验证查询商品成功
def see_goods_detail(page):
'''进入查看商品详情页'''
goods_detail_link=base.find_element_by_xpath(page,"/html/body/div/div[2]/div/table/tbody/tr[1]/td[4]/a")
goods_detail_link.click()
#验证是否进入商品详情页成功
goods_detail_page.judge_enter_goods_detail_success(page)
def see_user_info(page,username):
'''进入查看用户信息'''
user_link=base.find_element_by_text(page,username)
user_link.click()
#验证是否进入用户信息页成功
user_info_page.judge_enter_user_info_page_success(page)
def exit(page):
'''退出系统'''
exit_link=base.find_element_by_text(page,"退出")
exit_link.click()
login_page.judge_enter_login_page(page) #验证是否进入登录页
def enter_chart(page):
'''进入购物车页面'''
enter_chart_link=base.find_element_by_text(page,"查看购物车")
enter_chart_link.click()
chart_page.judge_enter_chart_page(page) #验证是否进入购物车页面
def view_all_orders(page):
'''查看所有订单'''
view_all_orders_link=base.find_element_by_text(page,"查看所有订单")
view_all_orders_link.click()
order_page.judge_enter_all_orders_page(page) #验证是否进入所有订单页
def judge_enter_goods_list_page(page,username):
'''验证是否进入商品列表页面'''
WaitUtils.wait_for_selector(page,".navbar-form")
judge.judge_by_text(page,'a[href="/user_info/"]',username)
def judge_put_into_chart_success(page):
'''验证把商品放入购物车成功'''
chart_sgin_xpath="//font[@color='#FF0000' and text()='1']"
WaitUtils.wait_for_selector(page,chart_sgin_xpath)
judge.judge_by_part_text(page,'a[href="/view_chart/"]','查看购物车')
def judge_serch_good_success(page):
'''验证查询商品成功'''
WaitUtils.wait_for_selector(page,".form-control")
judge.judge_by_text(page,'a[href="/view_goods/1/"]',"查看")
class chart_page: #购物车类
def change_goods_number(page,number):
'''在购物车中更改商品数量'''
number_field =base.find_element_by_id(page,"id_count")
change_button=base.find_element_by_type_value(page,"submit","修改")
base.fill(number_field,number)
change_button.click()
chart_page.judge_number_in_chart(page,number) #验证修改后的购物车某个商品数量
def select_address(page):
'''进入选择收货地址页,准备下单'''
pay_button=base.find_element_by_type_value(page,"submit","生成订单")
pay_button.click()
order_page.judge_enter_select_address_page(page) #验证是否进入选择收货地址页
def judge_enter_chart_page(page):
'''验证是否进入购物车页面'''
WaitUtils.wait_for_selector(page,".vIntegerField")
judge.judge_by_text(page,'a[href="/remove_chart/1/"]',"移除")
def judge_number_in_chart(page,number):
'''验证修改后的购物车某个商品数量'''
get_number=base.get_text_value(page,"number")
assert get_number==number
class order_page: #订单类
def select_address(page,address,phone):
'''选择收货地址 '''
found=judge.judge_link_in_td_exists(page,r"^/delete_address/\d+/\d+/$","删除")
if not found:
#生成订单
add_address_button=base.find_element_by_type_value(page,"submit","添加地址")
add_address_button.click()
add_address_page.judge_enter_add_address(page) #判断有无进入添加收货地址页
add_address_page.enter_address_info(page,address,phone) #输入用户信息
user_info_page.judge_having_address(page,"order")#判断是否生成收货地址
address_field=base.find_element_by_input_name(page,"address")#选择订单
next_button=base.find_element_by_type_value(page,"submit","下一步")
address_field.click()
next_button.click()
order_page.judge_in_order(page)
def judge_in_order(page):
'''验证这条订单是否生成'''
WaitUtils.wait_for_selector(page,"td a:has-text('删除')")
judge.judge_by_text(page,"td a:has-text('删除')","删除")
goods_list_page.view_all_orders(page) #验证查看所有订单是否有这条订单
def judge_enter_select_address_page(page):
'''验证是否进入选择收货地址页'''
WaitUtils.wait_for_selector(page,".col-md-6")
judge.judge_element_is_visible(page,"form[method='POST']")
def judge_enter_all_orders_page(page):
'''验证是否进入所有订单页'''
WaitUtils.wait_for_selector(page,"td a:has-text('删除')")
judge.judge_by_text(page,"td a:has-text('删除')","删除")
class user_info_page: #用户信息类
def enter_add_adress(page):
'''从用户信息页面进入添加用户地址页面'''
add_address_button=base.find_element_by_role(page,"button","添加地址")
add_address_button.click()
add_address_page.judge_enter_add_address(page) #验证是否进入添加用户地址页面
def reset_password(page):
'''从用户信息页面进入修改密码'''
enter_reset_password_button=base.find_element_by_type_value(page,"submit","修改密码")
enter_reset_password_button.click()
#判断是否进入重置密码页面
reset_password_page.judge_enter_reset_password_page(page)
def judge_enter_user_info_page_success(page):
'''查看进入用户信息页成功'''
WaitUtils.wait_for_selector(page,"#add_address")
mystr=["修改密码","添加地址"]
judge.judge_type_value(page,"submit",mystr)
def judge_having_address(page,sign):
'''判断判断是否生成收货地址'''
if sign=="order":
judge.judge_element_is_visible(page,"input[type='radio']")
elif sign=="address":
found=judge.judge_link_in_td_exists(page,r"^/update_address/\d+/\d+/$","修改")
assert found,"未找到符合条件的 '"+lable+"' 链接"
else:
print("sign in fuction user_info_page.judge_having_address(page,sign) is error")
class add_address_page: #添加收货地址类
def enter_address_info(page,address,phone): #进入地址信息页
'''输入用户地址信息'''
address_field=base.find_element_by_name(page,"address")
phone_field=base.find_element_by_name(page,"phone")
submit_button=base.find_element_by_role(page,"button","提交")
base.fill(address_field,address)
base.fill(phone_field,phone)
submit_button.click()
user_info_page.judge_having_address(page,"address")#判断有无用户地址信息
def judge_enter_add_address(page):
'''判断有无进入添加收货地址页'''
WaitUtils.wait_for_selector(page,"#id_address")
judge.judge_by_text(page,'button',"提交")
class goods_detail_page: #商品详情类
@staticmethod
def judge_enter_goods_detail_success(page):
'''查看进入商品详情页成功'''
WaitUtils.wait_for_selector(page,".input-group")
judge.judge_by_text(page,'a[href="/add_chart/1/2/"]',"放入购物车")
class reset_password_page: #重置密码类
def reset_password(page,password,repassword):
'''重置密码'''
old_password_field=base.find_element_by_name(page,"oldpassword")
new_password_field=base.find_element_by_name(page,"newpassword")
renew_password_field=base.find_element_by_name(page,"checkpassword")
submit_button=base.find_element_by_type_value(page,"submit","修改")
base.fill(old_password_field,password)
base.fill(new_password_field,repassword)
base.fill(renew_password_field,repassword)
submit_button.click()
reset_password_page.reset_password_success(page) #重置密码成功
def reset_password_success(page):
'''重置密码成功'''
judge.judge_by_text(page,'p[style="color:red"]',"密码修改成功")
def judge_enter_reset_password_page(page):
'''判断是否进入重置密码页面'''
WaitUtils.wait_for_selector(page,'input[name="oldpassword"]')
value=["修改"]
judge.judge_type_value(page,"submit",value)flowobject.py封装业务流操作,在test/test.py中可以采用XXXFlow.XXXBusiness()的操作形式。在这里定义了如下几个类。
•userFlow:用户流。
•goodsFlow:商品流。
•addressFlow:收货地址流。
•orderFlow:订单流。
flowobject.py
import sys
sys.path.append("../basepage")
from pageobject import *
from base import myexception
class userFlow:
def __init__(self,config,page):
self.config=config
self.page=page
def Register_and_Login(self):
'''注册然后登录'''
try:
self.page.goto(self.config.url)
login_page.enter_register_page(self.page) #进入注册页
except Exception as e:
myexception.my_exception(self.page,f"进入注册页失败:{str(e)}","enter_register_page_fail.png")
try:
register_page.register(self.page,self.config.username,self.config.password,self.config.email) #注册用户
except Exception as e:
myexception.my_exception(self.page,f"注册失败:{str(e)}","register_fail.png")
try:
#用注册用户登录
login_page.login(self.page,self.config.username,self.config.password)
except Exception as e:
myexception.my_exception(self.page,f"登录失败:{str(e)}","login_fail.png")
def reset_password(self):
'''重置密码'''
try:
#进入查看用户信息
goods_list_page.see_user_info(self.page,self.config.username)
except Exception as e:
myexception.my_exception(self.page,f"进入用户详情页失败:{str(e)}","enter_user_info_page_fail.png")
try:
user_info_page.reset_password(self.page)#从用户信息页面进入修改密码
except Exception as e:
myexception.my_exception(self.page,f"进入修改页密码失败:{str(e)}","enter_reset_password_page_fail.png")
try: #判断是否进入重置密码页面
#重置密码
reset_password_page.reset_password(self.page,self.config.password,self.config.repassword)
except Exception as e:
myexception.my_exception(self.page,f"重置密码失败:{str(e)}","reset_password_fail.png")
try:
goods_list_page.exit(self.page) #退出系统
except Exception as e:
myexception.my_exception(self.page,f"退出系统失败:{str(e)}","exit_fail.png")
try:
#用重置密码登录
login_page.login(self.page,self.config.username,self.config.repassword)
except Exception as e:
myexception.my_exception(self.page,f"用重置密码登录失败:{str(e)}","login_using_new_password_fail.png")
class goodsFlow:
def __init__(self,config,page):
self.config=config
self.page=page
def search_goods(self,goods):
'''查询商品'''
try:
goods_list_page.serch_good(self.page,goods)#查询商品
except Exception as e:
myexception.my_exception(self.page,f"搜索失败:{str(e)}","search_goods_failed.png")
def put_goods_into_chart(self):
'''放入购物车'''
try:
goods_list_page.put_into_chart(self.page)#把商品放入购物车
except Exception as e:
myexception.my_exception(self.page,f"放入购物车失败:{str(e)}","put_into_char_failed.png")
def see_goods_detail(self):
'''查看商品详情'''
try:
goods_list_page.see_goods_detail(self.page)#进入查看商品详情
except Exception as e:
myexception.my_exception(self.page,f"查看商品详情失败:{str(e)}","see_goods_detail_failed.png")
class addressFlow:
def __init__(self,config,page):
self.config=config
self.page=page
def add_address(self):
'''添加收货地址'''
try:
#进入查看用户信息
goods_list_page.see_user_info(self.page,self.config.username)
except Exception as e:
myexception.my_exception(self.page,f"进入用户详情页失败:{str(e)}","see_user_info_fail.png")
try:
#从用户信息页面进入添加用户地址页面
user_info_page.enter_add_adress(self.page)
except Exception as e:
myexception.my_exception(self.page,f"进入添加地址页失败:{str(e)}","enter_add_address_fail.png")
try:
add_address_page.enter_address_info(self.page,self.config.address,self.config.phone) #输入用户地址信息
except Exception as e:
myexception.my_exception(self.page,f"进入添加地址页失败:{str(e)}","enter_add_address_fail.png")
class orderFlow:
def __init__(self,config,page):
self.config=config
self.page=page
def pay_order(self):
'''下订单'''
try:
goods_list_page.put_into_chart(self.page)#把商品放入购物车
except Exception as e:
myexception.my_exception(self.page,f"放入购物车失败:{str(e)}","put_into_char_failed.png")
try:
goods_list_page.enter_chart(self.page) #进入购物车
except Exception as e:
myexception.my_exception(self.page,f"进入购物车失败:{str(e)}","enter_chart_fail.png")
try:
#在购物车总更改商品数量
chart_page.change_goods_number(self.page,self.config.number)
except Exception as e:
myexception.my_exception(self.page,f"修改商品数量失败:{str(e)}","change_number_fail.png")
try:
chart_page.select_address(self.page) #进入选择收货地址页,准备下单
except Exception as e:
myexception.my_exception(self.page,f"选择收货地址页,准备下单失败:{str(e)}","prepare_pay_order_fail.png")
try:
#选择收货地址
order_page.select_address(self.page,self.config.address,self.config.phone)
except Exception as e:
myexception.my_exception(self.page,f"选择收货地址失败:{str(e)}","select_address_fail.png")•class Test_Ebusiness:
test.py
import sys
sys.path.append("../data")
sys.path.append("../basepage")
sys.path.append("../pageobject")
import pytest
from page import mypages
from base import base
from db import ClassDB
from data import Config
from flowobject import *
class Test_Ebusiness:
@pytest.fixture(autouse=True)
def setup_and_teardown(self):
self.config=Config('default')
page=mypages(self.config)
self.page=page.page
self.browser=page.browser
self.playwright=page.playwright
self.userFlow=userFlow(self.config,self.page)
self.goodsFlow=goodsFlow(self.config,self.page)
self.addressFlow=addressFlow(self.config,self.page)
self.orderFlow=orderFlow(self.config,self.page)
yield
self.browser.close()
self.playwright.stop()
def test_Register_Login(self):
'''测试注册和登录'''
self.userFlow.Register_and_Login()
base.save_cookies(self.page)
def test_search(self):
'''测试查询商品'''
base.load_cookies(self.page,self.config.url)
self.goodsFlow.search_goods("茶")
def test_put_into_chart(self):
'''测试放入购物车'''
base.load_cookies(self.page,self.config.url)
self.goodsFlow.put_goods_into_chart()
def test_see_goods_detail(self):
'''测试查看商品详情'''
base.load_cookies(self.page,self.config.url)
self.goodsFlow.see_goods_detail()
def test_reset_password(self):
'''测试修改密码'''
base.load_cookies(self.page,self.config.url)
self.userFlow.reset_password()
def test_add_address(self):
'''测试新加地址'''
base.load_cookies(self.page,self.config.url)
self.addressFlow.add_address()
def test_pay_order(self):
'''测试下订单'''
base.load_cookies(self.page,self.config.url)
self.orderFlow.pay_order()
def teardown_class(self):
try:
db=ClassDB()
db.finsh_test()
except:
pass
if __name__=='__main__':
pytest.main(["-sv","test.py"])原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。