Appium-Python3--UI自动化-[-12-]-UI自动化框架介绍
C:\chushujin\study\sales_ui_auto>tree
├─.idea
│ └─inspectionProfiles
├─app_package --APP的apk包
├─comm --封装一些访问数据库,日志输出,读取配置文件,HTMLTestRunner报告,获取设备信息方法封装
├─config --封装一些获取项目路径方法,读取excel等
│
├─locator --封装读取配置中元素的路径
│ └─app
│ ├─appCommon
│ │ ├─testLoginOut
│ │ │
│ │ └─testSalesLogin
│ │
│ └─BusinessProcess
│ ├─testLendRequestProcess
│ │ ├─testCustomerInfo
│ │ │
│ │ ├─testLoanInfo
│ │ │
│ │
│ └─testPotentialManager
│
├─page -- 通过locator中的读取到的内容,进行后续操作的封装
│ └─app
│ ├─appCommon
│ │ ├─testLoginOut
│ │ │
│ │ └─testSalesLogin
│ │
│ └─BusinessProcess
│ ├─testLendRequestProcess
│ │ ├─testCustomerInfo
│ │ │
│ │ ├─testLoanInfo
│ │ │
│ │
│ └─testPotentialManager
│
├─page_element --页面元素的定位和操作的方法封装
│
├─result --测试过程中的截图,日志,html报告
│ └─image
│ ├─2020-08-28
│ ├─2020-08-31
│ ├─2020-09-01
│ └─error
├─testCase -- 测试用例实现逻辑
│ ├─app
│ │ ├─appCommon
│ │ │ ├─testLogin
│ │ │ │
│ │ │ ├─testLoginOut
│ │ │ │
│ │ │
│ │ ├─BusinessProcess
│ │ │ ├─testLendRequestProcess
│ │ │ │ ├─testCustomerInfo
│ │ │ │ │
│ │ │ │ ├─testLoanInfo
│ │ │ │ │
│ │ │ │
│ │ │ ├─testPotentialManager
│ │ │ │
│ │ │
│ │
│
├─testFile -- 测试用例在excel中放置,名称,参数,期望结果,描述
│ └─app
│ ├─appCommon
│ │ ├─testLogin
│ │ └─testLoginOut
│ └─BusinessProcess
│ ├─testLendRequestProcess
│ │ ├─testCustomerInfo
│ │ └─testLoanInfo
│ └─testPotentialManager
├─testModels -- 类似java中getter和setter方法
│ └─app
│ ├─appCommon
│ │ └─testLogin
│ │
│ └─BusinessProcess
│ ├─testLendRequestProcess
│ │ ├─testCustomerInfo
│ │ │
│ │ └─testLoanInfo
│ └─testPotentialManager
└─util -- 封装生成一下身份证号,手机号,中文姓名,随机字符串等
├─deal_param
│
├─decorator
│
├─generator
│
├─caseList.txt --测试用例执行顺序
├─config.ini --配置文件
├─runCase.py -- 主入口
1. 配置文件中放置config.ini
#登录id login_id = com.ucredit.sale.android:id/account_et #密码id password_id = com.ucredit.sale.android:id/password_et #登录按钮id login_submit_id = com.ucredit.sale.android:id/sign_in_tv
2.locattor
class LocatorSalesLogin: # 位置授权是否弹出 auth_location_is_show_text = myConfig.getAppElement("auth_location_is_show_text") # 位置授权按钮 location_check_id = myConfig.getAppElement("login_click_id") # 用户名 username_id = myConfig.getAppElement("login_id") # 密码 password_id = myConfig.getAppElement("password_id") # 登录按钮 login_btn_id = myConfig.getAppElement("login_submit_id")
3. page
class SalesLoginPage(AppPageCommon): def location_check(self): """ 位置授权 :return: """ # 检查位置授权是否弹出 return self.is_toast_exist(LocatorSalesLogin.auth_location_is_show_text) def location_click(self): """ 位置授权 :return: """ # 点击 logger.info("开始授权位置...") print("开始授权位置...") self.click_element("id",LocatorSalesLogin.location_check_id) def login(self,u_data,p_data): """ 登录元素 :param u_data: :param p_data: :return: """ logger.info("开始登录...") self.input_id(LocatorSalesLogin.username_id,u_data) self.input_id(LocatorSalesLogin.password_id,p_data) logger.info("登录参数为:username : %s,password : %s" % (u_data,p_data)) print("登录参数为:username : %s,password : %s" % (u_data,p_data)) self.click_element("id",LocatorSalesLogin.login_btn_id)
4. testCase-测试用例逻辑
readconfig = readConfig.ReadConfig() writeconfig = writeConfig.WriteConfig() logger = logger sheet_name = readconfig.get_case("business") login_xls = readExcel.readExcel().get_xls('app/appCommon/testLogin','test_001_sales_login_module.xlsx', sheet_name) @paramunittest.parametrized(*login_xls) class TestLoginSales(unittest.TestCase): def setParameters(self,case_Name,param,excepted,reMarks): self.case_name = case_Name self.param = str(param) self.excepted = excepted self.reMarks = reMarks def setUp(self): """ :return: """ logger.info((self.case_name+"测试开始前准备").center(50,"*")) print('\n'+(self.case_name+"测试开始前准备").center(50,"*")) init_sales = initSalesObj self.driver = init_sales.get_driver() self.sales_login_page = SalesLoginPage(self.driver) def tearDown(self): logger.info((self.case_name + "测试结束,输出log完结").center(50, "*")) print((self.case_name + "测试结束,输出log完结").center(50, "*")) def test_Login(self): """登录""" # 输入参数处理 param = json.loads(str(self.param)) logger.info("检查位置授权弹框之前时间为:%s" % datetime.datetime.now()) # 检查位置授权是否弹出 is_show = self.sales_login_page.location_check() logger.info("位置授权是否存在: %s " % is_show) print("位置授权是否存在: %s " % is_show) # app正常启动,截图保存 common.take_screenShot(self.driver,u"启动页面") if is_show is True: # 获取位置授权 self.sales_login_page.location_click() # 登录 self.sales_login_page.login(param['username'],param['password']) # 断言 self.checkResult() def checkResult(self): # 断言登录成功 self.assertTrue(self.sales_login_page.is_toast_exist(self.excepted)) common.take_screenShot(self.driver,"登录成功")
5. testFile-测试用例
6. caseList.txt
#这里存放要运行的case,带#号的测试用例不会执行 # 登录 # app/appCommon/testSalesLogin/test_001_sales_login_module
7. runCase.py
读取caseList.txt中的用例到一个列表。
def set_case_list(self): """ 读取caselist.txt文件中的用例名称,并添加到caselist元素组 :return: """ fb = open(self.caseListFile,encoding="utf-8") for value in fb.readlines(): data = str(value) if data != '' and not data.startswith("#"): # 如果data非空且不以#开头 self.caseList.append(data.replace("\n", "")) # 读取每行数据会将换行转换为\n,去掉每行数据中的\n fb.close() # print(self.caseList)
生成测试套件,并将用例添加至其中
def set_case_suite(self): """ :return: """ # 通过set_case_list()拿到caselist元素组 self.set_case_list() # 创建测试套件 test_suite = unittest.TestSuite() suite_module = [] # 从caselist元素组中循环取出case for case in self.caseList: # 通过split函数来将aaa/bbb分割字符串,-1取后面,0取前面 case_name = case.split("/")[-1] # 打印出取出来的名称 print(case_name + ".py") # 批量加载用例,第一个参数为用例存放路径,第二个参数为规则 discover = unittest.defaultTestLoader.discover(self.caseFile, pattern=case_name + '.py', top_level_dir=None) # 将discover存入suite_module元素组 suite_module.append(discover) # print('suite_module:'+str(suite_module)) # 判断suite_module元素组是否存在元素 if len(suite_module) > 0: # 如果存在,循环取出元素组内容,命名为suite for suite in suite_module: # 从discover中取出test_name,使用addTest添加到测试集 for test_name in suite: test_suite.addTest(test_name) else: print('测试套件中无可执行的测试用例') return None return test_suite
run