在ui自动化测试过程当中,目前存在最大的缺陷就是若是产品的ui或者结构改了那么这个项目进行的自动化测试脚本可能要面临全面维护。这也是目前ui自动化面临的很让人崩溃的事情。所以如今不少互联网产品项目发现ui自动化在测试中的价值愈来愈小,由于互联网产品的迭代太快,自动化测试组每每刚刚完善了自动化脚本,项目也跑起来了。忽然来了项目大改版,崩溃啊,这意味这代码要从新进行维护,并且维护成本很高。可能维护完了产品需求又改了,每每跟不上脚步。所以我UI自动化比较适合如下两种状况的项目:1.产品原型趋于稳定阶段,2.手机固件项目(由于手机固件是在原生安卓上修改的,原生安卓的的系统构架一般短期内不多会作重大改版,即便小改动也是一年一次)。
之前咱们的自动化项目都是趋于关键字驱动,数据和代码是揉杂在一块儿的。咱们写自动化测试用例的流程大概是这样的(以魅族社区发帖举例子只走流程不包括断言):点击发帖按钮—输入标题—输入正文—点击发送按钮
代码以下:数据库
UiObject write_title=new UiObject(new UiSelector().resourceId("com.meizu.mzbbs:id/et_write_title"));post
//assertTrue("write_title focusable is false", write_title.isFocused()==true); Configurator config = Configurator.getInstance(); config.setKeyInjectionDelay(40); write_title.setText(Utf7ImeHelper.e(“帖子标题”)); sleep(2000); UiObject richet_post=new UiObject(new UiSelector().resourceId("com.meizu.mzbbs:id/richet_posts")); richet_post.click(); sleep(2000); //assertTrue("richet_post focusable is false", richet_post.isFocused()==true); richet_post.setText(Utf7ImeHelper.e(“帖子正文”)); config.setKeyInjectionDelay(0); sleep(2000); UiObject send_post=new UiObject(new UiSelector().resourceId("com.meizu.mzbbs:id/action_send_posts")); send_post.clickAndWaitForNewWindow(3000); sleep(3000);
这样测试流程走通了,可是如过遇到如下问题1.resourceId改变了或者控件名称改变了(uiautomator也能够用控件名称定位控件)这就意味着我须要在代码中修改这些控件资源id或者name了。2.原始流程是A-B-C这种固定流程,万一流程中添加了F步骤变成A-F-B-C了,意味着在中间要插入一段代码,在无数行代码中找到这段代码而后插入,这样必定是很麻烦的并且还要调试。3.若是这个功能不要了意味着这些幸幸苦苦写的代码就白写了。相信以上问题都是你们在自动化测试实践过程当中所到很蛋疼的问题。这也是为何现阶段你们愈来愈对ui自动化持怀疑态度了,由于随着产品的持续迭代维护成本愈来愈高,进而转向接口自动化的缘由。
那么为了解决以上问题,因此如今又出现了一种趋于数据驱动的自动化模型,就是将测试代码和测试数据分开来,作到代码和数据独自开来这样每次迭代咱们只须要修改测试数据和少许测试代码就能对自动化测试脚本进行很好维护,同时能减小代码量,经过对方法的二次封装能够简化自动化测试的难度,使新手能更快的入手。整个设计思路为:将测试控件的资源id或者name和操做类型保存在excel表格或者数据库中,而后代码去读取excel表格中的控件资源数据做为参数传给操做代码。最后经过判断操做类型作出相应的操做,以上实现方法以魅族社区发帖步骤为例:
1.如今用excel创建一个管理测试数据的表格测试
2.获取表格中的资源id和操做方式数据主要方法以下:ui
public List<String> readXls(int rowNun)throw Exception{this
String path="F:/test.xls" File file = new File(path); InputStream is =new FileInputStream( //默认第一个表格 HSSFSheet sheet = wb.getSheetAt(0); HSSFRow row = sheet.getRow(rowNun); int minColIx=row.getFirstCellNum(); int maxColIx=row.getLastCellNum(); List<String> result=new ArrayList<String>(); //过滤掉第一列和第二列数据 for(int collx=minColIx+2;collx<maxColIx;collx++){ HSSFCell cell=row.getCell(collx); if(cell==null){ continue; } result.add(ExcelUtils.getStringVal(cell)); } return result;
}
3.获取到数据后供uiautomator定位控件方法调用,接下来咱们对获取的数据进行调用操做:
/*
经过判断操做类型来调用不一样的用例方案
rowNum 读取数去行数
**/
public void testUI(int rowNum)throw Exception{spa
//还能够定义其余类型的操做(如:长按等)在里面这里只举例两种 if((String)this.readXls(rowNum).get(1).equals("单击")){ UiObject click=new UiObject(new UiSelector().resourceId((String)this.readXls(rowNum).get(0))); richet_post.click(); sleep(2000); } else if((String)this.readXls(rowNum).get(1).equals("输入")){ UiObject editText=new UiObject(new UiSelector().resourceId((String)this.readXls(rowNum).get(1))); Configurator config = Configurator.getInstance(); config.setKeyInjectionDelay(40); search_movies1.setText(Utf7ImeHelper.e((String)this.readXls(rowNum).get(2))); config.setKeyInjectionDelay(0); }
}
这样全部的工做都准备好了,咱们设计测试用例定位控件操做时只要按照逻辑重复的调testUI(int rowNum)方法就行,只需修改rowNum参数,它会按照操做类型自动帮你调不一样类型的操做。并且能够发现测试数据和代码都分离出来了。若是改了ui界面控件咱们只需在excel表格中修改测试数据就行,就算项目大修改代码维护起来工做量也不是很大,并且操做逻辑上很灵活。(未完待续)。设计