| #第1步:新建项目day10 |
| #第2步:在项目day10中 1)新建文件夹base 基类 package 2)新建文件夹page 封装 package 3)新建文件夹scripts 测试⽤例 package 4)新建文件夹data 数据⽂件 Directory 5)新建文件夹report 测试报告 Directory 6)新建文件夹log ⽇志⽂件 Directory 7)新建文件夹screenshot 截图⽂件 Directory |
| #第3步:在项目day10中新建项⽬配置信息⽂件config.py import logging.handlers import os#定义绝对路径 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) SERVER = "http://127.0.0.1:4723/wd/hub" DESIRED_CAPS = {#参数数据 "platformName": "Android",# 系统型号 "deviceName": "xxx",#设备号 "appPackage": "com.tpshop.malls",#APP的包名 #app打开的第一个界面 "appActivity": "com.tpshop.malls.SPMainActivity", "autoGrantPermissions": True#是否自动授权 } # 日志收集配置 def init_log_config(): # 创建日志器对象 logger = logging.getLogger() #定义日志类型INFO logger.setLevel(logging.INFO) # 创建处理器(控制台、文件) sh = logging.StreamHandler() #定义日志生成路径和文件名 filename = BASE_DIR + "/log/tpshop.log" # 配置信息 fh = logging.handlers.TimedRotatingFileHandler(filename, when='midnight', interval=1, backupCount=15, encoding="UTF-8") # 创建格式化器 fmt = "%(asctime)s %(levelname)s [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s" formatter = logging.Formatter(fmt) # 为处理器设置格式 sh.setFormatter(formatter) fh.setFormatter(formatter) # 把处理器添加到日志器中 logger.addHandler(sh) logger.addHandler(fh) |
| #第4步:在项目day10中新建项⽬配置信息⽂件utils.py import json import time from appium import webdriver from appium.webdriver.common.mobileby import MobileBy from selenium.webdriver.support.wait import WebDriverWait import config # 封装跳转指定activity的方法 def switch_to_activity(activity_name, package_name='com.tpshop.malls'): DriverUtil.get_app_driver().start_activity(package_name, activity_name) # 封装获取toast消息方法 def get_toast_msg(message): loc = (MobileBy.XPATH, f"//*[contains(@text,'{message}')]") try: el = WebDriverWait(DriverUtil.get_app_driver(), 10).until( lambda x: x.find_element(*loc) ) return el.text except Exception as e: print(f"没有找到toast元素{loc}") raise e # 封装数据处理函数可读取json文件 def build_data(filename): filepath = config.BASE_DIR + "/data/" + filename test_data = [] with open(filepath, encoding='utf-8') as f: data = json.load(f) for case_data in data: test_data.append(tuple(case_data.values())) return test_data # 封装获取屏幕截图方法 def get_screenshot(func_str="test"): filename = time.strftime("%Y%m%d-%H%M%S") + '.png' path = config.BASE_DIR + "/screenshot/" + func_str + filename DriverUtil.get_app_driver().get_screenshot_as_file(path) #封装驱动工具 class DriverUtil: __driver = None @classmethod # 封装启动驱动 def get_app_driver(cls): if cls.__driver is None: cls.__driver = webdriver.Remote(config.SERVER, config.DESIRED_CAPS) return cls.__driver @classmethod # 封装退出驱动 def quit_app_driver(cls): if cls.__driver is not None: cls.get_app_driver().quit() cls.__driver = None |
| #第5步:在项目day10中新建项⽬配置信息⽂件pytest.ini [pytest] addopts = -s -v --html=./report/tpshopapp.html --self-contained-html --capture=sys testpaths = ./scripts python_files = test*.py python_classes = Test* python_functions = test* |
| #第6步:base文件夹中新建文件base_page.py from selenium.webdriver.support.wait import WebDriverWait from utils import DriverUtil #封装基类 class BasePage: def __init__(self): self.driver= DriverUtil.get_app_driver()#启动 # 1)元素查找 def find_el(self,loc): try: el=WebDriverWait(self.driver,10).until(lambda x:x.find_element(*loc)) return el except Exception as e: print('没有找到元素') raise e #2)元素点击 def click_el(self,loc): self.find_el(loc).click() #3)文本输入 def input_text(self,loc,text): self.find_el(loc).click() self.find_el(loc).send_keys(text) #4)滑动查找元素 def swipe_find_el(self,loc,fx='up'): #定义w宽高h坐标 w=self.driver.get_window_size()['width'] h=self.driver.get_window_size()['height'] if fx=='up': s_x=e_x=w/2 s_y=h*0.9 e_y=h*0.1 elif fx=='down': s_x=e_x=w/2 s_y=h*0.1 e_y=h*0.9 elif fx=='left': s_x=w*0.9 e_x=w*0.1 s_y= e_y=h/2 else: s_x=w*0.1 e_x=w*0.9 s_y= e_y=h/2 while True: start_page=self.driver.page_source try: el=self.find_el(loc ) print('已找到元素') return el except Exception as e: print('没有找到元素') self.driver.swipe(s_x,s_y,e_x,e_y) if start_page==self.driver.page_source: print('已确定没有找到元素') return None |
| #第7步:page文件夹中新建文件index_page01.py '''1 首页页面 元素:1)我的 my_loc = MobileBy.XPATH, "//*[@text='我的']" 元素:1)搜索框 find_loc=MobileBy.CLASS_NAME,'android.widget.EditText' 业务方法: go_my_page() go_find_shop ''' from appium.webdriver.common.mobileby import MobileBy from base.base_page import BasePage class IndexPage(BasePage): def __init__(self): super().__init__() # 我的元素 self.my_loc = MobileBy.XPATH, "//*[@text='我的']" # 点击我的元素进入我的页面 def go_my_page(self): self.click_el(self.my_loc) |
| #第8步:page文件夹中新建文件my_page02.py '''2.我的页面 元素: 1)头像图片 profile_img_loc = (MobileBy.ID, "com.tpshop.malls:id/head_img") 2)地址管理 address_loc = (MobileBy.XPATH, "//*[@text='地址管理']") 业务方法: 1)去登录 go_login_page() 2)去地址管理 go_address_list_page() ''' from appium.webdriver.common.mobileby import MobileBy from base.base_page import BasePage class MyPage(BasePage): def __init__(self): super().__init__() # 1)头像图片 self.profile_img_loc = (MobileBy.ID, "com.tpshop.malls:id/head_img") # 2)地址管理 self.address_loc = (MobileBy.XPATH, "//*[@text='地址管理']") # 进入登录页面 def go_login_page(self): self.click_el(self.profile_img_loc) # 进入地址管理列表页面 def go_address_list_page(self): # 滑动找到目标地址管理元素点击 self.swipe_find_el(self.address_loc) self.click_el(self.address_loc) |
| #第9步:page文件夹中新建文件login_page03.py '''3. 登录页面 元素: 1)账号 mobile_loc = (MobileBy.ID, "com.tpshop.malls:id/mobile_et") 2)密码 pwd_loc = (MobileBy.ID, "com.tpshop.malls:id/pwd_et") 3)同意选框 agree_btn_loc = (MobileBy.ID, "com.tpshop.malls:id/agree_btn") 4)登录按钮 login_tv_loc =(MobileBy.ID,"com.tpshop.malls:id/login_tv") 业务方法: 1)去登录 go_login() ''' from appium.webdriver.common.mobileby import MobileBy from base.base_page import BasePage class LoginPage(BasePage): def __init__(self): super(LoginPage, self).__init__() #1)账号 self.mobile_loc = (MobileBy.ID, "com.tpshop.malls:id/mobile_et") # 2)密码 self.pwd_loc = (MobileBy.ID, "com.tpshop.malls:id/pwd_et") # 3)同意选框 self.agree_btn_loc = (MobileBy.ID, "com.tpshop.malls:id/agree_btn") # 4)登录按钮 self.login_tv_loc =(MobileBy.ID,"com.tpshop.malls:id/login_tv") def go_login(self, username, pwd): #输入数据点击同意选框和登录 self.input_text(self.mobile_loc, username) self.input_text(self.pwd_loc, pwd) self.click_el(self.agree_btn_loc) self.click_el(self.login_tv_loc) |
| #第10步:page文件夹中新建文件address_list_page04.py '''4. 地址管理列表页 元素: 1)新建地址 add_address_tv_loc = (MobileBy.ID, "com.tpshop.malls:id/add_address_tv") 业务方法: go_add_address_page() ''' from appium.webdriver.common.mobileby import MobileBy from base.base_page import BasePage class AddressListPage(BasePage): def __init__(self): super(AddressListPage, self).__init__() #新增地址元素 self.add_address_tv_loc = (MobileBy.ID, "com.tpshop.malls:id/add_address_tv") #去新增地址元素 def go_add_address_page(self): self.click_el(self.add_address_tv_loc) |
| #第11步:page文件夹中新建文件add_address_page05.py '''5. 新增地址页 元素: 1)收货人 receiver_loc = (MobileBy.ID, "com.tpshop.malls:id/consignee_name_et") 2)手机号码 mobile_loc = (MobileBy.ID, "com.tpshop.malls:id/consignee_mobile_et") 3)所在地区 region_loc = (MobileBy.ID, "com.tpshop.malls:id/consignee_region_tv") 3-1 省 province_loc = (MobileBy.XPATH, "//*[@text='{}']") 3-2 市 city_loc = (MobileBy.XPATH, "//*[@text='{}']") 3-3 区 area_loc = (MobileBy.XPATH, "//*[@text='{}']") 3-4 镇 town_loc = (MobileBy.XPATH, "//*[@text='{}']") 3-5 确定 Button_loc = (MobileBy.XPATH, "//*[@text='确定']") 4)详细地址 address_loc = (MobileBy.ID, "com.tpshop.malls:id/consignee_address_et") 5)设为默认地址 set_default_loc = (MobileBy.ID, "com.tpshop.malls:id/set_default_sth") 6)保存收货地址 save_address_loc = (MobileBy.ID, "com.tpshop.malls:id/save_tv") 业务方法: add_new_address(receiver, mobile, province, city, address, area=None, town=None)''' from appium.webdriver.common.mobileby import MobileBy from base.base_page import BasePage class AddAddressPage(BasePage): def __init__(self): super(AddAddressPage, self).__init__() # 1)收货人 self.receiver_loc = (MobileBy.ID, "com.tpshop.malls:id/consignee_name_et") # 2)手机号码 self.mobile_loc = (MobileBy.ID, "com.tpshop.malls:id/consignee_mobile_et") # 3)所在地区 self.region_loc = (MobileBy.ID, "com.tpshop.malls:id/consignee_region_tv") # 3 - 1省 self.province_loc = (MobileBy.XPATH, "//*[@text='{}']") # 3 - 2市 self.city_loc = (MobileBy.XPATH, "//*[@text='{}']") # 3 - 3区 self.area_loc = (MobileBy.XPATH, "//*[@text='{}']") # 3 - 4镇 self.town_loc = (MobileBy.XPATH, "//*[@text='{}']") #3-5 确定 self.Button_loc = (MobileBy.XPATH, "//*[@text='确定']") # 4)详细地址 self.address_loc = (MobileBy.ID, "com.tpshop.malls:id/consignee_address_et") # 5)设为默认地址 self.set_default_loc = (MobileBy.ID, "com.tpshop.malls:id/set_default_sth") # 6)保存收货地址 self.save_address_loc = (MobileBy.ID, "com.tpshop.malls:id/save_tv") def add_new_address(self,receiver, mobile, province, city, address, area=None, town=None): # 1)输入收货人# 2)输入手机号码# 3)点击所在地区 self.input_text(self.receiver_loc,receiver) self.input_text(self.mobile_loc,mobile) self.click_el(self.region_loc) #选择# 3 - 1省2市3区4镇5 点击确定 new_province_loc=self.province_loc[0],self.province_loc[1].format(province) self.swipe_find_el(new_province_loc) self.click_el(new_province_loc) # 选择# 3 - 2市3区4镇5 点击确定 new_city_loc=self.city_loc[0],self.city_loc[1].format(city) self.swipe_find_el(new_city_loc) self.click_el(new_city_loc) # 选择# 3 - 3区4镇5 点击确定 if area is not None: new_area_loc = self.area_loc[0], self.area_loc[1].format(area) self.swipe_find_el(new_area_loc) self.click_el(new_area_loc) # 选择# 3 - 4镇5 点击确定 if town is not None: new_town_loc = self.town_loc[0], self.town_loc[1].format(town) self.swipe_find_el(new_town_loc) self.click_el(new_town_loc) # 选择# 3 - 5 点击确定 self.click_el(self.Button_loc) # 4)输入详细地址 self.input_text(self.address_loc,address) # 5)点击设为默认地址 self.click_el(self.set_default_loc) # 6)点击保存收货地址 self.click_el(self.save_address_loc) |
| #第12步:data文件夹中新建文件add_address.json [ { "desc": "新增没有城镇的地址", "receiver": "王小丫4", "mobile": "13800000001", "province": "北京", "city": "朝阳区", "address": "三里屯蓝天大厦", "area": "定福庄", "town": null, "expect": "添加成功" }, { "desc": "新增有城镇的地址", "receiver": "王小丫4", "mobile": "13800000001", "province": "河北", "city": "石家庄市", "address": "河北大厦", "area": "辛集市", "town": "辛集镇", "expect": "添加成功" } ] |
| #第13步:scripts文件夹中新建文件test_add_address.py import logging.handlers import time import pytest import utils from page.add_address_page05 import AddAddressPage from page.address_list_page04 import AddressListPage from page.index_page01 import IndexPage from page.login_page03 import LoginPage from page.my_page02 import MyPage class TestAddAddress: def setup_class(self): # 进入地址管理列表页 # 创建各个页面对象 self.index_page = IndexPage() self.my_page = MyPage() self.login_page = LoginPage() self.address_list_page = AddressListPage() self.add_address_page = AddAddressPage() # 进入我的页面 self.index_page.go_my_page() # 进入登录页面 self.my_page.go_login_page() # 登录操作 self.login_page.go_login("13400000001", "123456") time.sleep(3) # 进入地址管理列表页 self.my_page.go_address_list_page() def teardown_class(self): # 关闭浏览器驱动 utils.DriverUtil.quit_app_driver() def setup(self): # 通过切换activity进入地址管理列表页 utils.switch_to_activity("com.tpshop.malls.activity.person.address.SPConsigneeAddressListActivity") def teardown(self): time.sleep(2) #读取json文件 data=utils.build_data("add_address.json") #使用@pytest方法读取数据 @pytest.mark.parametrize("desc, receiver, mobile, province, city, address, area, town, expect",data) def test_add_address(self, desc, receiver, mobile, province, city, address, area, town, expect): #生成测试报告内容 logging.info(f"desc={desc}, receiver={receiver}, mobile={mobile}," f"province={province}, city={city}, address={address}, " f"area={area}, town={town}, expect={expect}") try: # 进入新增地址页 self.address_list_page.go_add_address_page() # 新增地址 self.add_address_page.add_new_address(receiver, mobile, province, city, address, area, town) actual_msg = utils.get_toast_msg(expect) print(actual_msg) assert expect in actual_msg except Exception as e: utils.get_screenshot("test_add_address") raise e |



