ScalaTest 应用

 

ScalaTest 简介

ScalaTest 是一个开源的Java,Scala 的测试框架,它整合了JUnit, TestNG, Ant, and Maven 使你能非常高效,同时又符合你自己需要的单元测试方式。

APIhttp://www.scalatest.org/scaladoc/doc-1.2/

ScalaTest 单元测试基础

首先看一下ScalaTest 本身提供了哪些测试基类或者特质:

1org.scalatest.Suite

只要把测试类扩展Suite ,并且定义了名字以“test ”开头的测试方法,就可以实现简单的测试,参考下面的代码:

 

    import org.scalatest.Suite
   class MySuite extends Suite{
   def testOk(){
      assert(true)
   }
      def testOther(){
        assert(true)
   }
}
 

 

testOk() 函数就是为了测试MySuite 这个测试类是否能够跑通,如果想看看测试效果,你可以写个object 中的main 方法中new 一个MySuite 对象调用execute() 方法,可以测试所有方法,像这样

   

 

(new MySuite).execute()
 

 

 

这是控制台会打印测试结果,

    Test Starting - MySuite: testOk

Test Succeeded - MySuite: testOk

Test Starting - MySuite: testOther

Test Succeeded - MySuite: testOther

这说明测试成功了。execute() 方法还提供了一个String 参数,传入方法名,作用就是测试特定的方法( 假设MySuite 中含有2 个以上的方法) ,像这样

   

 

(new MySuite).execute("testOk")
 

 

 

ps :在这里会发生版本冲突,如果你的scala.**.jar 的版本是2.8 ,那么scalatest 版本最好是1.2 。经测试,如果不是这样,yoursuite.execute() 方法会失效报异常,必须传入具体方法名才有效。

2org.scalatest.FunSuite    extends Suite

ScalaTest 提供了名为 FunSuite 的特质,重载了execute ,从而可以让你以函数值的方式而不是方法定义测试:

 

import org.scalatest.FunSuite
    class MyFunSuite extends FunSuite{
      test("if ok"){
      assert(true)
   }
}
 

 

FunSuite 的一个好处是你不用给你所有的测试以“test ”开头起名。而且,你可以更容易地给你的测试起很长的名称,因为你不需要把它们编码为驼峰形式。

下面我们再来看看scalatest 提供了哪些断言方法。

 

ScalaTest 断言

1assert()

第二节中已经出现这个断言,单参数的assert(condition 表达式) 已经了解,完全类似于JUnitassertEqauls(value1,value2) 方法,不过scalatestassert() 方法又重载了双参数的方法,其作用就是自定义报错提示,

    assert(condition 表达式,“报错的文本提示”)

如果在condition 表达式中运用“=== ”,那么其作用相当于assert() 双参数方法,但是报错提示是缺省格式的,像这样3 did not equal 2

2except()

except() 方法的结构是这样的,except( 期望值){ 比较值} ,报错信息像这样Expected 2, but got 3 ,同样scalatestexcept 提供了类似assert 第二参数的作用,

    except( 期望值,“报错的文本提示”){ 比较值}

3intercept()

其作用检查方法是否抛出了期待的异常,其结构是,

    intercept(classOf[ 异常类]){ 会抛异常的表达式}

       

    intercept(classOf[ 异常类] ,“自定义报错信息”){ 会抛异常的表达式}

如果代码没有抛出异常,或抛出了不同的异常,intercept 将抛出 AssertionError 前者的缺省报错则类似这样,Expected IllegalArgumentException to be thrown, but NegativeArraySizeException was thrown.

4)org.scalatest.matchers.ShouldMatchers org.scalatest.matchers.MustMatchers

如果你想使用更丰富的更个性的断言表达式,可以在你的单元测试类里面混入这两个匹配器

他们的表达方式是这样的:

 

object should equal (3) 和 object must equal (3)
 

他们还有很多表达式这里就不一一列举了详见API

如果你想知道他们有什么区别,可以告诉你们这俩个类的实现方式是一样的,只是语气上是

shouldmust 的区别,作用也是一样的,你比较顺眼哪个就混入哪个。

 

ScalaTest 单元测试的运行

1)org.scalatest.tools.Runner 运行

ScalaTestRunner 应用可以在命令行或ant 任务中调用。前提条件是被测试对象必须是Suite 测试集。Runner 工具运行必须指定要运行的测试集,方式包括显式说明测试集名称或者说明你想要Runner 执行自动发现的测试集名称前缀。你可以选择性地指定运行路径:runpath ,目录列表和装载测试类的JAR 文件以及它们测试的代码。你还可以指定一个或多个报表器,以格式化测试结果的外观。例如,ScalaTest 的发布包里包含了测试ScalaTest 自身的测试集。你可以使用下列命令执行其中的测试集,SuiteSuite

        我在本机进入scalatest-1.2 的安装目录下,输入

        >scala cp scalatest-1.2.jar org.scalatest.tools.Runner

              -p "scalatest-1.2-tests.jar" s org.scalatest.SuiteSuite

        就可以运行SuiteSuite 这个测试集了,还会有工具自带的GUI 窗口显示:


ScalaTest 应用

 

 

-cp 的目的是把 ScalaTest JAR 文件放在类路径中。下一项,org.scalatest.tools.Runner ,是 Runner 应用的全称。Scala 将运行这个应用并把剩余的项当做命令行参数传递给应用。-p 指定了运行路径,这里是包含了测试集类的 JAR 文件:scalatest-1.2-tests.jar-s 说明了SuiteSuite 是要执行的测试集。

如果每一个Suite 测试集都要输一个命令行来执行的话,必然是相当麻烦,下面就来看看在ant 任务中配置Runner 运行脚本是怎么样的:

最主要的就是配置antbuild.xml ,写好这个配置文件,Eclipse 想要运行build 任务,就只需调用ant 工具就可以了。这个是build.xml 的主要配置代码:引入了scalatest 提供的

org.scalatest.tools.ScalaTestAntTask 标签库。       

 

    <?xml version="1.0" encoding="GB2312"?>
    <project name="scala_ceshi" default="test" basedir=".">
    <property name="scala.home"            value="C:\Program Files\scala-2.8.0"/>   
    <property name="src.dir"               value="src"/>
    <property name="test.dir"            value="test"/>
    <property name="build.dir"             value="build"/>
    <property name="build.test"         value="${build.dir}/test" />
    <property name="build.classes"         value="${build.dir}/classes" />
    <property name="scala-library.jar" value="${scala.home}/lib/scala-library.jar"/>
    <target name="clean" description="Removes previous build">
           <delete quiet="true" verbose="false" dir="${build.dir}"/>
    </target>
    <target name="make_dir" depends="clean">
        <mkdir dir="${build.classes}"/>
        <mkdir dir="${build.test}"/>
    </target>
    <target name="init_classpaths" depends="make_dir">
          <path id="classpath.build">
                <pathelement location="${scala-library.jar}"/>
          </path>
          <path id="classpath.test">
               <pathelement location="${build.classes}" />
                <pathelement location="C:\apache-maven-2.2.1\MyRepository\org\scalatest\scalatest\1.0.1-for-scala-2.8.0.Beta1-NQRFPT\scalatest-1.0.1-for-scala-2.8.0.Beta1-NQRFPT.jar" />
                <pathelement location="${scala-library.jar}"/>
          </path>
    </target>
    <target name="init_ant_tasks" depends="init_classpaths">
        <taskdef resource="scala/tools/ant/antlib.xml">
              <classpath>
                    <pathelement location="${scala.home}/lib/scala-compiler.jar"/>
                    <pathelement location="${scala-library.jar}"/>
              </classpath>
        </taskdef>
        <taskdef name="scalatest" classname="org.scalatest.tools.ScalaTestAntTask">
          <classpath refid="classpath.test"/>
        </taskdef>
    </target>
    <target name="compile" depends="init_ant_tasks">
         <scalac srcdir="${src.dir}"
                destdir="${build.classes}"
                classpathref="classpath.build"
                deprecation="on"
                force="changed">
        </scalac>
    </target>
    <target name="test" depends="compile">
        <scalac srcdir="${test.dir}"
                destdir="${build.test}"
                classpathref="classpath.test"
                force="changed">
        </scalac>
        <scalatest>
            <runpath>
                <pathelement location="${build.test}"/>
            </runpath>
            <reporter type="stdout"/>
            <suite classname="YourSuiteTestName"/>
        </scalatest>
    </target>
    </project>

 

 

这样就可以用<scalatest> 标签配置NSuite 测试集了。调用ant-build 既可以测试相关的单元测试。

    2 )使用JUnit 运行

    JUnit 运行scalatestSuite 测试集的方式也很多:

    这里就说由scalatest 自己提供的类库实现运行,

    首先是org.scalatest.junit.JUnit3Suite org.scalatest.junit.JUnitSuite

    只要你的测试集扩展了这两个类中一个类,你就可以用相应的JUnit3JUnit4 工具运行这个测试集,该测试集中可以使用Suite 所有断言语法,当然你的测试集也可以用scalatestRunner 工具运行。如果就想把测试集当成一个只用JUnit 运行的测试的话,那么你的测试集混入org.scalatest.junit.AssertionsForJunit 特质即可。

使用这种混入JUnit 特质的方式时,必须要在测试方法前加入org.junit.Test 标签,这样

JUnit 才能识别该方法的有效性。

=================================================================

接下来一种方法就是org.junit.runner.RunWith org.scalatest.junit.JUnitRunner 的组合使用:

 

import org.junit.runner.RunWith
import org.scalatest.junit.JUnitRunner
import org.scalatest.Suite
@RunWith(classOf[JUnitRunner])
class MySuiteTest extends Suite {
    def testAddition() {
       val sum = 1 + 1
       assert(sum === 2)
       assert(sum + 2 === 4)
    }
    def testSubtraction() {
       val diff = 4 - 1
       assert(diff === 3)
       assert(diff - 2 === 1)
    }
}
 

 

这样,JUnit 工具也可以运行这个Suite 测试集。

 

你可能感兴趣的:(maven,scala,ant,JUnit,单元测试)