JavaScript基础笔记(十三)测试和调试
错误处理与测试
一、错误处理
一)try-catch语句
function atest() {
try {
//可能发生错误的代码
return 0;
} catch (error) {
//错误处理程序
console.log(error.message);
return 1;
} finally {
//无论如何都会执行的,函数最后返回2
return 2;
}
}
错误类型:
1)Error:错误基类,其他错误类型都由该类继承。
2)EvalError:没有把eval()当函数调用时,会发送该错误。
3)RangeError:数值超出范围
4)ReferenceError:找不到对象时
5)SyntaxError:传入eval()函数的语法错误时
6)TypeError:变量的类型不符合要求
合理使用try-catch:
使用 try-catch 最适合处理那些我们无法控制的错误。假设你在使用一个大型 JavaScript 库中的
函数,该函数可能会有意无意地抛出一些错误。由于我们不能修改这个库的源代码,所以大可将对该函
数的调用放在 try-catch 语句当中,万一有什么错误发生,也好恰当地处理它们。
在明明白白地知道自己的代码会发生错误时,再使用 try-catch 语句就不太合适了。例如,如果
传递给函数的参数是字符串而非数值,就会造成函数出错,那么就应该先检查参数的类型,然后再决定
如何去做。在这种情况下,不应用使用 try-catch 语句。
二)抛出错误
使用throw操作符可以抛出错误,对抛出的值没有要求
//有效
throw 111;
throw ''ss;
在遇到 throw 操作符时,代码会立即停止执行。仅当有 try-catch 语句捕获到被抛出的值时,代
码才会继续执行。
通过使用某种内置错误类型,可以更真实地模拟浏览器错误。每种错误类型的构造函数接收一个参
数,即实际的错误消息。
throw new Error("An error");
何时抛出与捕获:
只应该捕获那些你确切地知道该如何处理的错误。捕获错误的
目的在于避免浏览器以默认方式处理它们;而抛出错误的目的在于提供错误发生具体原因的消息。
三)错误事件
任何没有通过 try-catch 处理的错误都会触发 window 对象的 error 事件 ,在任何 Web 浏览器中, onerror 事件处理程序都不会创建 event 对象,
但它可以接收三个参数:错误消息、错误所在的 URL 和行号 。要指定 onerror 事件处理程序,必须使用如下所示的 DOM0 级技术,它没有遵循“DOM2 级
事件”的标准格式。
window.onerror = function(msg, url, line) {
log(msg);
//阻止浏览器报告错误的行为
return fales;
}
二、测试
一)日志记录
//一个适用于所有浏览器的log
function log() {
try {
console.log.apply(console, arguments);
}
catch(e) {
try {
opera.postError.apply(opera, arguments);
}
catch (e) {
alert(Array.prototype.join.call(arguments, " "));
}
}
}
二)测试用例
一个好的测试用例的三个特征:
1)可重用性:多次运行应该产生相同的结果
2)简单性:只专注与测试,消除多余代码的影响
3)独立性:避免一个测试结果依赖于另一个结果
三)测试套件
测试套件的主要目的是聚合代码种的所有单个测试,将其组合成一个单位,这样他们可以批量运行,提供一个可以轻松反复运行的单一资源。
1)断言:
自己实现一个断言:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<style>
#results li.pass {
color: green;
}
#results li.fail {
color: red;
}
</style>
<body>
<ul id="results"></ul>
</body>
</html>
<script>
function assert(value, desc) {
var liElement = document.createElement("li");
liElement.className = value ? "pass" : "fail";
liElement.appendChild(document.createTextNode(desc));
document.getElementById("results").appendChild(liElement);
}
window.onload = function () {
assert(true, "Success");
assert(false, "Fail");
}
</script>
2)测试分组的实现:
(function () {
var results;
this.assert = function assert(value, desc) {
var li = document.createElement("li");
li.className = value ? "pass" : "fail";
li.appendChild(document.createTextNode(desc));
results.appendChild(li);
if (!value) {
li.parentNode.parentNode.className = "fail";
}
return li;
} this.test = function test(name, fn) {
results = document.getElementById("results");
results = assert(true, name).
appendChild(document.createElement("ul"));
fn();
}
})(); window.onload = function (ev) {
test("all true", function () {
assert(true, "111");
assert(true, "222");
assert(true, "333");
});
test("one false", function () {
assert(false, "failed");
assert(true, "success");
assert(true, "xxx");
});
}
3)异步测试
(function () {
var queue = [], paused = false, results;
this.assert = function assert(value, desc) {
var li = document.createElement("li");
li.className = value ? "pass" : "fail";
li.appendChild(document.createTextNode(desc));
results.appendChild(li);
if (!value) {
li.parentNode.parentNode.className = "fail";
}
return li;
}; this.test = function test(name, fn) {
queue.push(function () {
results = document.getElementById("results");
results = assert(true, name).
appendChild(document.createElement("ul"));
fn();
});
runTest();
}; function runTest() {
if (!paused && queue.length) {
queue.shift()();
if (!paused) {
resume();
}
}
} this.pause = function () {
paused = true;
}; this.resume = function resume() {
paused = false;
setTimeout(runTest, 1);
}
})(); window.onload = function (ev) {
test("First async test", function () {
pause();
setTimeout(function () {
assert(true, "First async completed!");
resume();
}, 1000);
}); test("Second async test", function () {
pause();
setTimeout(function () {
assert(true, "Second async test completed!");
resume();
}, 1000);
});
}
JavaScript基础笔记(十三)测试和调试的更多相关文章
- JavaScript基础笔记集合(转)
JavaScript基础笔记集合 JavaScript基础笔记集合 js简介 js是脚本语言.浏览器是逐行的读取代码,而传统编程会在执行前进行编译 js存放的位置 html脚本必须放在&l ...
- JavaScript基础笔记二
一.函数返回值1.什么是函数返回值 函数的执行结果2. 可以没有return // 没有return或者return后面为空则会返回undefined3.一个函数应该只返回一种类型的值 二.可变 ...
- JavaScript基础笔记一
一.真假判断 真的:true.非零数字.非空字符串.非空对象 假的:false.数字零.空字符串.空对象.undefined 例: if(0){ alert(1) }else{ alert(2) } ...
- JavaScript基础笔记(一)基本概念
基本概念 一.语法 一)区分大小写 二)标识符 书写规则同Java 三)注释 略 四)严格模式 1.在整个脚本中启用严格模式:在顶部添加 "use strict" 2.指定函数在严 ...
- Javascript基础知识小测试(一)
这里罗列了<你不知道的js>上卷的一些知识点以及小问题,如果你想巩固一下js那么就和我一起来看看吧. 如果你能不看书就回答上80%的问题说明你js的这一部分学得还不错,再接再厉. 作用域和 ...
- JavaScript基础笔记(十四)最佳实践
最佳实践 一)松散耦合 1.解耦HTML/JavaScript: 1)避免html种使用js 2)避免js种创建html 2.解耦CSS/JS 操作类 3.解耦应用逻辑和事件处理 以下是要牢记的应用和 ...
- JavaScript基础笔记(十)表单脚本
表单脚本 一.表单基础知识 JavaScript中表单对应的是HTMLFormElement类型,该类型继承自HTMLElement类型. 通过document.forms可以获得所有表单元素,通过数 ...
- JavaScript基础笔记(八)DOM扩展
DOM扩展 一.选择符API Selectors API是由W3C发起制定的一个标准,致力于让浏览器原生支持CSS查询. 一)querySelector() 在Document和Element类型实例 ...
- JavaScript基础笔记1220
JavaScript笔记1.JavaScript关键词2.JavaScript标识符 必须以字母,下划线(_)或美元符($)开始. 后续的字符可以是字母.数字.下划线或者美元符 (数字是不允许作为首字 ...
随机推荐
- C++ Primer 笔记——动态数组
1.动态数组定义时也需要指明数组的大小,但是可以不是常量. int i; int arr[i]; // 错误,数组的大小必须为常量 int *p = new int[i]; // 正确,大小不必是常量 ...
- 开放系统的直连式存储(Direct-Attached Storage,简称DAS)
开放系统的直连式存储(Direct-Attached Storage,简称DAS)已经有近四十年的使用历史,随着用户数据的不断增长,尤其是数百GB以上时,其在备份.恢复.扩展.灾备等方面的问题变得日益 ...
- 史上最简单的SpringCloud教程 | 第五篇: 路由网关(zuul)
在微服务架构中,需要几个基础的服务治理组件,包括服务注册与发现.服务消费.负载均衡.断路器.智能路由.配置管理等,由这几个基础组件相互协作,共同组建了一个简单的微服务系统.一个简答的微服务系统如下图: ...
- Python自定义排序
比如自定义了一个class,并且实例化了这个类的很多个实例,并且组成一个数组.这个数组要排序,是通过这个class的某个字段来排序的.怎么排序呢? 有两种做法: 第一种是定义__cmp__( )方法: ...
- springboot快速使用
1.编写SpringConfig 用于实例化Spring容器 @Configuration //通过该注解来表明该类是一个Spring的配置,相当于一个xml文件 @Bean // 通过该注解来表明是 ...
- 免费API接口
网址:https://code.juhe.cn/ http://apistore.baidu.com/ http://blog.csdn.net/cc20032706/article/details/ ...
- POJ 1364 / HDU 3666 【差分约束-SPFA】
POJ 1364 题解:最短路式子:d[v]<=d[u]+w 式子1:sum[a+b+1]−sum[a]>c — sum[a]<=sum[a+b+1]−c−1 ...
- bzoj4059
题解: 还是一道不错的题目 首先它要求每个区间都满足要求,所以我们很容易想到将它映射到二维平面上 然后我们算出每个数的前驱以及后继li,ri 那么第一维是li-i,第二维是i-ri的区间就是合法的,同 ...
- Windows系统下MySQL添加到系统服务方法(mysql解压版)
MySQL软件版本:64位 5.7.12 1.首先配置MySQL的环境变量,在系统环境变量Path的开头添加MySQL的bin目录的路径,以“;”结束,我的路径配置如下: 2.修改MySQL根目录下的 ...
- 【BZOJ】3730: 震波
原题链接 题解 查询距离一个点距离在一定范围内的点,直接点分树,前缀和用树状数组维护 答案是当前重心距离不超过k - (x到重心距离)的点的前缀和,减去在x所在子树中,距离重心不超过k - (x到重心 ...