changelist:

--------------------------------

1.0

如何利用QUnit来进行javascript的TDD

1.1

添加javascript code coverage

添加Pavlov介绍,如果利用Qunit进行BDD

--------------------------------

现下有很多JavaScript的测试框架,比如:Jasmine ,  Qunit等(后续会继续补充)

关于单元测试的TDD(Test  Drive Develop)框架,我觉得来自他人博客的一段话很好的说明了一些基本的需求:(参见:http://www.cnblogs.com/tonyqus/archive/2010/10/31/jquery_tdd_qunit.html)

作为标准的TDD框架,必须满足这么几个要求:

1. 即使测试脚本出错了也要能继续运行接下来的脚本

2. 能够不依赖被测试代码写测试用例,即使代码没有实现也可以先写测试用例

3. 能够显示详细的错误信息和位置

4. 能够统计通过和未通过的用例的数量

5. 有专门的可视化界面用于统计和跟踪测试用例

6. 易于上手,通过一些简单的指导就可以马上开始写测试代码。

在这之中,个人觉得目前比较容易上手的有QUnit,那么首先说说Qunit。

Qunit 官方站点:http://docs.jquery.com/QUnit

如何使用Qunit?

首先去http://github.com/jquery/qunit 下载Qunit(包括 qunit.js 和 qunit.css)

之后,新建一个测试页面,标准的代码如下:

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="js/jquery-1.7.1.js"></script>
<link rel="stylesheet" href="js/qunit/qunit.css"/>
<script type="text/javascript" src="js/qunit/qunit.js"></script>
<!--测试代码-->
<script>
test("hello", function() {ok(true, "world");
});
</script></head>
<body><h1 id="qunit-header">QUnit example</h1><h2 id="qunit-banner"></h2><div id="qunit-testrunner-toolbar"></div><h2 id="qunit-userAgent"></h2><ol id="qunit-tests"></ol><div id="qunit-fixture">test markup, will be hidden</div>
</body>
</html>

在浏览器中看的效果如图:

更通常的写法,在页面中加入一个单独的js引用专门用来写单元测试的function,比如叫test.js

<script language="javascript" src="test.js" type="text/javascript"/>

test.js的内容来自 http://msdn.microsoft.com/en-us/scriptjunkie/gg749824:

function format(string, values) {for (var key in values) {string = string.replace(new RegExp("\{" + key + "}"), values[key]);}return string;
}test("basics", function() {var values = {name: "World"};equal( format("Hello, {name}", values), "Hello, World", "single use" );equal( format("Hello, {name}, how is {name} today?", values),"Hello, World, how is World today?", "multiple" );
});


在浏览器中,我们看到如下的效果:

这就是一个标准的QUnit的测试界面,红色的表示这个测试用例没有通过,绿色的表示通过。每一个框比表示一个测试函数,里面可能有多个断言语句的结果,标题中(x,y,z)表示总共有z个断言,y个是正确的,x个是错误的。
在Qunit中,经常用到的函数有:
expect(amount) - 指定某个函数中会有多少个断言,通常写在测试函数开头。
module(name) - 模块是测试函数的集合,使用该函数可以在UI中将测试函数按模块归类。
ok(state, message) – 布尔型断言,message是专门显示在QUnit界面上,用来区分不同的断言的
equals(actual, expected, message) - 相等断言,actual和expected的值相等时才能通过。
这些是最常用的,其他的大家可以自己参考Qunit官方文档。

另外,有些测试中,我们如果改变DOM,那么这样跑完一个测试用例,就会影响到下一个测试用例,这样的情况怎么办呢?其实QUnit已经考虑到了这一点,只要我们把需要修改的内容放在"qunit-fixture" 这个div的里面, 在运行下一个测试用例之前,QUnit会先自动reset 这个div里面的内容,这样测试用例就不会互相干扰。
<div id="qunit-fixture"><input id="input" type="text" placeholder="placeholder text" />
</div>

另外,如果还有一些额外的数据需要操作的话,QUnit也提供了module的概念,类似于测试用例组。
module("core", {setup: function() {// runs before each test},teardown: function() {// runs after each test}
});
test("basics", function() {// test something
});
这样在每次执行test的时候,都会先执行一次setup函数,再执行完test的时候,会执行teardown函数。

上面的测试都是同步的,就是说一旦载入测试页面,就会开始跑测试用例,那么又如何测试ajax等需要回调的异步操作呢?QUnit也考虑到了这一点,
提供了三个函数,start, stop , asyncTest.
function ajax(callback){$.ajax({url:"/ajaxtest",success:callback});
}test("asynchronous test" , function(){stop();expect(3);ajax(function(){ok(true);});ajax(function(){ok(true);ok(true);        });setTimeout(function(){start();},1000);
});asyncTest("asynchronous test" , function(){    expect(3);ajax(function(){ok(true);});ajax(function(){ok(true);ok(true);        });setTimeout(function(){start();},1000);
});
asyncTest已经调用了一次stop,所以不需要像test一样再调用一次stop函数。

很多的时候,在写代码的时候,服务器端还没有写好,那么这个时候,往往需要去模拟ajax的请求,那么在这样的情况下,又该如何呢?这个时候可以借助于jquery.mockjax.js,官网:https://github.com/appendto/jquery-mockjax
, 这个插件很方便使用,只要在代码中引入jquery.mockjax.js,同时加上需要模拟的ajax的请求就可以了,下面是一个例子:
$.mockjax({url: '/ajaxtest',responseTime: 200,responseText: {status: 'success',fortune: 'Are you a turtle?'}
});

另外对于需要模拟鼠标,键盘操作的,可以用jquery的trigger(比如:trigger($.Event("keydown", { which: 40 }));), 也可以用YUI的UserAction。

如果进行javascript code coverage?

上面一直再讲如何用Qunit来写单元测试,但是很多的时候单元测试是要看覆盖率的。那么在javascript里面怎么做coverage测试呢?
在这里介绍一个专门用于javascript coverage的工具:JSCoverage (官网:http://siliconforks.com/jscoverage/)
先看看和Qunit结合的效果:


再看看coverage的效果:


再看看代码中有哪些没有覆盖:(红色的地方没有覆盖,绿色的地方覆盖)


效果看完了,那是怎么把JSCoverage和QUnit结合起来使用呢?
1》安装JSCoverage
2》新建两个目录(目录名随意),一个叫source,一个叫dest。把需要测试的js文件(例如:XX.js)放在一个目录中(例如,目录名为source)
3》运行jscoverage source dest
4》这样在dest中,就会把XX.js格式化一下,同时也会生成jscoverage.html,jscoverage.css和jscoverage.js等和jscoverage相关的文件。
5》用jscoverage生成的XX.js替换掉原先的xx.js,同时把jscoverage.html,jscoverage.css和jscoverage.js等文件拷贝到相关的目录
6》在浏览器中运行jscoverage.html?xxx.html(xxx.html是用qunit写好的测试代码)

那么JSCoverage是怎么做到的呢?
原来在我们需要测试的代码的开始的地方,声明了一个对象,这个对象通过行号来表示每一行跑过还是没有跑过
if (! _$jscoverage['enginecore.js']) {_$jscoverage['enginecore.js'] = [];_$jscoverage['enginecore.js'][1] = 0;_$jscoverage['enginecore.js'][16] = 0;_$jscoverage['enginecore.js'][17] = 0;_$jscoverage['enginecore.js'][18] = 0;_$jscoverage['enginecore.js'][20] = 0;_$jscoverage['enginecore.js'][23] = 0;_$jscoverage['enginecore.js'][24] = 0;_$jscoverage['enginecore.js'][26] = 0;_$jscoverage['enginecore.js'][27] = 0;
在一个方法中,我们可以看到,对应的代码一旦跑过,在代码开始声明的对象就会记录下来。
ui.engine.ButtonBar.prototype._setItemToHighlightState = (function (index) {_$jscoverage['enginecore.js'][1463]++;var buttonBar = this;_$jscoverage['enginecore.js'][1465]++;var item = buttonBar._getItem(index);_$jscoverage['enginecore.js'][1466]++;var button = buttonBar._getButton(index);_$jscoverage['enginecore.js'][1467]++;item.find(">img").attr("src", button.icon.highlight);
});

参考资料:
Qunit:
1》http://msdn.microsoft.com/en-us/scriptjunkie/gg749824
2》http://www.cnblogs.com/tonyqus/archive/2010/10/31/jquery_tdd_qunit.html
3》http://hetao.im/2011/03/13/%E9%87%87%E7%94%A8tdd%E8%BF%9B%E8%A1%8Cjavascript%E5%BC%80%E5%8F%91
4》http://www.groovyq.net/content/qunit%E5%B0%8F%E8%AE%B0
5》http://www.oncoding.cn/2010/javascript-unit-testing-qunit/
6》http://yue.st/slides/gktest/
7》http://lds2008.blogbus.com/tag/qunit/
8》http://www.weakweb.com/articles/category/javascript%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95

JSCoverage:
http://siliconforks.com/jscoverage/manual.html

JSCoverage & Qunit:
http://www.eviltester.com/index.php/2008/06/08/test-driven-javascript-code-coverage-using-jscoverage/
http://msdn.microsoft.com/zh-tw/scriptjunkie/ff452703.aspx (写到这里,居然发现有了一篇很类似的文章)












												

JavaScript 测试框架 ( QUnit , javascript code coverage , JSCoverage , Pavlov , Jasmine )相关推荐

  1. javascript测试框架mocha

    node测试框架mocha 简单.灵活.有趣,mocha是一个功能丰富的javascript测试框架,运行在node和浏览器中,使异步测试变得更加简单有趣.http://mochajs.org/ 安装 ...

  2. javascript测试框架 Mocha 实例教程

    http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html 转载于:https://www.cnblogs.com ...

  3. 从头搭建rpc框架_#LearnByDIY-如何从头开始创建JavaScript单元测试框架

    从头搭建rpc框架 by Alcides Queiroz 通过Alcides Queiroz #LearnByDIY-如何从头开始创建JavaScript单元测试框架 (#LearnByDIY - H ...

  4. iOS 9 学习系列:Xcode Code Coverage Tools

    2019独角兽企业重金招聘Python工程师标准>>> Code coverage 是一个计算你的单元测试覆盖率的工具.高水平的覆盖给你的单元测试带来信心,也表明你的应用被彻底的测试 ...

  5. Noejs Mocha测试框架

    ㅤㅤㅤ ㅤㅤㅤ ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ(不应当急于求成,应当去熟悉自己的研究对象,锲而不舍,时间会成全一切.凡事开始最难,然而更难的是何以善终.--莎士比亚) ㅤㅤㅤ ㅤㅤㅤ ㅤㅤㅤㅤㅤㅤㅤㅤ ...

  6. React测试框架之enzyme

    简介 Enzyme是由Airbnb开源的一个React的JavaScript测试工具,使React组件的输出更加容易extrapolate .Enzyme的API和jQuery操作DOM一样灵活易用, ...

  7. 前端测试框架(学习之路)前言

    为什么需要单元测试 正确性:测试可以验证代码的正确性,在上线前做到心里有底 自动化:当然手工也可以测试,通过console可以打印出内部信息,但是这是一次性的事情,下次测试还需要从头来过,效率不能得到 ...

  8. 10种JavaScript开发者必备的VS Code插件

    摘要: 好的代码插件可以让工作效率翻倍,心情也更加舒畅! 原文:10 Must-have VS Code Extensions for JavaScript Developers 作者:Michael ...

  9. jasmine单元测试_使用Jasmine,Spock和Nashorn测试JVM服务器端JavaScript

    jasmine单元测试 JavaScript使用不仅限于浏览器中的客户端代码或NodeJS支持的服务器端代码. 许多基于JVM的项目都将其用作内部脚本语言. 测试这种功能既不简单也不标准. 在本文中, ...

最新文章

  1. 2013年6月编程语言排行榜,C语言位据第一位
  2. justify-content与align-items解析
  3. 很好的linux启动说明( bootsect.S、setup.S、head.S)
  4. jquery datatable的详细用法
  5. linux之systemctl设置自定义服务
  6. 浅谈auto与decltype函数的区别
  7. 有关系统环境变量的设置问题
  8. 微软亚洲研究院资深专家、IEEE Fellow帮助您深入细致地学习网络传播模型和算法啦!...
  9. c#UDP发送接收消息
  10. php 判断时间超过5分钟_视频超过5分钟怎么在微信中进行发送
  11. wps2000老版本 v3.02.99
  12. 2019版颱風24、48小時警戒綫(附帶2010版)
  13. 互联网史上10大经典商战
  14. photo的复数是photos
  15. 解决Extraneous non-props attributes (border, class) were passed to component but could not be
  16. 【2023年1月·第二周】-单词学习记录(1月9日-1月15日)
  17. 大数据的理解,大数据是什么,大数据能干什么?
  18. 游戏模型:不是天生,不用PS,3DMax教你怎么拥有长长的睫毛
  19. 信奥一本通-动态规划-例9.2-数字金字塔-方法四-逆推法代码实现
  20. NCUT 数据库基础 铁路购票系统

热门文章

  1. Ubuntu 18.04上安装Skype
  2. 手机短信数据恢复大全
  3. Unity3D 2019版-UI技巧,将物体/模型置于UI前,将物体/模型置于UI后,将物体/模型置于UI中
  4. 【原创】写在百度一面后 (原网易博客搬迁过来)
  5. cnzz广告管家使用心得
  6. 安装配置操作节点(Operator),并获取OCP离线安装文件
  7. 音悦Tai-音悦商城项目(专辑页面以及商品购买页面)
  8. 《增长黑客》阅读笔记(纲要)
  9. JavaFX鼠标拖拽移动图片
  10. 开心斗地主小游戏代码