1.assert断言模块主要解决:
- 测试需求,提供校验值是否为真、相等/不相等、深度匹配/不匹配等调试方法,不满足校验条件的通过fail函数构造AssertionError对象并抛出。
- 抛出错误,构造执行函数block,通过block函数抛出错误对象Error,捕获该错误对象,与期望值比较,assert.throw方法中若由block捕获的错误匹配expected期望的校验要求(包括正则、构造函数、以block捕获错误为参数的函数),则既不抛出Error错误,也不抛出AssertionError错误;assert.doesNotThrow方法,若block捕获错误符合期望,抛出AssertionError错误,若不符合,抛出Error错误。
2.assert一般测试方法的构建:
- 通过assert.throw(block[,error][,message])方法校验block函数执行时捕获的错误是否符合期望error的校验条件,因此该测试方法的实现在于构造block函数。或者重新构建assert方法
3.与jquery-unit的比较:
- assert模块相等性比较更为细致,还需顾及buffer、ArrayBuffer、DataView对象。
- 添加一般测试方法,jquery-validate提供了定制校验方法的功能,可以用于多个校验框,jquery-unit也能构造特定的通用的校验方法用于多个测试对象,assert需要反复重写block函数构建,或者重新构建assert方法。
4.使用
- assert.AssertionError(options) 配置AssertionError错误对象
- assert.fail(actual, expected, message, operator) 配置AssertionError错误对象,并抛出该错误,actual为实际值,expected为期望值,message错误消息,operater分隔符
- assert(value, message), assert.ok(value, [message]) 校验value是否为真
- assert.equal(actual, expected, [message]) 校验两者是否相等==
- assert.notEqual(actual, expected, [message]) 校验两者是否不相等!=
- assert.deepEqual(actual, expected, [message]) 数组、对象、时间对象、正则对象、ArrayBuffer对象、arguments对象深度匹配,非严格模式
- assert.deepStrictEqual(actual, expected, [message]) 数组、对象、时间对象、正则对象、ArrayBuffer对象、arguments对象深度匹配,严格模式
- assert.notDeepEqual(actual, expected, [message]) 深度匹配返回否值,非严格模式
- assert.notDeepStrictEqual(actual, expected, [message]) 深度匹配返回否值,严格模式
- assert.strictEqual(actual, expected, [message]) 相等比较===
- assert.notStrictEqual(actual, expected, [message]) 不相等比较!==
- assert.throws(block, [error], [message]) block没有错误抛出AssertionError错误,或者错误不符期望,抛出block捕获的错误
- assert.doesNotThrow(block, [message]) 没有期望或者block捕获错误符合期望,抛出AssertionError错误;block捕获错误不符合期望,抛出block捕获的错误
- assert.ifError(value) 参数为Error对象,直接抛出该错误对象
5源码:
'use strict'; // 比较字符串、buffer对象 function compare(a,b){ if ( a===b ){ return 0; } var x=a.length; var y=b.length; for ( var i=0, len=Math.min(x, y); i<len; ++i ){ if ( a[i]!==b[i] ){ x=a[i]; y=b[i]; break; } } if ( x<y ){ return -1; } if ( y<x ){ return 1; } return 0; } // 判断是否buffer对象 function isBuffer(b){ if ( global.Buffer && typeof global.Buffer.isBuffer==='function' ){ return global.Buffer.isBuffer(b); } return !!(b!=null && b._isBuffer); } var util=require('util/'); var hasOwn=Object.prototype.hasOwnProperty; var pSlice=Array.prototype.slice; // 是否拥有函数名 var functionsHaveNames=(function(){ return function foo(){}.name==='foo'; }()); // 调用toString方法将对象转化为字符串 function pToString(obj){ return Object.prototype.toString.call(obj); } // ArrayBuffer是二进制数据的原始缓冲区,该缓冲区用于存储各种类型化数组的数据 // var buffer=new ArrayBuffer(12); // var x=new Int32Array(buffer);// 也可以直接创建 // // Int8Array 8位二补码有符号整数 // // Uint8Array 8位无符号整数 // // Int16Array 16位二补码有符号整数 // // Uint16Array 16位无符号整数 // // Int32Array 32位二补码有符号整数 // // Uint32Array 32位无符号整数 // // Float32Array 32位 IEEE 浮点数 // // Float64Array 64位 IEEE 浮点数 // x[0]=1234;console.log(x[0]) // 1234 // DataView可以对数据作更细致的操作,即每项设置不同的数据类型 // var buffer=new ArrayBuffer(12); // var x=new DataView(buffer, 0); // x.setInt8(0, 22); // x.setFloat32(1, Math.PI); // console.log(x.getInt8(0)); // 22 // console.log(x.getFloat32(1)); // 3.1415927410125732 // 判断是否ArrayBuffer对象 function isView(arrbuf){ if ( isBuffer(arrbuf) ){ return false; } if ( typeof global.ArrayBuffer!=='function' ){ return false; } if ( typeof ArrayBuffer.isView==='function' ){ return ArrayBuffer.isView(arrbuf); } if ( !arrbuf ){ return false; } if ( arrbuf instanceof DataView ){ return true; } if ( arrbuf.buffer && arrbuf.buffer instanceof ArrayBuffer ){ return true; } return false; } var assert=module.exports=ok; // 获取函数名 var regex=/\s*function\s+([^\(\s]*)\s*/; function getName(func){ if ( !util.isFunction(func) ){ return; } if ( functionsHaveNames ){ return func.name; } var str=func.toString(); var match=str.match(regex); return match && match[1]; } // AssertionError形式的错误对象,继承Error错误对象,用于校验失败后抛出 // new assert.AssertionError({ message: message, // actual: actual, // expected: expected }) assert.AssertionError=function AssertionError(options){ this.name='AssertionError'; this.actual=options.actual;// 实际值 this.expected=options.expected;// 期望值 this.operator=options.operator;// 分割符 if ( options.message ){ this.message=options.message; this.generatedMessage=false; }else{ this.message=getMessage(this);// 以实际值+operator+期望值的形式构建默认错误消息 this.generatedMessage=true; } // 获取错误的堆栈信息 var stackStartFunction=options.stackStartFunction || fail; if ( Error.captureStackTrace ){ Error.captureStackTrace(this, stackStartFunction); }else{ // non v8 browsers so we can have a stacktrace var err=new Error(); if ( err.stack ){ var out=err.stack; // try to strip useless frames var fn_name=getName(stackStartFunction); var idx=out.indexOf('\n'+fn_name); if ( idx>=0 ){ // once we have located the function frame // we need to strip out everything before it (and its line) var next_line=out.indexOf('\n', idx+1); out=out.substring(next_line+1); } this.stack = out; } } }; util.inherits(assert.AssertionError, Error); // 截取字符串 function truncate(s, n) { if ( typeof s==='string' ){ return s.length<n ? s : s.slice(0, n); } else { return s; } } // 将对象转化为字符串后输出,或将函数转化为[Function: fnName]的形式 function inspect(something){ if ( functionsHaveNames || !util.isFunction(something) ){ return util.inspect(something);// 将任意对象转化成字符串 } var rawname=getName(something); var name=rawname ? ': '+rawname : ''; return '[Function'+name+']'; } // 以实际值+分割符+期望值的形式构建默认错误消息 function getMessage(self) { return truncate(inspect(self.actual), 128)+' '+ self.operator+' '+ truncate(inspect(self.expected), 128); } // 配置AssertionError的实际值、期望值、错误消息、分割符、堆栈函数,并抛出错误 function fail(actual, expected, message, operator, stackStartFunction){ throw new assert.AssertionError({ message: message, actual: actual, expected: expected, operator: operator, stackStartFunction: stackStartFunction }); } assert.fail=fail; // 校验value是否为真 function ok(value, message){ if (!value) fail(value, true, message, '==', assert.ok); } assert.ok=ok; // 校验实际值和期望值是否相等 assert.equal=function equal(actual, expected, message){ if ( actual!=expected ) fail(actual, expected, message, '==', assert.equal); }; // 校验实际值和期望值是否不相等 assert.notEqual=function notEqual(actual, expected, message){ if ( actual==expected ){ fail(actual, expected, message, '!=', assert.notEqual); } }; // 对象等深度比较,非严格模式值比较 assert.deepEqual=function deepEqual(actual, expected, message){ if ( !_deepEqual(actual, expected, false) ){ fail(actual, expected, message, 'deepEqual', assert.deepEqual); } }; // 对象等深度比较,非严格模式引用地址比较 assert.deepStrictEqual=function deepStrictEqual(actual, expected, message){ if ( !_deepEqual(actual, expected, true) ){ fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual); } }; // buffer对象、ArrayBuffer对象、时间对象、正则对象、数组、对象比较 function _deepEqual(actual, expected, strict, memos){ if ( actual===expected ){ return true; // buffer对象相等比较 }else if( isBuffer(actual) && isBuffer(expected) ){ return compare(actual, expected)===0; // 时间对象比较 }else if( util.isDate(actual) && util.isDate(expected) ){ return actual.getTime()===expected.getTime(); // 正则对象比较 }else if( util.isRegExp(actual) && util.isRegExp(expected) ){ return actual.source===expected.source && actual.global===expected.global && actual.multiline===expected.multiline && actual.lastIndex===expected.lastIndex && actual.ignoreCase===expected.ignoreCase; // null值比较,分为严格比较和不严格比较 }else if( (actual===null || typeof actual!=='object') && (expected===null || typeof expected !== 'object')){ return strict ? actual===expected : actual==expected; // 判断ArrayBuffer对象是否相等 }else if( isView(actual) && isView(expected) && pToString(actual)===pToString(expected) && !(actual instanceof Float32Array || actual instanceof Float64Array) ){ return compare(new Uint8Array(actual.buffer),new Uint8Array(expected.buffer))===0; }else if( isBuffer(actual)!==isBuffer(expected) ){ return false; }else{ // 关于memos以及数组相等判断 memos=memos || {actual: [], expected: []}; var actualIndex=memos.actual.indexOf(actual); if ( actualIndex!==-1 ){ if ( actualIndex===memos.expected.indexOf(expected) ){ return true; } } memos.actual.push(actual); memos.expected.push(expected); return objEquiv(actual, expected, strict, memos); } } // 是否arguments参数对象 function isArguments(object){ return Object.prototype.toString.call(object)=='[object Arguments]'; } // arguments参数对象、对象、null、undefined比较 function objEquiv(a, b, strict, actualVisitedObjects){ if ( a===null || a===undefined || b===null || b===undefined ) return false; // util.isPrimitive??? if ( util.isPrimitive(a) || util.isPrimitive(b) ) return a===b; if ( strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b) ) return false; // arguments参数对象比较 var aIsArgs=isArguments(a); var bIsArgs=isArguments(b); if ( (aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs) ) return false; if ( aIsArgs ){ a=pSlice.call(a); b=pSlice.call(b); return _deepEqual(a,b,strict); } // 对象比较,先比较键,再比较值 var ka=objectKeys(a); var kb=objectKeys(b); var key, i; if ( ka.length!==kb.length ) return false; ka.sort(); kb.sort(); for ( i=ka.length-1; i>=0; i-- ){ if ( ka[i]!==kb[i] ) return false; } // 递归比较值 for ( i=ka.length-1; i>=0; i-- ){ key=ka[i]; if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects)) return false; } return true; } // 对象等深度比较,非严格模式值比较 assert.notDeepEqual=function notDeepEqual(actual, expected, message){ if (_deepEqual(actual, expected, false)) { fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); } }; // 对象等深度比较,非严格模式引用地址比较 assert.notDeepStrictEqual=notDeepStrictEqual; function notDeepStrictEqual(actual, expected, message){ if (_deepEqual(actual, expected, true)) { fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual); } } // ===相等判断 assert.strictEqual = function strictEqual(actual, expected, message) { if (actual !== expected) { fail(actual, expected, message, '===', assert.strictEqual); } }; // !==不相等判断 assert.notStrictEqual = function notStrictEqual(actual, expected, message) { if (actual === expected) { fail(actual, expected, message, '!==', assert.notStrictEqual); } }; // 用正则、是否实例、函数校验由block函数获得的错误actual function expectedException(actual, expected){ if ( !actual || !expected ){ return false; } // 当block函数抛出错误throw new Error("Wrong value"),捕获后用正则/value/校验该error为真 if ( Object.prototype.toString.call(expected)=='[object RegExp]' ){ return expected.test(actual); } try{ if ( actual instanceof expected ){ return true; } }catch (e){ // Ignore. The instanceof check doesn't work for arrow functions. } if ( Error.isPrototypeOf(expected) ){ return false; } return expected.call({}, actual) === true; } // 执行block,有错则捕获错误,返回为真,否则为否 function _tryBlock(block){ var error; try { block(); }catch (e){ error=e; } return error; } // shouldThrow为真时,block没有错误抛出AssertionError错误,或者错误不符期望,抛出block捕获的错误 // shouldThrow为否时,没有期望或者block捕获错误符合期望,抛出AssertionError错误 // block捕获错误不符合期望,抛出block捕获的错误 function _throws(shouldThrow, block, expected, message){ var actual; if (typeof block!=='function'){ throw new TypeError('"block" argument must be a function'); } if ( typeof expected==='string' ){ message=expected; expected=null; } actual=_tryBlock(block);// 获取错误或undefined message=(expected && expected.name ? ' ('+expected.name+').' : '.')+ (message ? ' '+message : '.'); if ( shouldThrow && !actual ){ fail(actual, expected, 'Missing expected exception'+message); } var userProvidedMessage=typeof message==='string'; var isUnwantedException=!shouldThrow && util.isError(actual); var isUnexpectedException=!shouldThrow && actual && !expected; // shouldThrow为否,且actual是期望捕获的错误,用AssertionError的方式抛出错误 if ( (isUnwantedException && userProvidedMessage && expectedException(actual, expected)) || isUnexpectedException ){ fail(actual, expected, 'Got unwanted exception'+message); } // shouldThrow为真,且actual不是期望捕获的错误,或者shouldThrow为否,actual捕获到错误,抛出actual错误 if ( (shouldThrow && actual && expected && !expectedException(actual, expected)) || (!shouldThrow && actual) ){ throw actual; } } // block没有错误抛出AssertionError错误,或者错误不符期望,抛出block捕获的错误 assert.throws=function(block, /*optional*/error, /*optional*/message){ _throws(true, block, error, message); }; // 没有期望或者block捕获错误符合期望,抛出AssertionError错误 // block捕获错误不符合期望,抛出block捕获的错误 assert.doesNotThrow=function(block, /*optional*/error, /*optional*/message) { _throws(false, block, error, message); }; // 参数为Error对象,直接抛出该错误对象 assert.ifError=function(err){if (err) throw err;}; // 获取对象的键 var objectKeys=Object.keys || function (obj){ var keys=[]; for ( var key in obj ){ if ( hasOwn.call(obj, key) ) keys.push(key); } return keys; };
相关推荐
在标题提到的"assert模块"中,`assert`语句是其核心部分。它的基本语法是: ```python assert condition, message ``` 这里,`condition`是一个布尔表达式,如果为`False`,则会触发异常;`message`是可选的错误...
本项目“业务异常提示处理 springboot+Assert(自定义断言)”着重于利用Spring Boot的特性来构建高效、易维护的业务逻辑,并通过自定义断言提升代码的可读性和可维护性。下面我们将详细探讨这些知识点。 1. **Spring...
Assert是Node.js核心模块之一,包含了一系列的断言方法,如`assert.equal()`、`assert.notEqual()`等,用于比较预期值和实际值,如果两者不符,就会抛出错误。例如: ```javascript const assert = require('assert...
"json4s-ast-master"可能是JSON4S AST模块的源代码主分支,包含了构建、测试和使用这个模块的所有必要文件。 开源项目通常会提供清晰的文档、示例代码和测试用例,帮助开发者理解和使用这些工具。在这个压缩包中,...
在给定的“uart通信模块verilog代码.zip”压缩包中,包含了一些关键的UART模块和测试平台的源代码文件,接下来将详细介绍这些文件及其相关的知识点。 1. **uart_tx.v**:这是UART的发送模块,负责将并行数据转化为...
断言在编程中是一种非常重要的调试工具,尤其是在测试过程中,用于验证代码的预期行为。在Node.js中,`assert`...在Node.js项目中,通过引入`assert`模块,可以轻松地集成这些断言功能,提高代码质量并减少潜在的bug。
Node.js中的assert模块是JavaScript中一个非常重要的测试库,它主要用于编写程序的单元测试。通过断言可以尽早地发现和排查程序中潜在的错误。在Node.js中,assert模块作为核心模块之一,提供了一系列用于测试的断言...
在Node.js上运行mocha时,可以使用标准的assert模块。 如果您使用此库,则将在浏览器中运行相同的测试。 如何使用 $ bower install https://github.com/Jxck/assert < script src =" assert.js " > </ ...
5. `src` 或 `pytest_assert_utils` 目录:包含实际的 Python 模块和类。 - `__init__.py`:使目录成为 Python 包。 - `assertion_utils.py` 或类似文件:包含增强的断言函数或类。 6. `tests` 目录:存放测试代码...
最近在用Node写一个实时聊天小应用,其中就用到了单元测试,所以死下面这篇文章主要给大家介绍了关于Node.js利用断言模块assert进行单元测试的方法,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来...
标签“源码”和“工具”提示我们,这个主题可能涉及到查看和理解RSA模块的源代码,以及它作为一个实用工具在实际项目中的应用。通过阅读源码,开发者可以更好地理解RSA算法的工作原理,以便于自定义或优化相关功能。...
6. **断言(Assertion)**:测试完成后,我们需要使用JUnit的assert方法(如assertEquals()、assertTrue()等)来验证Service层方法的执行结果是否符合预期。 7. **测试覆盖率**:为了确保测试的全面性,我们还需要...
断言 yeoman-assert正在扩展本机Node.js assert模块。 yeoman-assert assert还可以使用assert每个方法,以及一些与代码框架相关的断言帮助器。安装 $ npm install yeoman-assert用法 const assert = require ( '...
在Linux平台上进行CLI(命令行接口)模块的代码自动化测试是一项关键的技术实践,它能够显著提高软件开发的效率和质量。下面将详细讲解这个主题,包括相关知识点、测试原理以及实施步骤。 首先,理解CLI模块的基本...
在给定的"Python ddt模块数据驱动下载.rar"压缩包中,很可能包含了ddt库的源码、示例代码、可能的文档以及相关教程。 ddt的核心功能是将一个测试用例转化为多个独立的测试,每个用例对应一组不同的输入数据。这样,...
通过源码我们可以看到,console.assert方法内部实际上是对Node.js的assert模块的ok函数进行了调用。在断言失败的情况下,console.assert使用util.format方法来格式化错误信息,并将这个信息作为参数传递给assert.ok...
本文将介绍一种基于C++模板技术的模块间参数传递方式,旨在提高代码的灵活性和复用性。 #### 二、问题背景 当我们在设计软件时,经常遇到需要在不同模块之间传递各种类型的参数的情况。这些参数可能包括基本数据...
nose可以通过第三方插件如`dupfind`或`radon`来检测代码中的重复部分,鼓励编写模块化、可重用的代码,提高代码质量。 ### 3. 使用nose进行测试驱动开发(TDD) nose支持测试驱动开发模式,鼓励开发者先编写测试...