1 / 23

敏捷开发中 的通过 Mock 实践

敏捷开发中 的通过 Mock 实践. 测 试工具-朱士松. Mock 与敏捷的关系 ( 一 ). 敏捷要求及早地对程序进行测试 Test First Development Test Driven Development 敏捷要求尽早交付有价值的软件 尽早交付需要以尽早完成前提 为加快速度通常会采取并行开发 并行开发中的服务依赖方难以测试. Mock 与敏捷的关系 ( 二 ). 并行开发造成的测试困难 依赖的服务仍在开发之中-无法获取和使用这项服务 依赖的服务处于调试阶段-不稳定的服务难以调查测试失败 使用真实服务有其它困难

adelle
Download Presentation

敏捷开发中 的通过 Mock 实践

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 敏捷开发中的通过Mock实践 测试工具-朱士松

  2. Mock与敏捷的关系(一) • 敏捷要求及早地对程序进行测试 • Test First Development • Test Driven Development • 敏捷要求尽早交付有价值的软件 • 尽早交付需要以尽早完成前提 • 为加快速度通常会采取并行开发 • 并行开发中的服务依赖方难以测试

  3. Mock与敏捷的关系(二) • 并行开发造成的测试困难 • 依赖的服务仍在开发之中-无法获取和使用这项服务 • 依赖的服务处于调试阶段-不稳定的服务难以调查测试失败 • 使用真实服务有其它困难 • 真实对象的行为难以触发-某些闹钟警报等触发条件很特殊 • 真实对象的行为结果难测-不便于编写短小有针对性的测试 • 异常处理测试需引发异常,但异常难以以某种方式稳定产生 • 压力测试时测试性能瓶颈

  4. 需要使用Mock对象 • 如果有个可控的虚拟对象? • 行为触发 • 控制结果 • 控制性能

  5. 流行的 Mock 工具 • Java • Jmock, Mockito, EasyMock • … • Mockrunner • .Net • Nmock, .NetMock • C/C++ • Google Mock -大多Mock的工作方式: • 按指定接口创建代理对象 • 设定代理对象的预期行为 • 使用代理类对象进行工作

  6. 流行的Mock工具- Jmock示例 • Talk is cheap, show me the code: - Linus • Interface defination publicinterfaceSomeInterface{ publicabstract Integer getDate(UserInfo user); } • Jmock example Mock mock=new Mock(SomeInterface.class); SomeInterface service =(SomeInterface)mock.proxy; // code to crate and set the args UserInfo user =newUserInfo(); // code to create and set the return value Integer[] expected =new Integer[]{1,2,3,4,5}; // code to set the funciton behavior mock.expects(once()).method("getDate").with(eq(args)).will(returnValue(expected); // work with the interface Integer[] actual =mock.getDate(user); assertArrayEquals(expected, actual);

  7. 流行的Mock工具-EasyMock示例 • Interface defination publicinterfaceSomeInterface{ publicabstract Integer getDate(UserInfo user); } • EasyMock example MockControl control = MockControl.createControl(SomeInterface.class); SomeInterface service = (SomeInterface)control.getMock(); // code to crate and set the args UserInfo user =newUserInfo(); // code to create and set the return value Integer[] expected =new Integer[]{1,2,3,4,5}; // code to set the funciton behavior EasyMock.expect(service.getDate(user)).andReturn(expected); EasyMock.replay(service); // work with the interface Integer[] actual =service.getDate(user); assertArrayEquals(expected, actual);

  8. 流行的Mock工具-Mockito示例 • Interface defination publicinterfaceSomeInterface{ publicabstract Integer getDate(UserInfo user); } • Mockito example SomeInterface service = mock(SomeInterface.class); // code to crate and set the args UserInfo user =newUserInfo(); // code to create and set the return value Integer[] expected =new Integer[]{1,2,3,4,5}; // code to set the funciton behavior when(service.getDate(user)).thenReturn(expected); Integer[] actual =service.getDate(user);

  9. 为什么还要再造一个 Mock呢(一) • 拉里·沃尔 (Perl 语言之父)的经典语录 • “Most of you are familiar with the virtues of a programmer. There are three, of course: laziness, impatience, and hubris.” • 你们大部分人都熟悉程序员的美德。当然了,是这三种:懒惰、急躁、傲慢。 • 现有Mock需要写

  10. 为什么还要再造一个 Mock呢(二) • “懒惰”又“急躁”的程序员希望能简单地完事: ApplicationContext context =newClassPathXmlApplicationContext("SpringServices.xml"); SomeService service =(SomeService)context.getBean("ServiceBeanId"); // wo don’t know where this service is real servie or mock service // method call on the interface, no more codes to set the exprected result by codes Integer[] array =service.getData("Monday"); // the other codes to use the array ...

  11. 为什么还要另做新的 Mock呢(一) • 现有Mock软件的一些不便 • 显式地使用了虚拟对象,测试真实对象时还要另写代码 • 显式设定了对象的行为,这段代码对于真实服务是多余的 • 设定预期的代码可能会很繁琐,比如入参和返回值很复杂 • 最重要的一点是,因为使用了Mock就需要要多写一套代码 • 我们更期待有一个这样的Mock • 隐式使用:让配置来决定是真实对象还是Mock对象在服务 • 数据驱动:数据决定行为,只需要造数据,不额外写代码 • API访问:仍然提供API,可以像其他Mock的方式一样工作

  12. 新Mock设计结构 Mock Server Web Service

  13. Mock Service工作流程

  14. 新Mock 要解决的两个问题 • 返回值的问题? • Q :返回值是一个Java类的实例,如何存储呢? • Q :返回类型可能很复杂,如何查看与编辑呢? • A :编写一个可以查看和编辑的“对象编辑器” • 匹配关系的问题? • Q:参数可有多个,还会有复杂的类,如何设置一个匹配条件? • A:让“对象编辑器”也能够编辑参数,并选择一些项作为条件。

  15. MockWebUI-服务管理 • http://10.232.134.38:8080/HsfServiceMock

  16. MockWebUI-资源浏览

  17. MockWebUI-入参匹配

  18. MockWebUI-对象编辑器

  19. 关于对象编辑器-PropertyGrid • 支持原始类型及一些特殊类型 • 泛型,数组,List, Set, Map • 有许多可用于扩展的特性 • @Display • @DisplayName • @DisplayValue • @Description • @DefaultValue • @Readonly • @Converter • @Editor, @Editor.KeyEditor, • @Descriptor • 作为单独的项目开源

  20. Mock的实际使用示例 • Spring.xml <beanid="userSyncService“class="com.taobao.hsf.app.spring.util.HSFSpringConsumerBean"> <propertyname="interfaceName"value="com.ali.luna.sync.service.UserSyncService"/> <propertyname="version"value="1.0.0.1.mock"/> </bean> • Javacode ApplicationContext context =newClassPathXmlApplicationContext("SimbaCallService.xml"); UserSyncServiceuserSyncService=(UserSyncService)context.getBean("userSyncService"); UserSyncObject user =newUserSyncObject(); user.setLocation(“suzou"); // more code to set this parameter try{ int ok =userSyncService.syncUser(user,"BP"); System.out.println(ok); } catch(Exception ex){ ex.printStackTrace(); }

  21. Mock的适用场景 • 适用的场景 • 交互的对象是一个”Interface” • 调用的目的在于得到返回值 • 不适用的场景 • 不适宜模拟类似set/write等需要改变某种状态的行为 • 同样调用需要不同的返回值时,配置过程比较复杂 • 有些接口有专用的Mock工具(如servlet/filter/jdbc/jmc)

  22. Mock的未来 • 向通用Mock的方向前进 • 用开放的RPC框架代替当前使用的HSF • 开发其它更多的功能 • 模拟服务器异常 • …… • 开源的准备

  23. 关于我们-一淘测试工具组 • 一淘测试网站: http://testing.etao.com/ • 一淘测试微博:http://weibo.com/etaotesting • Bug 管理软件:http://testing.etao.com/project/bugfree(BSD) • 任务调度系统:http://testing.etao.com/project/toast(GPL) • 关于本人: 淘锐奇 -http://weibo.com/treesong

More Related