关于编程测试中的断言-.pdf
编程断言概述编写代码时,我们总是会做出一些假设,断言就是用于在代码中捕捉这些假设可以将断言看作是异常处理的一种高级形式断言表示为一些布尔表达式,程序员相信在程序中的某个特定点该表达式值为真可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言而在部署时禁用断言。同样,程序投入运行后,最终用户在遇到问题时可以重新起用断言。使用断言可以创建更稳定,品质更好且易于除错的代码当需要在一个值为FALSE时中断当前操作的话,可以使用断言单元测试必须使用断言(Junit/JunitX)除了类型检查和单元测试外,断言还提供了一种确定个种特性是否在程序中得到维护的极好的方法使用断言使我们向按契约式设计更近了一步。常见的断言特性前置条件断言:代码执行之前必须具备的特性后置条件断言:代码执行之后必须具备的特性前后不变断言:代码执行前后不能变化的特性。断言使用方式断言可以有两种形式1assertExpression1 2assertExpression1:Expression2 其中 Expression1应该总是一个布尔值,Expression2是断言失败时输出的失败消息的字符串。如果Expression1为假,则抛出一个AssertionError,这是一个错误,而不是一个异常,也就是说是一个不可控制异常(uncheckedException),AssertionError由于是错误,所以可以不捕获,但不推荐这样做,因为那样会使你的系统进入不稳定状态。启用断言断 言 在 默 认 情 况 下 是 关 闭 的,要 在 编 译 时 启 用 断 言,需 要 使 用source14标 记 既javacsource14Testjava,在运行时启用断言需要使用-ea 参数。要在系统类中启用和禁用断言可以使用-esa 和-dsa 参数。例如:publicclassAssertExampleOne publicAssertExampleOne()publicstaticvoidmain(Stringargs)intx=10;Systemoutprintln(TestingAssertionthatx=100);assertx=100:Outassertionfailed!;Systemoutprintln(Testpassed!);如果编译时未加-source14,则编译通不过在执行时未加-ea 时输出为TestingAssertionthatx=100 Testpassed jre 忽略了断言的旧代码,而使用了该参数就会输出为TestingAssertionthatx=100 ExceptioninthreadmainjavalangAssertionError:Outassertionfailed!atAssertExampleOnemain(AssertExampleOnejava:6)断言的副作用由于程序员的问题,断言的使用可能会带来副作用,例如:booleanisEnable=false;/assertisEnable=true;这个断言的副作用是因为它修改了程序中变量的值并且未抛出错误,这样的错误如果不细心的检查是很难发现的。但是同时我们可以根据以上的副作用得到一个有用的特性,根据它来测试断言是否打开。publicclassAssertExampleTwo publicstaticvoidmain(Stringargs)booleanisEnable=false;/assertisEnable=true;if(isEnable=false)thrownewRuntimeException(Assertionshoulebeenable!);何时需要使用断言1 可以在预计正常情况下程序不会到达的地方放置断言:assertfalse2 断言可以用于检查传递给私有方法的参数。(对于公有方法,因为是提供给外部的接口,所以必须在方法中有相应的参数检验才能保证代码的健壮性)3 使用断言测试方法执行的前置条件和后置条件4 使用断言检查类的不变状态,确保任何情况下,某个变量的状态必须满足。(如 age属性应大于0 小于某个合适值)什么地方不要使用断言断言语句不是永远会执行,可以屏蔽也可以启用因此:1 不要使用断言作为公共方法的参数检查,公共方法的参数永远都要执行2 断言语句不可以有任何边界效应,不要使用断言语句去修改变量和改变方法的返回值下边是介绍断言的用法:assert 是在 J2SE14 中引入的新特性,assertion 就是在代码中包括的布尔型状态,程序员认为这个状态是true。一般来说assert 在开发的时候是检查程序的安全性的,在发布的时候通常都不使用assert。在14 中添加了assert 关键字和javalangAssertError类的支持。首先,我们有必要从一个例子说起assert publicclassAssertTest publicstaticvoidmain(Stringargs)AssertTestat=newAssertTest();atassertMe(true);atassertMe(false);privatevoidassertMe(booleanboo)assertboo?true:false;Systemoutprintln(truecondition);程序中包含了assert 的话,你要用javac-source14xxxjava来编译,否则编译器会报错的。要想让assert 得部分运行的话,要使用java-eaxxx来运行,否则包含assert 得行会被忽略。下面我们运行javac-source14AssertTestjava java-eaAssertTest 看看结果的输出是:truecondition ExceptioninthreadmainjavalangAssertionError atAssertTestassertMe(AssertTestjava:13)atAssertTestmain(AssertTestjava:7)当我们运行atassertMe(true)得时候,由于 assertboo?true:false相当于asserttrue;因此没有任何问题,程序往下执行打印出truecondition,但是执行atassertMe(false)的时候相当于 assertfalse,这个时候解释器就会抛出AssertionError了,程序就终止了。大家必须清楚AssertionError是继承自Error 得,因此你可以不再程序中catch 它的,当然你也可以在程序中catch 它然后程序可以继续执行。例如:publicclassAssertTest publicstaticvoidmain(Stringargs)AssertTestat=newAssertTest();try atassertMe(true);atassertMe(false);catch(AssertionErrorae)Systemoutprintln(AsseriontErrorcatched);Systemoutprintln(goon);privatevoidassertMe(booleanboo)assertboo?true:false;Systemoutprintln(truecondition);assert 还有另外一种表达的方式,就是assertexp1:exp2;其中 exp1 是个 boolean 返回值得表达式,而exp2 可以是原始的数据类型或者对象都可以例如:booleanboo=true;Stringstr=null;assertboo=false:str=error;我们刚开始讲得assertexp1 得形式,当exp1 是 false 得时候,AssertionError得默认构造器会被调用,但是assertexp1:exp2这样的形式,当exp1 为 true 的时候后面exp2 被或略,如果false 的话,后面的表达式的结果会被计算出来并作为AssertionError得构造器参数。看下面的例子:publicclassAssertTest publicstaticvoidmain(Stringargs)AssertTestat=newAssertTest();atassertMe(true);atassertMe(false);privatevoidassertMe(booleanboo)Strings=null;assertboo?true:false:s=helloworld;Systemoutprintln(truecondition);运行的时候会得到这样的结果truecondition ExceptioninthreadmainjavalangAssertionError:helloworld atAssertTestassertMe(AssertTestjava:14)atAssertTestmain(AssertTestjava:7)Assert 最好不要滥用,原因是assert 并不一定都是enable 的,下面两种情况就不应该用 assert 不要再public 的方法里面检查参数是不是为null 之类的操作例如 publicintget(Strings)asserts!=null;如果需要检查也最好通过ifs=null抛出NullPointerException来检查不要用assert 来检查方法操作的返回值来判断方法操作的结果例如 assertlistremoveAll();这样看起来好像没有问题但是想想如果assert 被 disable 呢,那样他就不会被执行了所以removeAll()操作就没有被执行可以这样代替booleanboo=listremoveAl();assertboo;就说这么多吧,assert 是 scjp14 的考试内容所以还是有必要了解的扩展阅读:1-http:/wwwjava2000net/p9082Assert异常的处理2-http:/wwwjava2000net/p7575一段断言 assert不生效的问题3-http:/wwwjava2000net/p7557如何在 Java 代码中启用和禁用断言4-http:/zhidaobaiducom/question/14299781html?si=1