版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Mr_shashadudu/article/details/82018167
该方案将具体的操作代码抽离,并通过json文件的形式,使需要传入的特定参数可自由配置,而无需重复书写操作代码。同时将与appium服务器连接所需的参数、操作步骤、界面控件分开,将整个自动化测试过程分成不同模块,并根据具体需求自由组合,也方便多成员共同维护。
1、启动py时传入平台和应用版本信息
parser = argparse.ArgumentParser(description='APP自动化测试方案')
parser.add_argument('--p', metavar='<project path>', help='平台,ios/android')
parser.add_argument('--v', metavar='<project path>', help='测试的应用版本号')
2、将appium运行所需要的配置信息,以及操作和element对应信息,通过json形式分别描述,可以根据版本和平台信息加载相应的配置文件,也可以根据需要加载操作和element对应信息的配置文件。
与appium创建连接的配置文件
{
"platformName": "Android",
"platformVersion": "5.1.1",
"deviceName": "632340c3",
"appPackage": "包名",
"appActivity": "启动页面activity"
}
操作步骤配置文件
[
{
"type": "action",
"elements_id": "nav_bar",
"action_type": "recycler_click",
"page": "family_home",
"recycler_index":0,
"delay": 2
},
{
"type": "action",
"action_type": "click",
"page": "family_home",
"elements_id": "btn_add_dev",
"delay": 2
}
]
界面控件配置文件
{
"device_type_config_choose": {
"page_tag_name": "此界面的activity",
"elements": [
{
"elements_id": "btn_back",
"type": "android.widget.ImageButton"
},
{
"elements_id": "btn_qrcode",
"path": "//android.widget.TextView[@content-desc='扫一扫']"
},
{
"elements_id": "btn_zigbee_dev",
"path": "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.ScrollView/android.widget.RelativeLayout/android.widget.LinearLayout/android.widget.LinearLayout[1]/android.widget.ImageView"
},
{
"elements_id": "btn_ble_dev",
"path": "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.ScrollView/android.widget.RelativeLayout/android.widget.LinearLayout/android.widget.LinearLayout[2]/android.widget.ImageView"
},
{
"elements_id": "btn_all_dev",
"path": "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.ScrollView/android.widget.RelativeLayout/android.widget.LinearLayout/android.widget.LinearLayout[3]/android.widget.ImageView"
}
]
}
}
3、加载需要的界面配置信息,解析json放进字典中,使用时,根据操作文件中传入的page和element_id信息,到界面配置信息中定位到指定元素,获取对应的path、id、class等可抓去元素的方式信息。
根据文件路径解析json并添加到字典中
def init(paths):
global configData
for path in paths:
dicts = sys_fun.load_config_json(path)
configData.update(dicts)
解析json文件
def load_config_json(path):
print 'load config json ' + path
with open(path, 'r') as f:
a = f.read()
try:
return json.loads(a)
except Exception, e:
return None
根据操作配置文件中传入的page和element_id在界面控件配置文件中定位到指定的element
def get_element(page, element_id):
page = configData.get(page, None)
if page is None:
return None
else:
des_item = None
for item in page[AUTO_CONST.ACTION_ELEMENT]:
if item.get(AUTO_CONST.ACTION_ELEMENT_ID) == element_id:
des_item = item
break
return des_item
4、读取与appium建立连接所需的配置文件,解析json,并传入,与appium服务器建立连接,并返回driver对象。
def connect_server(config_path):
desired_caps = load_config_json(config_path)
desired_caps['unicodeKeyboard'] = True
desired_caps['resetKeyboard'] = True
driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
driver.implicitly_wait(5)
return driver
5、读取操作配置界面,解析json,逐个执行操作。
for page_item in action_config:
case_config = load_config_json('./config/case/' + page_item + '.json')
for step in case_config:
print step
cur_parser = generate_parser(step, platform)
if cur_parser is not None:
cur_parser.execute(driver)
else:
print 'cur_parser is none!!'
根据操作配置界面中传入的“action”,判断是action还是assert行为,并进行相对应的操作。
def generate_parser(case_item, platform):
case_item_type = case_item.get(AUTO_CONST.CASE_TYPE)
if AUTO_CONST.CASE_TYPE_ACTION == case_item_type:
return ActionParser(case_item, platform)
elif AUTO_CONST.CASE_TYPE_ASSERT == case_item_type:
return AssertParser(case_item, platform)
else:
return None