前端测试
个人介绍:赵勇 / 淘宝UED / 前端 / 遇春(花名)
前端测试
Why   前端      测试
找一个说服自己的理由
产品的变化• RIA• Base on Browser• Heavy Javascript• Html 5
开发量的变化       Server        Browser   Server       Browser
前端关注点的变化 内部质量       外部质量 可维护性   前   功能 性能     端        质   界面 设计模式        量 开发效率
前端团队的变化游击队          正规军
测试同学:“前端的问题越来越多了”
别再找理由了先搞起来再说
How   前端      测试
• 产品界面         • 功能可用前端测试目标         • 性能高效稳定         • 代码可维护性强
声音“前端不好测”“界面老是改,改完用例就没用了”“单元测试不好做,很难隔离,不好做mock”“业内没有成熟的实践”“项目太紧,没时间”“前端测试性价比不高”
前端的痛                Dom                           兼容                            性      匿名函       数                 Ajax   ...
分而治之  浏览     兼容    匿名函       Ajax   器      性     数                          闭  Dom                     包        Dom测试 单元测试...
Dom测试              单元测试•   结构,布局          •   对象属性,方法•   兼容性            •   过程函数            前端测试    功能测试               性能测...
DOM测试
• DOM结构完整测试目标   • 模块布局样式无错乱       • 浏览器兼容性
谁动了我的TAG       </div>
还有• 加个样式,Ie6乱掉了• 开发html嵌套时,标签没闭合• 某个元素的样式名写错了• …
DEMOhttp://www.labs.com/sample/ershou.html#testOn
代码 describe(UI-logo,function(){      var logo = KISSY.get(#logo);      it(exist,function(){       expect(logo).toBeNode();...
代码describe(UI-logo,function(){     var logo = KISSY.one(#logo);     it(position is right,function(){           var oPos = ...
代码describe(UI-新鲜货,function(){     var freshItem = KISSY.one(#J_FreshItems);     it(childNode is right,function(){       ex...
功能测试
• 功能可用功能测试目标         • 交互过程正确
DEMOhttp://www.labs.com/sample/ershou.html#testOn
代码describe(功能-城市切换, function(){     var cityTrigger = KISSY.get(.J_CityPicker),     cityPopup = KISSY.get(.more-city-bd); ...
性能测试
• 同步执行耗时性能测试目标         • 异步响应耗时
DEMOhttp://www.labs.com/sample/ershou.html#testOn
代码describe(功能-城市切换, function(){     var cityTrigger = KISSY.one(.J_CityPicker).getDOMNode(),     cityPopup = KISSY.one(.mo...
代码describe(搜索推荐-城市切换,function(){  var searchInput = KISSY.get(#J_TBSearchQuery);  it(自动搜索推荐, function(){        searchInpu...
单元测试
• 函数单元测试目标   • 对象的属性和方法         • 业务逻辑
代码可测试性问题1. 面向过程,过程嵌套2. 太多的DOM操作3. 展现逻辑和业务逻辑混淆4. 闭包
语言特性1. 本地对象 & 宿主对象2. 静态作用域链3. 动态 & 弱类型
提升可测试性         抽象
过程式函数结构  function(){         var    CONSTANTS = constants value,定义常量            ELEMENTID = J_EId;         var    localVar...
对象结构Obj : {      attr-data:value,               数据属性      attr-ui:D.get(xid),          DOM相关属性      method-data:function()...
如何抽象  1. 单一职责法则,更细颗粒的过程抽象  2. 避免使用匿名函数  3. 将数据处理和DOM操作完全分开  4. 分离业务逻辑和展现逻辑  5. 减少闭包,为闭包中待测函数提供全局命名空间
过程抽象范例//...calculate point           function getLevel(point){var level;        var level;if (point < 100){if (point < 100...
闭包内函数暴露测试接口范例(function(){      var a = 1;      function method1(m){           return a + m;      }      testTarget = windo...
逻辑分离范例           Event.on(#content,blur,function(){                  if(hasError(this.value)){Event.on(#content,blur,funct...
提升可测试性         分层
1. 构建Js本地对象             2. 处理数据逻辑Javascript   3. 与 Server 通信             4. 添加事件回调             5. 操作DOM,BOM
DOM            BOM                     Javascript        UI                       Control      Model      Server
MVC对象结构View                        Control obj           obj    obj   instantia                            tion        obj...
ViewObj_Attr:value1                        1. 获取DOM,BOM数据AttrEl:someEl                        2. 修改DOM和BOMgetUIData:functi...
ModelObj                      1. 建立业务数据模型_Attr1:value1_Attr2:value2         2. 处理数据间的逻辑关系_Method:function(){}       //…   ...
Control              1. 对象实例化Var objUI = new View();Var obj = new Model();                          2. 初始化Function Process...
分层的好处  1. 可测试性提升  2. 各层关注分离,提升可扩展性  3. 业务逻辑和展现逻辑分离,UI修改更安全
分层的问题  1. 面向过程面向对象,推行成本较大  2. 对于简单的过程,反而增加可理解性  3. 对开发人员的抽象能力要求较高
DEMOhttp://www.labs.com/mvc/talk.html
Dom测试       单元测试        如何应用?功能测试        性能测试
首页型                  逻辑复杂型      DOM测试   单元测试      功能测试    性能测试交互型
3QA
Upcoming SlideShare
Loading in …5
×

前端测试

15,332 views
16,092 views

Published on

前端测试

Published in: Technology
0 Comments
9 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
15,332
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
96
Comments
0
Likes
9
Embeds 0
No embeds

No notes for slide

前端测试

  1. 1. 前端测试
  2. 2. 个人介绍:赵勇 / 淘宝UED / 前端 / 遇春(花名)
  3. 3. 前端测试
  4. 4. Why 前端 测试
  5. 5. 找一个说服自己的理由
  6. 6. 产品的变化• RIA• Base on Browser• Heavy Javascript• Html 5
  7. 7. 开发量的变化 Server Browser Server Browser
  8. 8. 前端关注点的变化 内部质量 外部质量 可维护性 前 功能 性能 端 质 界面 设计模式 量 开发效率
  9. 9. 前端团队的变化游击队 正规军
  10. 10. 测试同学:“前端的问题越来越多了”
  11. 11. 别再找理由了先搞起来再说
  12. 12. How 前端 测试
  13. 13. • 产品界面 • 功能可用前端测试目标 • 性能高效稳定 • 代码可维护性强
  14. 14. 声音“前端不好测”“界面老是改,改完用例就没用了”“单元测试不好做,很难隔离,不好做mock”“业内没有成熟的实践”“项目太紧,没时间”“前端测试性价比不高”
  15. 15. 前端的痛 Dom 兼容 性 匿名函 数 Ajax 面向过 异 闭 程 步 包 浏览 性 器 能
  16. 16. 分而治之 浏览 兼容 匿名函 Ajax 器 性 数 闭 Dom 包 Dom测试 单元测试 功能测试 性能测试 异 面向过 性 步 程 能
  17. 17. Dom测试 单元测试• 结构,布局 • 对象属性,方法• 兼容性 • 过程函数 前端测试 功能测试 性能测试• 过程 • 动态执行响应
  18. 18. DOM测试
  19. 19. • DOM结构完整测试目标 • 模块布局样式无错乱 • 浏览器兼容性
  20. 20. 谁动了我的TAG </div>
  21. 21. 还有• 加个样式,Ie6乱掉了• 开发html嵌套时,标签没闭合• 某个元素的样式名写错了• …
  22. 22. DEMOhttp://www.labs.com/sample/ershou.html#testOn
  23. 23. 代码 describe(UI-logo,function(){ var logo = KISSY.get(#logo); it(exist,function(){ expect(logo).toBeNode(); }); })
  24. 24. 代码describe(UI-logo,function(){ var logo = KISSY.one(#logo); it(position is right,function(){ var oPos = (KISSY.DOM.viewportWidth() – 990)/2; expect(logo.width()).toNear(177); expect(logo.height()).toNear(48); expect(logo.offset().left).toNear(oPos); expect(logo.offset().top).toNear(47); });})
  25. 25. 代码describe(UI-新鲜货,function(){ var freshItem = KISSY.one(#J_FreshItems); it(childNode is right,function(){ expect(freshItem.children().length).toBe(2); });})
  26. 26. 功能测试
  27. 27. • 功能可用功能测试目标 • 交互过程正确
  28. 28. DEMOhttp://www.labs.com/sample/ershou.html#testOn
  29. 29. 代码describe(功能-城市切换, function(){ var cityTrigger = KISSY.get(.J_CityPicker), cityPopup = KISSY.get(.more-city-bd); it(打开地区浮出层, function(){ jasmine.simulate(cityTrigger, mouseover); expect(cityPopup).toBeVisible(); });})
  30. 30. 性能测试
  31. 31. • 同步执行耗时性能测试目标 • 异步响应耗时
  32. 32. DEMOhttp://www.labs.com/sample/ershou.html#testOn
  33. 33. 代码describe(功能-城市切换, function(){ var cityTrigger = KISSY.one(.J_CityPicker).getDOMNode(), cityPopup = KISSY.one(.more-city-bd).getDOMNode(); it(打开速度, function(){ var start = +new Date(); jasmine.simulate(cityTrigger, mouseover); var end = +new Date(); var runtime = end-start; expect(cityPopup).toBeVisible(); expect(runtime).toBeLessThan(500); });})
  34. 34. 代码describe(搜索推荐-城市切换,function(){ var searchInput = KISSY.get(#J_TBSearchQuery); it(自动搜索推荐, function(){ searchInput.value = nokia; jasmine.simulate(searchInput,keydown); waits(1000); runs(function(){ var suggestContainer = KISSY.get(.ks-suggest-container); var suggestContent = KISSY.one(.ks-suggest-content).children().length; expect(suggestContainer).toBeVisible(); expect(suggestContent).toBe(1); }); });
  35. 35. 单元测试
  36. 36. • 函数单元测试目标 • 对象的属性和方法 • 业务逻辑
  37. 37. 代码可测试性问题1. 面向过程,过程嵌套2. 太多的DOM操作3. 展现逻辑和业务逻辑混淆4. 闭包
  38. 38. 语言特性1. 本地对象 & 宿主对象2. 静态作用域链3. 动态 & 弱类型
  39. 39. 提升可测试性 抽象
  40. 40. 过程式函数结构 function(){ var CONSTANTS = constants value,定义常量 ELEMENTID = J_EId; var localVariable,定义变量 result; var element = KISSY.one(ELEMENTID);从UI层获取数据 localVariable = element.attr(data-need);处理数据 result = handle(localVariable);更新DOM update(element,result);绑定事件回调 E.on(element, event, EventHandler); }
  41. 41. 对象结构Obj : { attr-data:value, 数据属性 attr-ui:D.get(xid), DOM相关属性 method-data:function(){ // deal attr-data... 处理数据的方法 }, method-ui:function(){ // deal attr-ui... 操作DOM的方法 }, process:function(){ method-data(); 功能或过程方法 method-ui(); }}
  42. 42. 如何抽象 1. 单一职责法则,更细颗粒的过程抽象 2. 避免使用匿名函数 3. 将数据处理和DOM操作完全分开 4. 分离业务逻辑和展现逻辑 5. 减少闭包,为闭包中待测函数提供全局命名空间
  43. 43. 过程抽象范例//...calculate point function getLevel(point){var level; var level;if (point < 100){if (point < 100){ level = 文艺青年; level = 文艺青年;}else if (point >= 100 if (point <>= 100 && point < 200){ }else && point 200){ level = ‘2B青年’; level = 2B青年‘;}else{ }else{ level = 普通青年‘; level = 普通青年‘;} } return level; }//...use level //... var level = getLevel(point); //...
  44. 44. 闭包内函数暴露测试接口范例(function(){ var a = 1; function method1(m){ return a + m; } testTarget = window[testTarget‘] || {}; testTarget.method1 = method1;})();
  45. 45. 逻辑分离范例 Event.on(#content,blur,function(){ if(hasError(this.value)){Event.on(#content,blur,function(){ showError(); } if(this.value === ){ hasError(this.value) }) function hasError(v){ alert(输入有误,不能为空) showError() return isBlank(v); } } function isBlank(v){}) var BLANK = ; return KISSY.trim(v) === BLANK; } function showError(){ var errMsg = 输入有误,不能为空; alert(errMsg); }
  46. 46. 提升可测试性 分层
  47. 47. 1. 构建Js本地对象 2. 处理数据逻辑Javascript 3. 与 Server 通信 4. 添加事件回调 5. 操作DOM,BOM
  48. 48. DOM BOM Javascript UI Control Model Server
  49. 49. MVC对象结构View Control obj obj obj instantia tion obj obj process bindEvent …Model obj obj obj obj
  50. 50. ViewObj_Attr:value1 1. 获取DOM,BOM数据AttrEl:someEl 2. 修改DOM和BOMgetUIData:function(){ //…} 3. 处理展现层逻辑setUI:function(){ //…}
  51. 51. ModelObj 1. 建立业务数据模型_Attr1:value1_Attr2:value2 2. 处理数据间的逻辑关系_Method:function(){} //… 3. 提供数据访问器Method:function(){ //… 4. 预留数据事件接口}
  52. 52. Control 1. 对象实例化Var objUI = new View();Var obj = new Model(); 2. 初始化Function Process1(){ //…} 3. 定义过程,实现viewFunction Process2(){ //…} 和model层对接E.on(someEl,’event’,process1); 4. 事件绑定
  53. 53. 分层的好处 1. 可测试性提升 2. 各层关注分离,提升可扩展性 3. 业务逻辑和展现逻辑分离,UI修改更安全
  54. 54. 分层的问题 1. 面向过程面向对象,推行成本较大 2. 对于简单的过程,反而增加可理解性 3. 对开发人员的抽象能力要求较高
  55. 55. DEMOhttp://www.labs.com/mvc/talk.html
  56. 56. Dom测试 单元测试 如何应用?功能测试 性能测试
  57. 57. 首页型 逻辑复杂型 DOM测试 单元测试 功能测试 性能测试交互型
  58. 58. 3QA

×