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

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. POJ-2418 Hardwood Species(二叉搜索树)

    思路就是先将每个单词存进二叉树中,没出现一次,修改该单词所在结点的cnt++: 最后通过递归中序遍历输出结果. 思路很清晰,主要注意一下指针的使用,想一想为什么要这么用? 简单的解释就是,insert ...

  2. ISSCC 2017论文导读 Session 14 Deep Learning Processors,A 2.9TOPS/W Deep Convolutional Neural Network SOC

    最近ISSCC2017大会刚刚举行,看了关于Deep Learning处理器的Session 14,有一些不错的东西,在这里记录一下. A 2.9TOPS/W Deep Convolutional N ...

  3. [解决]JS失效,提示HTML1114: (UNICODE 字节顺序标记)的代码页 utf-8 覆盖(META 标记)的冲突的代码页 utf-8

    上网找了找,木有找到相关的解决办法,索性自己试了试. 原页面是这样写的: <html> <head> <meta http-equiv="Content-Typ ...

  4. Python基础笔记系列十四:python无缝调用c程序

    本系列教程供个人学习笔记使用,如果您要浏览可能需要其它编程语言基础(如C语言),why?因为我写得烂啊,只有我自己看得懂!! python语言可以对c程序代码进行调用,以弥补python语言低性能的缺 ...

  5. SSH密钥登陆免密码方法

    原帖地址:http://ask.apelearn.com/question/798 用Putty实现A机器远程登陆B机器,具体实现请看链接:http://www.cnblogs.com/ImJerry ...

  6. FTRL 使用tensorflow的实现

    import tensorflow as tfimport numpy as npfrom sklearn import metricsfrom sklearn.datasets import loa ...

  7. Linux查看和剔除当前登录用户

    Linux查看和剔除当前登录用户 如何在linux下查看当前登录的用户,并且踢掉你认为应该踢掉的用户? 看了网络中的一些例子.在这里总结一下.主要用到的命令有,w,who,ps,kill,pkill ...

  8. Python编程

    1.pip的使用.安装 pip show 显示输出版本 pip -V 是否安装成功 pip --help 查看相关帮助

  9. 翻译"Python编程无师自通——专业程序员的养成"

    这本书在 畅销Python编程类入门书,美国亚马逊Kindle编程类排行榜榜一. 开始初学python,也有不少书了,不想在白花钱(买了就放那里不看了),看一个英文文档的原著,准备每天翻译一点,放到b ...

  10. 【MySQL】查看当前存储引擎

    一般情况下,mysql会默认提供多种存储引擎,你可以通过下面的查看: 看你的mysql现在已提供什么存储引擎: mysql> show engines; 看你的mysql当前默认的存储引擎: m ...