当前位置: 首页 > news >正文

长沙教育建设信息网站怎么样自己建立网站

长沙教育建设信息网站,怎么样自己建立网站,雕刻业务网站怎么做,阿里巴巴外贸平台下载处于高速迭代开发中的Android项目往往需要除黑盒测试外更加可靠的质量保障#xff0c;这正是单元测试的用武之地。单元测试周期性对项目进行函数级别的测试#xff0c;在良好的覆盖率下#xff0c;能够持续维护代码逻辑#xff0c;从而支持项目从容应对快速的版本更新。单元… 处于高速迭代开发中的Android项目往往需要除黑盒测试外更加可靠的质量保障这正是单元测试的用武之地。单元测试周期性对项目进行函数级别的测试在良好的覆盖率下能够持续维护代码逻辑从而支持项目从容应对快速的版本更新。单元测试是参与项目开发的工程师在项目代码之外建立的白盒测试工程用于执行项目中的目标函数并验证其状态或者结果其中单元指的是测试的最小模块通常指函数。如图1所示的绿色文件夹即是单元测试工程。这些代码能够检测目标代码的正确性打包时单元测试的代码不会被编译进入APK中。 ![](https://awps-assets.meituan.net/mit-x/blog-images-bundle-2015/f6b3c032.png) 图1 单元测试工程位置 与Java单元测试相同Android单元测试也是维护代码逻辑的白盒工程但由于Android运行环境的不同Android单元测试的环境配置以及实施流程均有所不同。 Java单元测试 在传统Java单元测试中我们需要针对每个函数进行设计单元测试用例。如图2便是一个典型的单元测试的用例。 ![](https://awps-assets.meituan.net/mit-x/blog-images-bundle-2015/7f6b69db.png) 图2 单元测试示例 上述示例中针对函数dosomething(Boolean param)的每个分支我们都需要构造相应的参数并验证结果。单元测试的目标函数主要有三种 1. 有明确的返回值如上图的dosomething(Boolean param)做单元测试时只需调用这个函数然后验证函数的返回值是否符合预期结果。 2. 这个函数只改变其对象内部的一些属性或者状态函数本身没有返回值就验证它所改变的属性和状态。 3. 一些函数没有返回值也没有直接改变哪个值的状态这就需要验证其行为比如点击事件。 既没有返回值也没有改变状态又没有触发行为的函数是不可测试的在项目中不应该存在。当存在同时具备上述多种特性时本文建议采用多个case来真对每一种特性逐一验证或者采用一个case逐一执行目标函数并验证其影响。构造用例的原则是测试用例与函数一对一实现条件覆盖与路径覆盖。Java单元测试中良好的单元测试是需要保证所有函数执行正确的即所有边界条件都验证过一个用例只测一个函数便于维护。在Android单元测试中并不要求对所有函数都覆盖到像Android SDK中的函数回调则不用测试。 Android单元测试 在Android中单元测试的本质依旧是验证函数的功能测试框架也是JUnit。在Java中编写代码面对的只有类、对象、函数编写单元测试时可以在测试工程中创建一个对象出来然后执行其函数进行测试而在Android中编写代码需要面对的是组件、控件、生命周期、异步任务、消息传递等虽然本质是SDK主动执行了一些实例的函数但创建一个Activity并不能让它执行到resume的状态因此需要JUnit之外的框架支持。当前主流的单元测试框架AndroidTest和Robolectric前者需要运行在Android环境上后者可以直接运行在JVM上速度也更快可以直接由Jenkins周期性执行无需准备Android环境。因此我们的单元测试基于Robolectric。对于一些测试对象依赖度较高而需要解除依赖的场景我们可以借助Mock框架。 Robolectric环境配置 Android单元测试依旧需要JUnit框架的支持Robolectric只是提供了Android代码的运行环境。如果使用Robolectric 3.0依赖配置如下 testCompile junit:junit:4.10 testCompile org.robolectric:robolectric:3.0Gradle对Robolectric 2.4的支持并不像3.0这样好但Robolectric 2.4所有的测试框架均在一个包里另外参考资料也比较丰富作者更习惯使用2.4。如果使用Robolectric 2.4则需要如下配置 classpath org.robolectric:robolectric-gradle-plugin:0.14.//这行配置在buildscript的dependencies中 apply plugin: robolectric androidTestCompile org.robolectric:robolectric:2.4上述配置中本文将testCompile写成androidTest并且常见的Android工程的单元测试目录名称有test也有androidTest这两种写法并没有功能上的差别只是Android单元测试Test Artifact不同而已。Test Artifact如图3所示 ![](https://awps-assets.meituan.net/mit-x/blog-images-bundle-2015/6e8678e9.png) 图3 Test Artifact 在Gradle插件中这两种Artifact执行的Task还是有些区别的但是并不影响单元测试的写法与效果。虽然可以主动配置单元测试的项目路径本文依旧建议采用与Test Artifact对应的项目路径和配置写法。 Mock配置 如果要测试的目标对象依赖关系较多需要解除依赖关系以免测试用例过于复杂用Robolectric的Shadow是个办法但是推荐更加简单的Mock框架比如Mockito该框架可以模拟出对象来而且本身提供了一些验证函数执行的功能。Mockito配置如下 repositories {jcenter() } dependencies {testCompile org.mockito:mockito-core:1. }Robolectric单元测试编写结构 单元测试代码写在项目的test也可能是androidTest该目录在项目中会呈浅绿色目录下。单元测试也是一个标准的Java工程以类为文件单位编写执行的最小单位是函数测试用例以下简称case是带有Test注解的函数单元测试里面带有case的类由Robolectric框架执行需要为该类添加注解RunWith(RobolectricTestRunner.class)。基于Robolectric的代码结构如下 //省略一堆import RunWith(RobolectricTestRunner.class) public class MainActivityTest {Beforepublic void setUp() {//执行初始化的操作}Testpublic void testCase() {//执行各种测试逻辑判断} }上述结构中带有Before注解的函数在该类实例化后会立即执行通常用于执行一些初始化的操作比如构造网络请求和构造Activity。带有test注解的是单元测试的case由Robolectric执行这些case本身也是函数可以在其他函数中调用因此case也是可以复用的。每个case都是独立的case不会互相影响即便是相互调用也不会存在多线程干扰的问题。 常见Robolectric用法 Robolectric支持单元测试范围从Activity的跳转、Activity展示View包括菜单和Fragment到View的点击触摸以及事件响应同时Robolectric也能测试Toast和Dialog。对于需要网络请求数据的测试Robolectric可以模拟网络请求的response。对于一些Robolectric不能测试的对象比如ConcurrentTask可以通过自定义Shadow的方式现实测试。下面将着重介绍Robolectric的常见用法。 Robolectric 2.4模拟网络请求 由于商业App的多数Activity界面数据都是通过网络请求获取因为网络请求是大多数App首要处理的模块测试依赖网络数据的Activity时可以在Before标记的函数中准备网络数据进行网络请求的模拟。准备网络请求的代码如下 public void prepareHttpResponse(String filePath) throws IOException {String netData FileUtils.readFileToString(FileUtils.toFile(getClass().getResource(filePath)), HTTP.UTF_8);Robolectric.setDefaultHttpResponse(200, netData); }//代码适用于Robolectric 2.43.0需要注意网络请求的包的位置由于Robolectric 2.4并不会发送网络请求因此需要本地创建网络请求所返回的数据上述函数的filePath便是本地数据的文件的路径setDefaultHttpResponse()则创建了该请求的Response。上述函数执行后单元测试工程便拥有了与本地数据数据对应的网络请求在这个函数执行后展示的Activity便是有数据的Activity。在Robolectric 3.0环境下单元测试可以发真的请求并且能够请求到数据本文依旧建议采用mock的办法构造网络请求而不要依赖网络环境。 Activity展示测试与跳转测试 创建网络请求后便可以测试Activity了。测试代码如下 Test public void testSampleActivity(){SampleActivity sampleActivityRobolectric.buildActivity(SampleActivity.class).create().resume().get();assertNotNull(sampleActivity);assertEquals(Activity的标题, sampleActivity.getTitle()); }Robolectric.buildActivity()用于构造Activitycreate()函数执行后该Activity会运行到onCreate周期resume()则对应onResume周期。assertNotNull和assertEquals是JUnit中的断言Robolectric只提供运行环境逻辑判断还是需要依赖JUnit中的断言。Activity跳转是Android开发的重要逻辑其测试方法如下 Test public void testActivityTurn(ActionBarActivity firstActivity, Class secondActivity) {Intent intent new Intent(firstActivity.getApplicationContext(), secondActivity);assertEquals(intent, Robolectric.shadowOf(firstActivity).getNextStartedActivity());//3.0的API与2.4不同 }Fragment展示与切换 Fragment是Activity的一部分在Robolectric模拟执行Activity过程中如果触发了被测试的代码中的Fragment添加逻辑Fragment会被添加到Activity中。需要注意Fragment出现的时机如果目标Activity中的Fragment的添加是执行在onResume阶段在Activity被Robolectric执行resume()阶段前该Activity中并不会出现该Fragment。采用Robolectric主动添加Fragment的方法如下 Test public void addfragment(Activity activity, int fragmentContent){FragmentTestUtil.startFragment(activity.getSupportFragmentManager().findFragmentById(fragmentContent));Fragment fragment activity.getSupportFragmentManager().findFragmentById(fragmentContent);assertNotNull(fragment); }startFragment()函数的主体便是常用的添加fragment的代码。切换一个Fragment往往由Activity中的代码逻辑完成需要Activity的引用。 控件的点击以及可视验证 Test public void testButtonClick(int buttonID){Button submitButton (Button) activity.findViewById(buttonID);assertTrue(submitButton.isEnabled());submitButton.performClick();//验证控件的行为 }对控件的点击验证是调用performClick()然后断言验证其行为。对于ListView这类涉及到Adapter的控件的点击验证写法如下 //listView被展示之后 listView.performItemClick(listView.getAdapter().getView(position, null, null), 0, 0);与button等控件稍有不同。 Dialog和Toast测试 测试Dialog和Toast的方法如下 public void testDialog(){Dialog dialog ShadowDialog.getLatestDialog();assertNotNull(dialog); } public void testToast(String toastContent){ShadowHandler.idleMainLooper();assertEquals(toastContent, ShadowToast.getTextOfLatestToast()); }上述函数均需要在Dialog或Toast产生之后执行能够测试Dialog和Toast是否弹出。 Shadow写法介绍 Robolectric的本质是在Java运行环境下采用Shadow的方式对Android中的组件进行模拟测试从而实现Android单元测试。对于一些Robolectirc暂不支持的组件可以采用自定义Shadow的方式扩展Robolectric的功能。 Implements(Point.class) public class ShadowPoint {RealObject private Point realPoint;...public void __constructor__(int x, int y) {realPoint.x x;realPoint.y y;} }//样例来源于Robolectric官网上述实例中Implements是声明Shadow的对象RealObject是获取一个Android 对象constructor则是该Shadow的构造函数Shadow还可以修改一些函数的功能只需要在重载该函数的时候添加Implementation这种方式可以有效扩展Robolectric的功能。Shadow是通过对真实的Android对象进行函数重载、初始化等方式对Android对象进行扩展Shadow出来的对象的功能接近Android对象可以看成是对Android对象一种修复。自定义的Shadow需要在config中声明声明写法是Config(shadowsShadowPoint.class)。 Mock写法介绍 对于一些依赖关系复杂的测试对象可以采用Mock框架解除依赖常用的有Mockito。例如Mock一个List类型的对象实例可以采用如下方式 List list mock(List.class); //mock得到一个对象也可以用mock注入一个对象所得到的list对象实例便是List类型的实例如果不采用mockList其实只是个接口我们需要构造或者借助ArrayList才能进行实例化。与Shadow不同Mock构造的是一个虚拟的对象用于解耦真实对象所需要的依赖。Mock得到的对象仅仅是具备测试对象的类型并不是真实的对象也就是并没有执行过真实对象的逻辑。 Mock也具备一些补充JUnit的验证函数比如设置函数的执行结果示例如下 When(sample.dosomething()).thenReturn(someAction);//when(一个函数执行).thenReturn(一个可替代真实函数的结果的返回值); //上述代码是设置sample.dosomething()的返回值当执行了sample.dosomething()这个函数时就会得到someAction从而解除了对真实的sample.dosomething()函数的依赖上述代码为被测函数定义一个可替代真实函数的结果的返回值。当使用这个函数后这个可验证的结果便会产生影响从而代替函数的真实结果这样便解除了对真实函数的依赖。 同时Mock框架也可以验证函数的执行次数代码如下 List list mock(List.class); //Mock得到一个对象 list.add(1); //执行一个函数 verify(list).add(1); //验证这个函数的执行 verify(list,time(3)).add(1); //验证这个函数的执行次数在一些需要解除网络依赖的场景中多使用Mock。比如对retrofit框架的网络依赖解除如下 //代码参考了参考文献[3] public class MockClient implements Client {Overridepublic Response execute(Request request) throws IOException {Uri uri Uri.parse(request.getUrl());String responseString ;if(uri.getPath().equals(/path/of/interest)) {responseString 返回的json1;//这里是设置返回值} else {responseString 返回的json2;}return new Response(request.getUrl(), 200, nothing, Collections.EMPTY_LIST, new TypedByteArray(application/json, responseString.getBytes()));} } //MockClient使用方式如下 RestAdapter.Builder builder new RestAdapter.Builder(); builder.setClient(new MockClient());这种方式下retrofit的response可以由单元测试编写者设置而不来源于网络从而解除了对网络环境的依赖。 单元测试的范围 在Android项目中单元测试的对象是组件状态、控件行为、界面元素和自定义函数。本文并不推荐对每个函数进行一对一的测试像onStart()、onDestroy()这些周期函数并不需要全部覆盖到。商业项目多采用Scrum模式要求快速迭代有时候未必有较多的时间写单元测试不再要求逐个函数写单元测试。本文单元测试的case多来源于一个简短的业务逻辑单元测试case需要对这段业务逻辑进行验证。在验证的过程中开发人员可以深度了解业务流程同时新人来了看一下项目单元测试就知道哪个逻辑跑了多少函数需要注意哪些边界——是的单元测试需要像文档一样具备业务指导能力。在大型项目中遇到需要改动基类中代码的需求时往往不能准确快速地知道改动后的影响范围紧急时多采用创建子类覆盖父类函数的办法但这不是长久之计在足够覆盖率的单元测试支持下跑一下单元测试就知道某个函数改动后的影响可以放心地修改基类。美团的Android单元测试编写流程如图4所示。 ![](https://awps-assets.meituan.net/mit-x/blog-images-bundle-2015/607bd9fe.png) 图4 美团Android单元测试编写流程 单元测试最终需要输出文档式的单元测试代码为线上代码提供良好的代码稳定性保证。 单元测试的流程 实际项目中单元测试对象与页面是一对一的并不建议跨页面这样的单元测试藕合度太大维护困难。单元测试需要找到页面的入口分析项目页面中的元素、业务逻辑这里的逻辑不仅仅包括界面元素的展示以及控件组件的行为还包括代码的处理逻辑。然后可以创建单元测试case列表列表用于纪录项目中单元测试的范围便于单元测试的管理以及新人了解业务流程列表中记录单元测试对象的页面对象中的case逻辑以及名称等。工程师可以根据这个列表开始写单元测试代码。 单元测试是工程师代码级别的质量保证工程上述流程并不能完全覆盖重要的业务逻辑以及边界条件因此需要写完后看覆盖率找出单元测试中没有覆盖到的函数分支条件等然后继续补充单元测试case列表并在单元测试工程代码中补上case。 直到规划的页面中所有逻辑的重要分支、边界条件都被覆盖该项目的单元测试结束。单元测试流程如图5所示。 ![](https://awps-assets.meituan.net/mit-x/blog-images-bundle-2015/b0f09068.jpg) 图5 单元测试执行流程 上述分析页面入口所得到结果便是Before标记的函数中的代码之后的循环便是所有的caseTest标记的函数。 为了系统的介绍单元测试的实施过程本文创建了一个小型的demo项目作为测试对象。demo的功能是供用户发布所见的新闻到服务端并浏览所有已经发表的新闻是个典型的自媒体应用。该demo的开发和测试涉及到TextView、EditView、ListView、Button以及自定义View包含了网络请求、多线程、异步任务以及界面跳转等。能够为多数商业项目提供参照样例。项目页面如图6所示。 ![](https://awps-assets.meituan.net/mit-x/blog-images-bundle-2015/6a8ce640.jpg) 图6 单元测试case设计 首先需要分析App的每个页面针对页面提取出简短的业务逻辑提取出的业务逻辑如图6绿色圈图所示。根据这些逻辑来设计单元测试的case带有Test注解的那个函数这里的业务逻辑不仅指需求中的业务还包括其他需要维护的代码逻辑。业务流程不允许跨页面以免增加单元测试case的维护成本。针对demo中界面的单元测试case设计如下 表1 单元测试case列表 目标页面业务覆盖界面元素逻辑描述最小断言数case名称创建新闻页面NewsCreatedActivity编写新闻1.标题框2.内容框3.发布按钮1.向标题框输入内容2.向内容框输入内容3.当标题和内容都存在的时候上传按钮可点击3testWriteNews()输入新闻的金额1.Checkbox2.金额控件1.选中免费发布时金额输入框消失2.不选免费时可以输入金额3.金额输入框只接受小数点后最多两位3testValue()菜单跳转至新闻列表1.菜单按钮1.点击菜单跳转到新闻列表页面1testMenuForTrunNewsList()发布新闻1.发布按钮2.Toast1.当标题或者内容为空时发布按钮不可点击2.编写了新闻的前提下点击发布按钮3.新闻发布成功弹出Toast提示 “新闻已提交”4.没有标题或者内容时新闻发布失败弹出Toast提示“新闻提交失败”5testNewsPush()、testPushNewsFailed()新闻列表页面NewsListActivity浏览新闻列表1.列表1.进入此页面后会出现新闻列表2.有网络情况下能发起网络请求3.网络请求需要用Mock解除偶和单独验证页面对数据的响应后端返回一项时列表只有一条数据6testNewsListNoNetwork()、testGetnewsWhenNetwork()、testSetNews()菜单跳转至创建新闻页面1.菜单按钮1.点击菜单跳转到创建新闻页面1testMenuForTrunCreatNews()查看详细新闻1.有内容的列表2.Dialog1.有新闻的前提下列表可点击点击弹出Dialog1testNewsDialog()接下来需要在单元测试工程中实现上述case最小断言数是业务逻辑上的判断并不是代码的边界条件真实的case需要考虑代码的边界条件比如数组为空等条件因此最终的断言数量会大于等于最小断言数。在需求业务上最小断言数也是该需求的业务条件。写完case后需要跑一遍单元测试并检查覆盖率报告当覆盖率报告中缺少有些单元测试case列表中没有但是实际逻辑中会有的逻辑时需要更新单元测试case列表添加遗漏的逻辑并将对应的代码补上。直到所有需要维护的逻辑都被覆盖该项目中的单元测试才算完成。单元测试并不是QA的黑盒测试需要保证对代码逻辑的覆盖。对表1分析第一个页面的“发布新闻”的case可以直接调用“编写新闻”的case以满足条件“2.编写了新闻的前提下点击发布按钮”在JUnit框架下case带Test注解的那个函数也是个函数直接调用这个函数就不是case和case是无关的两者并不会相互影响可以直接调用以减少重复代码。第二个页面不同于第一个一进入就需要网络请求后续业务都需要依赖这个网络请求单元测试不应该对某一个条件过度耦合因此需要用mock解除耦合直接mock出网络请求得到的数据单独验证页面对数据的响应。 单元测试并不是一个能直接产生回报的工程它的运行以及覆盖率也不能直接提升代码质量但其带来的代码控制力能够大幅度降低大规模协同开发的风险。现在的商业App开发都是大型团队协作开发不断会有新人加入无论新人是刚入行的应届生还是工作多年在代码存在一定业务耦合度的时候修改代码就有一定风险可能会影响之前比较隐蔽的业务逻辑或者是丢失曾经的补丁如果有高覆盖率的单元测试工程就能很快定位到新增代码对现有项目的影响与QA验收不同这种影响是代码级的。在本文所设计的单元测试流程中单元测试的case和具体页面的具体业务流程以及该业务的代码逻辑紧密联系单元测试如同技术文档一般能够体现出一个业务逻辑运行了多少函数需要注意什么样的条件。这是一种新人了解业务流程、对业务进行代码级别融入的好办法看一下以前的单元测试case就能知道与该case对应的那个页面上的那个业务逻辑会执行多少函数以及这些函数可能出现的结果。 [1] http://robolectric.org [2] https://github.com/square/okhttp/tree/master/mockwebserver [3] http://stackoverflow.com/questions/17544751/square-retrofit-server-mock-for-testing [4] https://en.wikipedia.org/wiki/Unit_testing
http://wiki.neutronadmin.com/news/184146/

相关文章:

  • 网页和网站设计请人做彩票网站多少钱
  • 建立个人博客网站百度指数分析数据
  • 网站开发文件东莞企业网络营销平台
  • 建站快车打电话外贸流程知乎
  • 做投票的网站赚钱嘛创意100图片欣赏
  • 数据网站建设哪个好智慧城市
  • 未备案个人网站 如何挣钱公司如何做网站
  • 上海建设牌电动三轮官方网站门户网站建设模式包括网站群和
  • 怎么制作公司自己网站wordpress高仿dz模板
  • 鞋业有限公司网站设计大型的网站建设公司
  • 网站的切图是谁来做济宁网络
  • 在线免费网站排名优化做网站销售说辞
  • 门户网站后台管理系统模板免费制作自己的网站
  • 江苏优化网站关键词新商盟显示 检查网站开发错误呢
  • 深圳一定火网站建设cms企业网站管理系统
  • 深圳网站建设深圳网络公司威海城市 建设信息网站
  • 目前做网站流行的是什么10大免费软件下载
  • 惠州网站建设系统广告设计图片网站
  • 郑州flash网站建设凡科互动投票破解
  • 用家用路由器ip做网站app开发公司怎么选
  • wordpress有多少网站网站建设教程最新资讯
  • 建设公司网站费用怎么做账wordpress个人博客主题好看
  • 杭州建设网站职称人才工作专题天元建设集团有限公司设计研究院征求意见
  • 深圳企业网站制作设计腾讯微校怎么做微网站
  • 如何搭建英文网站哪些网站可以免费做简历
  • 北京做网站公司专业团队电脑壁纸
  • 建设网站的合同南川网站建设
  • 广汉手机网站设计好男人视频在线观看免费直播
  • 企业网站设计图设计 中国官网
  • 技术支持 张家港网站建设舒城县重点工程建设局网站