zoukankan      html  css  js  c++  java
  • 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);
            });
        }
    Simple is important!
  • 相关阅读:
    [转] MapReduce详解
    [转] 自然语言处理全家福:纵览当前NLP中的任务、数据、模型与论文
    [转] 一文读懂BERT中的WordPiece
    [转] 文本分类——GLUE数据集介绍
    [转] Transformer详解
    [python] 转json好用的工具mark
    [转] 深度学习中的注意力机制
    [转] Python之time模块的时间戳、时间字符串格式化与转换
    日期相关
    airflow的定时任务
  • 原文地址:https://www.cnblogs.com/Shadowplay/p/8701239.html
Copyright © 2011-2022 走看看