发布新日志

  • Eclipse使用ANT

    2011-05-27 18:13:10

    Ant是Java平台下非常棒的批处理命令执行程序,能非常方便地自动完成编译,测试,打包,部署等等一系列任务,大大提高开发效率。如果你现在还没有开始使用Ant,那就要赶快开始学习使用,使自己的开发水平上一个新台阶。

      Eclipse中已经集成了Ant,我们可以直接在Eclipse中运行Ant。

      以前面建立的Hello工程为例,创建以下目录结构:


      新建一个build.xml,放在工程根目录下。build.xml定义了Ant要执行的批处理命令。虽然Ant也可以使用其它文件名,但是遵循标准能更使开发更规范,同时易于与别人交流。

      通常,src存放Java源文件,classes存放编译后的class文件,lib存放编译和运行用到的所有jar文件,web存放JSP等web文件,dist存放打包后的jar文件,doc存放API文档。

      然后在根目录下创建build.xml文件,输入以下内容:

    <?xml version="1.0"?>
    <project name="Hello world" default="doc">


    <!-- properies -->
    <property name="src.dir" value="src" />
    <property name="report.dir" value="report" />
    <property name="classes.dir" value="classes" />
    <property name="lib.dir" value="lib" />
    <property name="dist.dir" value="dist" />
    <property name="doc.dir" value="doc"/>


    <!-- 定义classpath -->
    <path id="master-classpath">
    <fileset file="${lib.dir}/*.jar" />
    <pathelement path="${classes.dir}"/>
    </path>


    <!-- 初始化任务 -->
    <target name="init">
    </target>


    <!-- 编译 -->
    <target name="compile" depends="init" description="compile the source files">
    <mkdir dir="${classes.dir}"/>
    <javac srcdir="${src.dir}" destdir="${classes.dir}" target="1.4">
    <classpath refid="master-classpath"/>
    </javac>
    </target>


    <!-- 测试 -->
    <target name="test" depends="compile" description="run junit test">
    <mkdir dir="${report.dir}"/>
    <junit printsummary="on"
    haltonfailure="false"
    failureproperty="tests.failed"
    showoutput="true">
    <classpath refid="master-classpath" />
    <formatter type="plain"/>
    <batchtest todir="${report.dir}">
    <fileset dir="${classes.dir}">
    <include name="**/*Test.*"/>
    </fileset>
    </batchtest>
    </junit>
    <fail if="tests.failed">
    ***********************************************************
    **** One or more tests failed! Check the output ... ****
    ***********************************************************
    </fail>
    </target>


    <!-- 打包成jar -->
    <target name="pack" depends="test" description="make .jar file">
    <mkdir dir="${dist.dir}" />
    <jar destfile="${dist.dir}/hello.jar" basedir="${classes.dir}">
    <exclude name="**/*Test.*" />
    <exclude name="**/Test*.*" />
    </jar>
    </target>


    <!-- 输出api文档 -->
    <target name="doc" depends="pack" description="create api doc">
    <mkdir dir="${doc.dir}" />
    <javadoc destdir="${doc.dir}"
    author="true"
    version="true"
    use="true"
    windowtitle="Test API">
    <packageset dir="${src.dir}" defaultexcludes="yes">
    <include name="example/**" />
    </packageset>
    <doctitle><![CDATA[<h1>Hello, test</h1>]]></doctitle>
    <bottom><![CDATA[<i>All Rights Reserved.</i>]]></bottom>
    <tag name="todo" scope="all" description="To do:" />
    </javadoc>
    </target>
    </project>

      以上xml依次定义了init(初始化),compile(编译),test(测试),doc(生成文档),pack(打包)任务,可以作为模板。

      选中Hello工程,然后选择“Project”,“Properties”,“Builders”,“New…”,选择“Ant Build”:


      填入Name:Ant_Builder;Buildfile:build.xml;Base Directory:${workspace_loc:/Hello}(按“Browse Workspace”选择工程根目录),由于用到了junit.jar包,搜索Eclipse目录,找到junit.jar,把它复制到Hello/lib目录下,并添加到Ant的Classpath中:(选择User Entries)加入架包


      然后在Builder面板中钩上Ant_Build,去掉Java Builder:


      再次编译,即可在控制台看到Ant的输出:

    Buildfile: F:\eclipse-projects\Hello\build.xml

    init:

    compile:
    [mkdir] Created dir: F:\eclipse-projects\Hello\classes
    [javac] Compiling 2 source files to F:\eclipse-projects\Hello\classes


    test:
    [mkdir] Created dir: F:\eclipse-projects\Hello\report
    [junit] Running example.HelloTest
    [junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.02 sec


    pack:
    [mkdir] Created dir: F:\eclipse-projects\Hello\dist
    [jar] Building jar: F:\eclipse-projects\Hello\dist\hello.jar


    doc:
    [mkdir] Created dir: F:\eclipse-projects\Hello\doc
    [javadoc] Generating Javadoc
    [javadoc] Javadoc execution
    [javadoc] Loading source files for package example...
    [javadoc] Constructing Javadoc information...
    [javadoc] Standard Doclet version 1.4.2_04
    [javadoc] Building tree for all the packages and classes...
    [javadoc] Building index for all the packages and classes...
    [javadoc] Building index for all classes...
    [javadoc] Generating F:\eclipse-projects\Hello\doc\stylesheet.css...
    [javadoc] Note: Custom tags that could override future standard tags: @todo. To avoid potential overrides, use at least one period character (.) in custom tag names.
    [javadoc] Note: Custom tags that were not seen: @todo
    BUILD SUCCESSFUL
    Total time: 11 seconds

      Ant依次执行初始化,编译,测试,打包,生成API文档一系列任务,极大地提高了开发效率。将来开发J2EE项目时,还可加入部署等任务。并且,即使脱离了Eclipse环境,只要正确安装了Ant,配置好环境变量ANT_HOME=<Ant解压目录>,Path=…;%ANT_HOME%\bin,在命令行提示符下切换到Hello目录,简单地键入ant即可。
  • Junit4 新断言语法介绍(转)

    2011-05-12 15:34:43

    1. 引言
    JUnit4提供的新断言语法具有很多优点且使用简单,这已经不再是新鲜事了,可发现在实际测试代码中仍未被普及应用,特发此文,以期更多的人能掌握运用。
    2. assertThat基本语法
    Hamcrest 是一个测试辅助工具,提供了一套通用的匹配符 Matcher,灵活使用这些匹配符定义的规则,程序员可以更加精确的表达自己的测试思想,指定所想设定的测试条件。
    Junit4结合Hamcrest提供了新的断言语句-assertThat,只需一个assertThat语句,结合Hamcrest提供的匹配符,就可以表达全部的测试思想。
    assertThat的基本语法如下:

    assertThat(T actual, Matcher matcher)
    assertThat(String reason, T actual, Matcher matcher)

    actual 是接下来想要验证的值;
    matcher是使用 Hamcrest 匹配符来表达的对前面变量所期望的值的声明,如果 actual值与 matcher 所表达的期望值相符,则断言成功,否则断言失败。
    reason是自定义的断言失败时显示的信息。
    一个简单的例子:
    // 如果测试的字符串testedString包含子字符串"taobao"则断言成功
    assertThat( testedString, containsString( "taobao" ) );

    3. assertThat优点

  • 统一

    只需一条assertThat语句即可替代旧有的其他语句(如assertEquals,assertNotSame,assertFalse,assertTrue,assertNotNull,assertNull等),使断言变得简单、代码风格统一,增强测试代码的可读性和可维护性。

  • 语法直观易懂

    assertThat 不再像 assertEquals 那样,使用比较难懂的“谓宾主”语法模式(如:assertEquals(3, x);)。相反,assertThat 使用了类似于“主谓宾”的易读语法模式(如:assertThat(x,is(3));),使得代码更加直观、易读,符合人类思维习惯。

  • 错误信息更具描述性

    旧的断言语法如果断言失败,默认不会有额外的提示信息,如
    assertTrue(testedString.indexOf(“taobao”) > -1);
    如果该断言失败,只会抛出无用的错误信息,如java.lang.AssertionError: ,除此之外不会有更多的提示信息。
    新的断言语法会默认自动提供一些可读的描述信息,如
    assertThat(testedString, containsString(“taobao”));
    如果该断言失败,抛出的错误提示信息如下:
    java.lang.AssertionError:
    Expected: a string containing “taobao”
    got: “taoba”

  • 跟Matcher匹配符联合使用更灵活强大

    Matcher提供了功能丰富的匹配符,assertThat结合这些匹配符使用可更灵活更准确的表达测试思想。
    // 验证字符串 s是否含有子字符串 "taobao" 或 "qa" 中间的一个
    // 旧的断言,不直观,需要分析代码逻辑明白验证意图
    assertTrue(s.indexOf("taobao")>-1||s.indexOf("qa")>-1);
    // 新的断言,直观易懂,准确表达测试思想
    assertThat(s,anyOf(containsString("taobao"),containsString("qa")));
    // anyOf满足条件之一即成立,containsString包含字符串则成立

    4. assertThat使用
    要想发挥assetThat的威力,必须跟Hamcrest联合使用,JUnit4本身包含了一些自带了一些 Hamcrest 的匹配符 Matcher,但是只有有限的几个。因此建议你将Hamcrest包加入项目。
    在pom里加入Hamcrest依赖。
    <dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-all</artifactId>
    <version>1.1</version>
    </dependency>

    在测试类里导入包
    import static org.junit.Assert.*;
    import static org.hamcrest.Matchers.*;

    通过例子学习是有效的学习方式之一,下面通过常用的示例演示如何使用assertThat,更详细的用法请参考Hamcrest相关文档。

  • 字符相关匹配符


    /**equalTo匹配符断言被测的testedValue等于expectedValue,
    * equalTo可以断言数值之间,字符串之间和对象之间是否相等,相当于Object的equals方法
    */
    assertThat(testedValue, equalTo(expectedValue));

    /**equalToIgnoringCase匹配符断言被测的字符串testedString
    *在忽略大小写的情况下等于expectedString
    */
    assertThat(testedString, equalToIgnoringCase(expectedString));

    /**equalToIgnoringWhiteSpace匹配符断言被测的字符串testedString
    *在忽略头尾的任意个空格的情况下等于expectedString,
    *注意:字符串中的空格不能被忽略
    */
    assertThat(testedString, equalToIgnoringWhiteSpace(expectedString);

    /**containsString匹配符断言被测的字符串testedString包含子字符串subString**/
    assertThat(testedString, containsString(subString) );

    /**endsWith匹配符断言被测的字符串testedString以子字符串suffix结尾*/
    assertThat(testedString, endsWith(suffix));

    /**startsWith匹配符断言被测的字符串testedString以子字符串prefix开始*/
    assertThat(testedString, startsWith(prefix));

  • 一般匹配符


    /**nullValue()匹配符断言被测object的值为null*/
    assertThat(object,nullValue());

    /**notNullValue()匹配符断言被测object的值不为null*/
    assertThat(object,notNullValue());

    /**is匹配符断言被测的object等于后面给出匹配表达式*/
    assertThat(testedString, is(equalTo(expectedValue)));

    /**is匹配符简写应用之一,is(equalTo(x))的简写,断言testedValue等于expectedValue*/
    assertThat(testedValue, is(expectedValue));

    /**is匹配符简写应用之二,is(instanceOf(SomeClass.class))的简写,
    *断言testedObject为Cheddar的实例
    */
    assertThat(testedObject, is(Cheddar.class));

    /**not匹配符和is匹配符正好相反,断言被测的object不等于后面给出的object*/
    assertThat(testedString, not(expectedString));

    /**allOf匹配符断言符合所有条件,相当于“与”(&&)*/
    assertThat(testedNumber, allOf( greaterThan(8), lessThan(16) ) );

    /**anyOf匹配符断言符合条件之一,相当于“或”(||)*/
    assertThat(testedNumber, anyOf( greaterThan(16), lessThan(8) ) );

  • 数值相关匹配符


    /**closeTo匹配符断言被测的浮点型数testedDouble在20.0¡À0.5范围之内*/
    assertThat(testedDouble, closeTo( 20.0, 0.5 ));

    /**greaterThan匹配符断言被测的数值testedNumber大于16.0*/
    assertThat(testedNumber, greaterThan(16.0));

    /** lessThan匹配符断言被测的数值testedNumber小于16.0*/
    assertThat(testedNumber, lessThan (16.0));

    /** greaterThanOrEqualTo匹配符断言被测的数值testedNumber大于等于16.0*/
    assertThat(testedNumber, greaterThanOrEqualTo (16.0));

    /** lessThanOrEqualTo匹配符断言被测的testedNumber小于等于16.0*/
    assertThat(testedNumber, lessThanOrEqualTo (16.0));

  • 集合相关匹配符


    /**hasEntry匹配符断言被测的Map对象mapObject含有一个键值为"key"对应元素值为"value"的Entry项*/
    assertThat(mapObject, hasEntry("key", "value" ) );

    /**hasItem匹配符表明被测的迭代对象iterableObject含有元素element项则测试通过*/
    assertThat(iterableObject, hasItem (element));

    /** hasKey匹配符断言被测的Map对象mapObject含有键值“key”*/
    assertThat(mapObject, hasKey ("key"));

    /** hasValue匹配符断言被测的Map对象mapObject含有元素值value*/
    assertThat(mapObject, hasValue(value));

数据统计

  • 访问量: 167340
  • 日志数: 260
  • 书签数: 81
  • 建立时间: 2007-08-28
  • 更新时间: 2012-06-13

RSS订阅

Open Toolbar