该方案将具体的操作代码抽离,并通过json文件的形式,使需要传入的特定参数可自由配置,而无需重复书写操作代码。同时将与appium服务器连接所需的参数、操作步骤、界面控件分开,将整个自动化测试过程分成不同模块,并根据具体需求自由组合,也方便多成员共同维护。
parser = argparse.ArgumentParser(description='APP自动化测试方案')
parser.add_argument('--p', metavar='' , help='平台,ios/android')
parser.add_argument('--v', metavar='' , help='测试的应用版本号')
{
"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"
}
]
}
}
def init(paths):
global configData
for path in paths:
dicts = sys_fun.load_config_json(path)
configData.update(dicts)
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
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
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
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!!'
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