1.新建一个html页面,如下
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Collection Test</title>
<link rel="stylesheet" href="SlickGrid/lib/qunit.css" type="text/css"/>
<script type="text/javascript" src="SlickGrid/lib/qunit.js">
</script>
<script type="text/javascript" src="collections.js">
</script>
<script type="text/javascript" src="ArrayListTest.js">
</script>
<script type="text/javascript" src="MapTest.js">
</script>
</head>
<body>
<h1 id="qunit-header">ArrayList And Map Test</h1>
<h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests">
</ol>
<div id="qunit-fixture">
</div>
</body>
</html>
在页面中引入qunit.js和qunit.css, 可以去官网下载:http://qunitjs.com/
引入你要测试的js
// 封装ArrayList类,用法与java类似。
(function(win){
var ArrayList = function(array){
var datas = []; this.setDatas = function(value){
datas = value;
}; this.getDatas = function(){
return datas;
}; if (array && Object.prototype.toString.call(array) === "[object Array]") {
this.setDatas(array);
}
}; var proto = ArrayList.prototype; // ArrayList的大小
proto.size = function(){
return this.getDatas().length;
}; // 判断是否为空
proto.isEmpty = function(){
return this.size() === 0;
}; // 判断是否包含指定的值
proto.contains = function(value){
return this.indexOf(value) !== -1;
}; // 查找指定的值,如果找到,返回它所在的数组下标
proto.indexOf = function(value){
var datas = this.getDatas(); for (var index = 0, len = datas.length; index < len; index++) {
if (datas[index] === value) {
return index;
}
} return -1;
}; // 从后往前找指定的值
proto.lastIndexOf = function(value){
var datas = this.getDatas(); for (var index = datas.length - 1; index >= 0; index--) {
if (datas[index] === value) {
return index;
}
} return -1;
}; // 把ArrayList转化为数组
proto.toArray = function(){
return this.getDatas();
}; // 判断是否超出范围
proto.outOfBound = function(index){
return index < 0 || index > (this.size() - 1);
}; // 根据位置取得指定的值
proto.get = function(index){
var datas = this.getDatas(); if (this.outOfBound(index)) {
return null;
} return datas[index];
}; // 根据位置设置指定的值
proto.set = function(index, value){
var datas = this.getDatas();
datas[index] = value;
}; // 增加指定的值
proto.add = function(value){
var datas = this.getDatas();
datas.push(value);
}; // 在指定的位置插入值
proto.insert = function(index, value){
var datas = this.getDatas(); if (this.outOfBound(index)) {
return false;
} datas.splice(index, 0, value);
return true;
}; // 删除指定位置的值
proto.remove = function(index){
var datas = this.getDatas(); if (this.outOfBound(index)) {
return false;
} datas.splice(index, 1);
return true;
}; // 删除指定的值
proto.removeValue = function(value){
if (this.contains(value)) {
this.remove(this.indexOf(value));
return true;
}
return false;
}; // 清空ArrayList
proto.clear = function(){
this.getDatas().length = 0;
}; // 把另一个ArrayList添加到当前ArrayList中
proto.addAll = function(list){
if (!list instanceof ArrayList) {
return false;
} var datas = list.getDatas();
for (var index = 0, len = datas.length; index < len; index++) {
this.add(list.get(index));
} return true;
}; // 在指定位置插入一个ArrayList
proto.insertAll = function(index, list){
if (this.outOfBound(index)) {
return false;
} if (!list instanceof ArrayList) {
return false;
} var pos = index;
var datas = list.getDatas();
for (index = 0, len = datas.length; index < datas.length; index++) {
this.insert(pos++, list.get(index));
} return true;
}; // 按数字排序
function numberorder(a, b){
return a - b;
} // 排序,isNumber为true表示按数字排序
proto.sort = function(isNumber){
var datas = this.getDatas(); if (isNumber) {
datas.sort(numberorder);
}
else {
datas.sort();
}
}; // 重写toString方法
proto.toString = function(){
var datas = this.getDatas();
return "[" + datas.join() + "]";
}; // 重写valueOf方法
proto.valueOf = function(){
return this.toString();
}; win.ArrayList = ArrayList;
})(window); // 封装map类,用法与java类似
(function(win){
var Map = function(obj){
var count = 0;
var entrySet = {}; this.setCount = function(value){
count = value;
}; this.getCount = function(){
return count;
}; this.setEntrySet = function(value){
entrySet = value;
}; this.getEntrySet = function(){
return entrySet;
}; if (obj && Object.prototype.toString.call(obj) === "[object Object]") {
this.setEntrySet(obj); var key = null;
for (key in obj) {
count++;
}
}
}; var proto = Map.prototype; // map的大小
proto.size = function(){
return this.getCount();
}; // 判断map是否为空
proto.isEmpty = function(){
return this.size() === 0;
}; // 判断map是否包含指定的key
proto.containsKey = function(key){
if (this.isEmpty()) {
return false;
} var entrySet = this.getEntrySet();
return entrySet.hasOwnProperty(key);
}; // 判断map是否包含指定的值
proto.containsValue = function(value){
var entrySet = this.getEntrySet(); if (this.isEmpty()) {
return false;
} var key = null;
for (key in entrySet) {
if (entrySet[key] === value) {
return true;
}
} return false;
}; // 根据key取得相应的value
proto.get = function(key){
var entrySet = this.getEntrySet(); if (this.isEmpty()) {
return null;
} if (this.containsKey(key)) {
return entrySet[key];
} return null;
};
// 把键值对放入到map中
proto.put = function(key, value){
var entrySet = this.getEntrySet(); if (!entrySet.hasOwnProperty(key)) {
var count = this.getCount();
this.setCount(count + 1);
} entrySet[key] = value;
this.setEntrySet(entrySet);
}; // 移除指定键值对
proto.remove = function(key){
if (this.isEmpty()) {
return false;
} if (this.containsKey(key)) {
var entrySet = this.getEntrySet();
var count = this.getCount();
delete entrySet[key];
count--;
this.setCount(count);
this.setEntrySet(entrySet);
return true;
}
else {
return false;
}
}; // 把指定map放入到当前map中
proto.putAll = function(map){
if (!map instanceof Map) {
return false;
} var entrySet = map.getEntrySet(); var key = null;
for (key in entrySet) {
this.put(key, entrySet[key]);
} return true;
}; // 清除当前map
proto.clear = function(){
this.setEntrySet({});
this.setCount(0);
}; // 取得当前map中的所有值,返回 一个数组
proto.values = function(){
var result = []; var entrySet = this.getEntrySet();
var key = null;
for (key in entrySet) {
result.push(entrySet[key]);
} return result;
}; // 取得当前map中的所有键,返回一个数组
proto.keySet = function(){
var result = []; var entrySet = this.getEntrySet();
var key = null;
for (key in entrySet) {
result.push(key);
} return result;
}; proto.entrySet = function(){
return this.getEntrySet();
}; // 重写toString方法
proto.toString = function(){
var result = []; var entrySet = this.getEntrySet();
var key = null;
for (key in entrySet) {
result.push(key + ":" + entrySet[key]);
} return "{" + result.join() + "}";
}; // 重写valueOf方法
proto.valueOf = function(){
return this.toString();
}; win.Map = Map;
})(window);
引入你将要编写的测试的js
body里的内容固定如上图。
2.写自己的测试代码
(function(){
var list = null; module("ArrayList", {
setup: function(){
list = new ArrayList();
},
teardown: function(){
list = null;
}
}); test("constructor", function(){
ok(list.isEmpty(), "new ArrayList() is Empty.");
list = new ArrayList([1, 2, 3, 4]);
equals(4, list.size(), "new ArrayList([1,2,3,4]), list.size()");
list = new ArrayList(null);
equals(0, list.size(), "new ArrayList(null), list.size()");
}); test("setDatas", function(){
list.setDatas([8, 6, 3, 7, 9]);
equals(5, list.size(), "list.setDatas([8,6,3,7,9]); list.size()");
equals("[8,6,3,7,9]", list.toString(), "list.toString()");
}); test("getDatas", function(){
list.setDatas([8, 6, 3, 7, 9]);
equals(5, list.getDatas().length, "list.setDatas([8,6,3,7,9]); list.getDatas().length");
equals("8,6,3,7,9", list.getDatas().toString(), "list.getDatas().toString()");
}); test("size", function(){
equals(0, list.size(), "only call constructor, list.size()");
list.add(1);
list.add(2);
list.add(3);
equals(3, list.size(), "call add method three times, list.size()");
}); test("isEmpty", function(){
equals(true, list.isEmpty(), "only call constructor, list.isEmpty()");
list.add(1);
equals(false, list.isEmpty(), "call add method one times, list.isEmpty()");
}); test("contains", function(){
list.add(1);
list.add(2);
equals(true, list.contains(1), "list is [1,2], list.contains(1)");
equals(true, list.contains(2), "list is [1,2], list.contains(2)");
equals(false, list.contains(3), "list is [1,2], list.contains(3)");
}); test("indexOf", function(){
list.add(1);
list.add(2);
equals(0, list.indexOf(1), "list is [1,2], list.indexOf(1)");
equals(1, list.indexOf(2), "list is [1,2], list.indexOf(2)");
equals(-1, list.indexOf(3), "list is [1,2], list.indexOf(3)");
}); test("lastIndexOf", function(){
list.add(1);
list.add(2);
equals(0, list.lastIndexOf(1), "list is [1,2], list.lastIndexOf(1)");
equals(1, list.lastIndexOf(2), "list is [1,2], list.lastIndexOf(2)");
equals(-1, list.lastIndexOf(3), "list is [1,2], list.lastIndexOf(3)");
}); test("toArray", function(){
list.add(1);
list.add(2);
equals("1,2", list.toArray().toString(), "list is [1,2], list.toArray() is");
same(list.getDatas(), list.toArray());
}); test("outOfBound", function(){
list.add(1);
list.add(2);
same(true, list.outOfBound(-1), "list is [1,2], list.outOfBound(-1) is");
same(false, list.outOfBound(0), "list is [1,2], list.outOfBound(0) is");
same(false, list.outOfBound(1), "list is [1,2], list.outOfBound(1) is");
same(true, list.outOfBound(2), "list is [1,2], list.outOfBound(2) is");
}); test("get", function(){
list.add("jack");
list.add("mary");
same("jack", list.get(0), "list is [jack, mary], list.get(0) is");
same("mary", list.get(1), "list is [jack, mary], list.get(1) is");
}); test("set", function(){
list.add("jack");
list.set(1, "mary");
same("mary", list.get(1), 'list.set(1, "mary"); list.get(1) is');
list.set(0, "mike");
same("mike", list.get(0), 'list.set(0, "mike"); list.get(0) is');
}); test("add", function(){
list.add(10);
list.add(20);
equal(10, list.get(0), "list add after is [10,20], list.get(0) is");
equal(20, list.get(1), "list add after is [10,20], list.get(1) is");
}); test("insert", function(){
list.add(10);
list.add(20);
list.insert(0, 30);
equal(30, list.get(0), "list is [10,20], list.insert(0, 30), list.get(0) is");
list.insert(2, 6);
equal(6, list.get(2), "list is [30,10,20], list.insert(2, 6), list.get(2) is");
}); test("remove", function(){
list.add(1);
list.add(2);
equal(true, list.remove(0), "list is [1, 2], list.remove(0) is ");
list.clear();
equal(false, list.remove(0), "list is [], list.remove(0) is ");
}); test("removeValue", function(){
list.add("jack");
list.add("mike");
equal(true, list.removeValue("jack"), "list is ['jack', 'mike'], list.removeValue('jack') is");
list.clear();
equal(false, list.removeValue("jack"), "list is [], list.removeValue('jack') is");
}); test("clear", function(){
list.add(10);
list.add(20);
ok(!list.isEmpty(), "Before call clear, list is " + list.toString());
list.clear();
ok(list.isEmpty(), "After call clear, list is " + list.toString());
}); test("addAll", function(){
var tmpList = new ArrayList([10, 20]);
list.addAll(tmpList);
same(list.getDatas(), tmpList.getDatas(), "tmpList is [10,20], list.addAll(tmpList), list is ");
}); test("insertAll", function(){
var tmpList = new ArrayList([10, 20]);
list.add(30);
list.insertAll(0, tmpList);
same(10, list.get(0), "tmpList is [10,20], list is [30], list.insertAll(0, tmpList), list.get(0) is ");
same(20, list.get(1), "tmpList is [10,20], list is [30], list.insertAll(0, tmpList), list.get(1) is ");
same(30, list.get(2), "tmpList is [10,20], list is [30], list.insertAll(0, tmpList), list.get(2) is ");
same(3, list.size(), "list.size() is ");
}); test("sort", function(){
list.setDatas([6, 9, 3, 1, 5]);
list.sort(true);
same("[1,3,5,6,9]", list.toString(), "list is [6,9,3,1,5], list.sort(true), list is ");
list.clear();
list.setDatas([4, 33, 222, 1111]);
list.sort();
same("[1111,222,33,4]", list.toString(), "list is [4,33,222,1111], list.sort(), list is ");
}); test("toString", function(){
list.setDatas([6, 9, 3]);
same("[6,9,3]", list.toString(), "list is [6, 9, 3], list.toString() is ");
}); test("valueOf", function(){
list.setDatas([6, 9, 3]);
same("[6,9,3]", list.valueOf(), "list is [6, 9, 3], list.toString() is ");
});
})();
(function(){
var map = null; module("Map", {
setup: function(){
map = new Map();
map.put("v001", "jack");
map.put("v002", "mike");
},
teardown: function(){
map = null;
}
}); test("constructor", function(){
map = new Map();
ok(map.isEmpty(), "only call constructor, map is empty.");
map = new Map({
'v001': 'jack',
'v002': 'mike'
});
equal("jack", map.get('v001'), "new Map({'v001' : 'jack', 'v002': 'mike'}), map.get('v001') is");
equal("mike", map.get('v002'), "new Map({'v001' : 'jack', 'v002': 'mike'}), map.get('v002') is");
}); test("put size", function(){
equal(2, map.size(), "call put two times, the key not same, map.size() is");
map.put("v002", "lucy");
equal(2, map.size(), "call put three times , the last time, the key is repeat, map.size() is");
}); test("isEmpty", function(){
equal(false, map.isEmpty(), "call put two times, map.isEmpty() is");
}); test("containsKey", function(){
equal(true, map.containsKey("v001"), "map is {'v001' : 'jack', 'v002': 'mike'}, map.containsKey('v001') is");
equal(true, map.containsKey("v002"), "map is {'v001' : 'jack', 'v002': 'mike'}, map.containsKey('v002') is");
equal(false, map.containsKey("v003"), "map is {'v001' : 'jack', 'v002': 'mike'}, map.containsKey('v003') is");
}); test("containsValue", function(){
equal(true, map.containsValue("jack"), "map is {'v001' : 'jack', 'v002': 'mike'}, map.containsValue('jack') is");
equal(true, map.containsValue("mike"), "map is {'v001' : 'jack', 'v002': 'mike'}, map.containsValue('mike') is");
equal(false, map.containsValue("lucy"), "map is {'v001' : 'jack', 'v002': 'mike'}, map.containsValue('lucy') is");
}); test("get", function(){
equal("jack", map.get("v001"), "map is {'v001' : 'jack', 'v002': 'mike'}, map.get('v001') is");
equal("mike", map.get("v002"), "map is {'v001' : 'jack', 'v002': 'mike'}, map.get('v002') is");
}); test("remove", function(){
equal(true, map.remove("v001"), "map is {'v001' : 'jack', 'v002': 'mike'}, map.remove('v001') is");
equal(false, map.remove("v003"), "map is {'v001' : 'jack', 'v002': 'mike'}, map.remove('v003') is");
}); test("putAll", function(){
var map2 = new Map();
map2.putAll(map);
equal(map.size(), map2.size(), "map2 is empty, map2.putAll(map), map2.size() is ");
}); test("clear", function(){
equal(2, map.size(), "before call clear method, map.size() is ");
map.clear();
equal(0, map.size(), "after call clear method, map.size() is ");
}); test("values", function(){
equal('jack,mike', map.values().join(), "map is {'v001' : 'jack', 'v002': 'mike'}, map.values() is ");
}); test("keySet", function(){
equal('v001,v002', map.keySet().join(), "map is {'v001' : 'jack', 'v002': 'mike'}, map.keySet() is ");
}); test("entrySet", function(){
var map2 = new Map(map.entrySet());
equal('{v001:jack,v002:mike}', map2.toString(), "map is {'v001' : 'jack', 'v002': 'mike'}, map.entrySet() is ");
}); test("toString", function(){
equal('{v001:jack,v002:mike}', map.toString(), "map is {'v001' : 'jack', 'v002': 'mike'}, map.toString() is ");
}); test("valueOf", function(){
equal('{v001:jack,v002:mike}', map.valueOf(), "map is {'v001' : 'jack', 'v002': 'mike'}, map.valueOf() is ");
});
})();
module有两个主要的方法:setup和teardown, 分别是在方法调用前和调用后执行。
test("", function(){}); 表示执行一个测试用例
用于诊断的方法主要有:equals、equal、same、deepEqual、notEqual、notDeepEqual、strictEqual、notStrictEqual、ok、expect
详细用法见官方文档。