什么是单元测试
  每个单元测试就是一段用于测试一个模块或接口是否能达到预期结果的代码。

QUnitjs

概念
Qunit是一款强大的用于帮助调试代码的,JavaScript单元测试框架。是jQuery的官方测试套件,不仅如此,QUnit还可以测试任何常规JavaScript代码,甚至可以通过一些像Rhino或者V8这样的JavaScript引擎,测试服务端JavaScript代码。

[官网](http://qunitjs.com/)

开始: hello wolrd
1. 目前版本:2.0.1
2. 需要链接QUnit的js资源和css资源(可以npm下载,官网下载,链接静态资源)
3. 简单的测试案例

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="node_modules/qunitjs/qunit/qunit.css">
<script src="node_modules/qunitjs/qunit/qunit.js"></script>
</head>
<body>
<!--页面输出标记-->
<h1 id="qunit-header">QUnit Hello World</h1>
<h2 id="qunit-banner"></h2>
<ol id="qunit-tests"></ol>
<script>
// 2.*
QUnit.test("hello", function(assert) {
assert.ok(true, "wolrd");
});
// 1.*
test("hello", function() {
ok(true, "wolrd");
});
</script>
</body>
</html>

  

4. 上述案例定义了一个名为hello的测试(test),在页面载入完毕的时候运行;test的第二个参数为测试函数;ok方法接收两个参数:第一个是表明测试是否通过,第二个是需要输出的信息。
5. 上述案例声明了两个版本的测试。2.*版本的全局方法test()被QUnit.test()替代,详细的版本语法区别见<http://qunitjs.com/upgrade-guide-2.x/>;

6. 效果图

二 HTML部分的标记
1. html部分

<body>
<!--页面输出标记-->
<h1 id="qunit-header">QUnit测试</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">
<input id="input" type="text" placeholder="placeholder text" />
</div>>
</body>

2. 效果图


3. toolbar调试工具
  1. Hide passed tests“隐藏通过的测试”,勾选后,通过的测试就不显示了。
  2. Check for Global “全局检测”。 如果勾选此项,在运行测试之前,QUnit会枚举window所有属性,然后与运行结束之后的window做比较,如果前后不一样,就会显示不通过-failed, 以及显示“引入或缺失全局属性”。**该工具作用在于可以很容易被发现判断导致全局变量的引入.**
  3. No try-catch "不要try-catch". **选中则意味着QUnit会在try-catch语句外运行回调,此时,如果测试出现异常,测试就会停止。**这有什么用呢?要知道,有些浏览器的调试工具是相当弱的,尤其IE6,一个未处理的异常要比捕获的异常可以提供更多的信息。即使再次抛出,由于JavaScript不擅长异常处理,原来的堆栈跟踪在大多数浏览器里都丢失了。
  4. toolbar的filter类似于搜索
  5. toolbar的Module可选择module
  6. (原子性)如果要测试DOM修改,我们可以使用***#qunit-fixture***元素。在做测试的时候,这个静态标记你**可以随便置空或append元素**,每个测试结束的时候QUnit会自动把**#qunit-fixture**元素的innerHTML属性值设置为初始值。如果可以使用jQuery,QUnit会使用jQuery的html()方法代替,同时清除jQuery事件句柄。

QUnit.module('qunit-fixture');
QUnit.test( "Appends a span", function( assert ) {
var fixture = $( "#qunit-fixture");
fixture.append( "<span>hello!</span>");
assert.equal( $( "span", fixture ).length, 1, "span added successfully!" );
});
QUnit.test( "Appends a span again", function( assert ) {
var fixture = $( "#qunit-fixture");
fixture.append("<span>hello!</span>");
assert.equal( $( "span", fixture ).length, 1, "span added successfully!" );
});

  

部分API  [详细文档](http://api.qunitjs.com/)

test
  1. module 分组

QUnit.module("M one",{
before: function(assert) {//在M one的第一个test前执行
console.log(assert);
},
after: function(assert) {//在M one的最后一个test后执行
console.log(assert);
}
});

  2. test

QUnit.test('test b', function(assert) {
  assert.ok(true, 'true is passed');
  assert.ok(1 ,"1 is passed");
  assert.ok(2, '2 is passed');
  assert.ok(new Object(), 'object is pass');
  assert.ok(2>1,'2>1 is passed');
  assert.ok(" ","' ' is passed");
  assert.ok([],'[] is passed');
});

在下一个module出来之前,M one之后的test都属于M one
Assert
  1. ok()上面已经提到
  2. equal()

function add (a,b) {
return a + b + 1;
}
QUnit.test("test a", function(assert) {
assert.ok(add(1,2) === 4, 'add is true');
assert.equal(add(1,2) , 4 , 'add is true');
});

接收三个参数,参数一与参数二相等则为true否则为false,参数三为输出信息.

  3. notEqual,deepEqual, notDeepEqual,strictEqual,notStrictEqual,propEqual,notPropEqual

QUnit.test('test-assert', function(assert) {
assert.equal(1,'1','相等');//将参一和参二进行比较(==) 相等则通过
assert.notEqual(1,2,'不相等');//不相等,则通过
assert.strictEqual(1,1,'全相等');//将参一和参二进行比较(===) 全相等则通过
assert.notStrictEqual(1,'1','不全相等');//不全相等则通过
assert.deepEqual({foo:1},{foo:'1'},'对象相等');//深度比较,如果是对象,则将值进行简单对比(相当于==),只有相等才能通过。
assert.notDeepEqual({foo:1},{foo:'2'},'对象不相等');
assert.propEqual({foo:1},{foo:1},'对象全等');//深度比较,如果是对象 则将值进行全等比较;
assert.notPropEqual({foo:1},{foo:'1'},'对象不全等');
});

notEqual: 将参一和参二进行比较(==) 不相等则通过

strictEqual: 将参一和参二进行比较(===) 全相等则通过
deepEqual: 深度比较,如果是对象,则将值进行简单对比(相当于==),只有相等才能通过
propEqual: 深度比较,如果是对象 则将值进行全等比较

4. expect()

QUnit.test("mulipile call done()",function(assert){
assert.expect(3);
assert.equal(1,'1','相等');
assert.notEqual(1,2,'不相等');
});
QUnit.test("mulipile call done()",function(assert){
assert.expect(3);
var done = assert.async(3);
setTimeout(function(){
assert.ok( true, "first call done." );
done();
},100);
setTimeout(function(){
assert.ok(true,"second call done");
done();
},300);
setTimeout(function(){
assert.ok(true,"third call done.");
done();
},200);
});

测试回调的时候,无论是不是异步,我们都不能确定回调会在某些时候被真正调用了。为了应付这种状况,可以使用expect(), 定义一个测试中我们**期望的判断个数**。这样就可以避免本应出现两个判别结果的,结果一个通过后就停止的情况。

Async Control

//模拟数据
Mock.mock('http://lhy', {
'name' : 'name@lhy',
'age|10-28': 20
});
//定义module
QUnit.module('m-ajax');
function ajax(successCallback) {
$.ajax({
url: 'http://lhy',
dataType: 'json',
success: function(data){
successCallback(data)
}
});
}
QUnit.test('test-ajax', function(assert) {
var done = assert.async();
var obj;
ajax(function(val){
obj = val;
console.log(val);
});
setTimeout(function(){
assert.ok(typeof obj === 'object','ajax返回的数据类型正确');
done();
},200);
});

也可以QUnit.start()与QUnit.stop()来控制异步回调中断言的判断。

callbacks
  1. begin()

QUnit.begin(function(tests){
  console.log(tests);
  console.log(tests.totalTests);
});

在所有test之前被调用一次。tests包括totalTests(test的数量)和modules(module的数组).

  2. done

QUnit.done(function( details ) {
console.log( "Total: ", details.total, " Failed: ", details.failed, " Passed: ", details.passed, " Runtime: ", details.runtime );
});

在test结束之后调用,details包括failed(失败的断言数),total(总断言数),passed(通过的断言数),runtime(所有test执行完所用的时间)

Configuration and Utilities
  assert 断言

自定义判断
  1. 定义

QUnit.assert.mod2 = function(value, expected,message) {
  var actual = value % 2;
  this.push(actual === expected ,actual ,expected,message);
}; 

2. 使用

QUnit.test("mod2",function(assert) {
  assert.expect(2);
  assert.mod2(2, 0, "2 % 2 == 0");
  assert.mod2(3, 1, "3 % 2 == 1");
});

example:判断设备

//判断是否是pc
function IsPC() {
  var userAgentInfo = navigator.userAgent;
  var Agents = new Array("Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod");
  var flag = true;
  for (var v = 0; v < Agents.length; v++) {
    if (userAgentInfo.indexOf(Agents[v]) > 0) {
      flag = false;
      break;
    }
  }
  return flag;
}
//判断是Android还是iOS
function getOSType() {
  if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {
    return "IOS";
  } else if (/(Android)/i.test(navigator.userAgent)) {
    return "Android";
  } else {
    return "other";
  }
}
QUnit.module("M one");
  QUnit.test('test-device', function(assert) {
  assert.ok(IsPC(), 'this is PC');
  assert.ok(getOSType()=='Android', 'this is Android');
});  

PC运行截图:

Android端运行截图:

QUnit使用的更多相关文章

  1. qunit 前端脚本测试用例

    首先引用qunit 测试框架文件 <link rel="stylesheet" href="qunit-1.22.0.css"> <scrip ...

  2. Cookbook of QUnit

    本篇文章是QUnit的简介,可以作为很好的入门教程.文章原址 介绍 自动化测试时软件开发过程中必不可少的一部分,而单元测试则是自动化测试的最为基本的一块,软件的每一个组件, 每一个功能单元都需要经过不 ...

  3. 使用QUnit进行自动化单元测试

    前言 前阵子由于项目需求接触了java的单元测试JUnit,就顺带着学习了前端的单元测试:Qunit. 既然跟测试有关,不妨介绍一下测试中的黑盒测试.白盒测试以及单元测试. 1.黑盒测试:所谓的黑盒, ...

  4. JavaScript测试工具比较: QUnit, Jasmine, and Mocha

    1. QUnit A JavaScript Unit Testing framework. QUnit is a powerful, easy-to-use JavaScript unit testi ...

  5. 在requirejs中使用qunit

    requirejs(['QUnit'], function(qunit) { qunit.test('test name', function(assert) { // 一些测试, assert }) ...

  6. Javascript单元测试之QUnit

    首先去Qunit官网下载. Qunit有一个js脚本文件和一个css我们在页面中引入它. <script src="qunit-2.0.1.js"></scrip ...

  7. Javascript单元测试Unit Testing之QUnit

    body{ font: 16px/1.5em 微软雅黑,arial,verdana,helvetica,sans-serif; }           QUnit是一个基于JQuery的单元测试Uni ...

  8. qunit学习(一)

    QUnit是一个强大的JavaScript单元测试框架,用于调试代码.该框架是由jQuery团队的成员所开发,并且是jQuery的官方测试套件.任意正规JavaScript代码QUnit都能测试. 其 ...

  9. QUnit使用笔记-5简化编写

    在测试中,如果用到了大量相同的方法返回判断结果,可以将他们简化; 使用push(): push( result/*boolean,result of assert*/, actual, /*objec ...

  10. QUnit使用笔记-4保持原子性与分组

    原子性: 当将许多测试用例放到一起测试的时候,可能会因为相互的副作用而出错:这个时候应该尽可能将他们分别放到test()中测试: 对应测试到Dom,应该尽可能地使用#qunit-fixture,因为它 ...

随机推荐

  1. [HAOI2015]T2

    [题目描述] 有一棵点数为N的树,以点1为根,且树点有边权.然后有M个操作,分为三种: 操作1:把某个节点x的点权增加a. 操作2:把某个节点x为根的子树中所有点的点权都增加a. 操作3:询问某个节点 ...

  2. LeetCode——Decode String

    Question Given an encoded string, return it's decoded string. The encoding rule is: k[encoded_string ...

  3. linux怎么上真正的国际互联网

    1.安装git yum install -y git 2.执行git clone git@github.com:XX-net/XX-Net.git 3.升级python到python 2.7(妈妈说p ...

  4. saga+.net core 分布式事务处理

    Apache ServiceComb Saga 是一个微服务应用的数据最终一致性解决方案 中文官方地址:https://github.com/apache/servicecomb-saga/blob/ ...

  5. dpdk CUSE

    As the Userspace I/O HOWTO says For many types of devices, creating a Linux kernel driver is overkil ...

  6. springboot统一异常处理及返回数据的处理

    一.返回code数据的处理 代码: Result.java /** * http请求返回的最外层对象 * Created by 廖师兄 * 2017-01-21 13:34 */ public cla ...

  7. Ubuntu下配置Nginx+PHP

    1.安装Nginxapt-get install nginx 2.启动Nginxservice nginx start 3.访问服务器IP 如果看到“Welcome to nginx!”说明安装好了. ...

  8. nyoj——弃九法

    A*B Problem 时间限制:1000 ms  |  内存限制:65535 KB 难度:2   描述 设计一个程序求出A*B,然后将其结果每一位相加得到C,如果C的位数大于等于2,继续将C的各位数 ...

  9. python3.6环境部署文档

    python3.6环境部署文档   内容 Linux部署Python3.6环境 Mac部署Python3.6环境 Window10部署Python3.6环境 Pycharm安装 1. Linux部署P ...

  10. jquery下跨域请求之代码示例

    场景描述: 在域A下异步获取B域下的接口: 实现方法: $.ajax({ url : (Q.lottery.serverTimeUrl || 'about:blank'), error : funct ...