欢迎光临
我们一直在努力

JUnit实施–5.JUnit简介-JSP教程,资料/其它

建站超值云服务器,限时71元/月

5.junit简介

既然我们已经对junit有了一个大致的了解,我希望能给大家提供一个稍微正式一些的编写junit测试文档的手册,明白其中的一些关键术语和概念。但我要声明的是这并不是一本完全的手册,只能认为是一本入门手册。同其他opensource的软件有同样的问题,junit的文档并没有商业软件文档的那种有规则,简洁和完全。由开发人员编写的文档总是说不太清楚问题,全整的文档需要参考"官方"指南,api手册,邮件讨论组的邮件,甚至包括源代码中及相关的注释。

事实上问题并没有那么复杂,除非你有非常特别的要求,否则,只需参考本文你就可以得到所需的大部分信息。

  1. 安装

    首先你要获取junit的软件包,从junit下载最新的软件包(截至写作本文时,junit的最新版本是3.7)。将其在适当的目录下解包。这样在安装目录(也就是你所选择的解包的目录)下你找到一个名为junit.jar的文件。将这个jar文件加入你的classpath系统变量。(ide的设置会有所不同,参看你所喜爱的ide的配置指南)junit就安装完了。太easy了!

    你一旦安装完junit,就有可能想试试我们的car和testcar类,没问题,我已经运行过了,你得到的结果应该和我列出的结果类似。(以防新版junit使我的文章过时)

    接下来,你可能会先写测试代码,再写工作代码,或者相反,先写工作代码,再写测试代码。我更赞成使用前一种方法:先写测试代码,再写工作代码。因为这样可以使我们编写工作代码时清晰地了解工作类的行为。

    要注意编写一定能通过的测试代码(如文中的例子)并没有任何意义,只有测试代码能帮助我们发现bug,测试代码才有其价值。此外测试代码还应该对工作代码进行全面的测试。如给方法调用的参数传入空值、错误值和正确的值,看看方法的行为是否如你所期望的那样。

    你现在已经知道了编写测试类的基本步骤:
    1>扩展testcase类;
    2>覆盖runtest()方法(可选);
    3>写一些testxxxxx()方法;

  2. fixture

    解下来的问题是,如果你要对一个或若干个的类执行多个测试,该怎么办?junit对此有特殊的解决办法。

    如果需要在一个或若干个的类执行多个测试,这些类就成为了测试的context。在junit中被称为fixture(如testcar类中的 mycar 和 expectedwheels )。当你编写测试代码时,你会发现你花费了很多时间配置/初始化相关测试的fixture。将配置fixture的代码放入测试类的构造方法中并不可取,因为我们要求执行多个测试,我并不希望某个测试的结果意外地(如果这是你要求的,那就另当别论了)影响其他测试的结果。通常若干个测试会使用相同的fixture,而每个测试又各有自己需要改变的地方。

    为此,junit提供了两个方法,定义在testcase类中。

            protected void setup() throws java.lang.exception        protected void teardown() throws java.lang.exception        

    覆盖setup()方法,初始化所有测试的fixture(你甚至可以在setup中建立网络连接),将每个测试略有不同的地方在testxxx()方法中进行配置。

    覆盖teardown()(我总想起一首叫雨滴的吉他曲),释放你在setup()中分配的永久性资源,如数据库连接。

    当junit执行测试时,它在执行每个testxxxxx()方法前都调用setup(),而在执行每个testxxxxx()方法后都调用teardown()方法,由此保证了测试不会相互影响。

  3. testcase

    需要提醒一下,在junit.framework.assert类中定义了相当多的assert方法,主要有assert(), assert(), assertequals(), assertnull(), assertsame(), asserttrue(), fail()等方法。如果你需要比较自己定义的类,如car。assert方法需要你覆盖object类的equals()方法,以比较两个对象的不同。实践表明:如果你覆盖了object类的equals()方法,最好也覆盖object类的hashcode()方法。再进一步,连带object类的tostring()方法也一并覆盖。这样可以使测试结果更具可读性。

    当你设置好了fixture后,下一步是编写所需的testxxx()方法。一定要保证testxxx()方法的public属性,否则无法通过内省(reflection)对该测试进行调用。

    每个扩展的testcase类(也就是你编写的测试类)会有多个testxxx()方法。一个testxxx()方法就是一个测试。要想运行这个测试,你必须定义如何运行该测试。如果你有多个testxxx()方法,你就要定义多次。junit支持两种运行单个测试的方法:静态的和动态的方法。

    静态的方法就是覆盖testcase类的runtest()方法,一般是采用内部类的方式创建一个测试实例:

            testcase test01 = new testcar("test getwheels") {            public void runtest() {                testgetwheels();            }        }            

    采用静态的方法要注意要给每个测试一个名字(这个名字可以任意起,但你肯定希望这个名字有某种意义),这样你就可以区分那个测试失败了。

    动态的方法是用内省来实现runtest()以创建一个测试实例。这要求测试的名字就是需要调用的测试方法的名字:

            testcase test01 = new testcar("testgetwheels");            

    junit会动态查找并调用指定的测试方法。动态的方法很简洁,但如果你键入了错误的名字就会得到一个令人奇怪的nosuchmethodexception异常。动态的方法和静态的方法都很好,你可以按照自己的喜好来选择。(先别着急选择,后面还有一种更酷的方法等着你呢。)

  4. testsuite

    一旦你创建了一些测试实例,下一步就是要让他们能一起运行。我们必须定义一个testsuite。在junit中,这就要求你在testcase类中定义一个静态的suite()方法。suite()方法就像main()方法一样,junit用它来执行测试。在suite()方法中,你将测试实例加到一个testsuite对象中,并返回这个testsuite对象。一个testsuite对象可以运行一组测试。testsuite和testcase都实现了test接口(interface),而test接口定义了运行测试所需的方法。这就允许你用testcase和testsuite的组合创建一个testsuite。这就是为什么我们前面说testcase,testsuite以及testsuite组成了一个composite pattern的原因。例子如下:

            public static test suite() {            testsuite suite= new testsuite();            suite.addtest(new testcar("testgetwheels"));            suite.addtest(new testcar("testgetseats"));            return suite;        }            

    从junit 2.0开始,有一种更简单的动态定义测试实例的方法。你只需将类传递给testsuite,junit会根据测试方法名自动创建相应的测试实例。所以你的测试方法最好取名为testxxx()。例子如下:

            public static test suite() {            return new testsuite(testcar.class);        }            

    从junit的设计我们可看出,junit不仅可用于单元测试,也可用于集成测试。关于如何用junit进行集成测试请参考相关资料

    为了兼容性的考虑,下面列出使用静态方法的例子:

            public static test suite() {            testsuite suite= new testsuite();            suite.addtest(                new testcar("getwheels") {                     protected void runtest() { testgetwheels(); }                }            );                suite.addtest(                new testcar("getseats") {                     protected void runtest() { testgetseats(); }                }            );            return suite;                    }            
  5. testrunner

    有了testsuite我们就可以运行这些测试了,junit提供了三种界面来运行测试

            [text  ui] junit.textui.testrunner        [awt   ui] junit.awtui.testrunner        [swing ui] junit.swingui.testrunner            

    我们前面已经看过文本界面了,下面让我们来看一看图形界面:

    JUnit实施--5.JUnit简介-JSP教程,资料/其它

    界面很简单,键入类名-testcar。或在启动ui的时候键入类名:

            [windows] d:>java junit.swingui.testrunner testcar            [unix] % java junit.swingui.testrunner testcar        

    从图形ui可以更好的运行测试可查单测试结果。还有一个问题需要注意:如果junit报告了测试没有成功,junit会区分失败(failures)和错误(errors)。失败是一个期望的被assert方法检查到的结果。而错误则是意外的问题引起的,如arrayindexoutofboundsexception。

    由于testrunner十分简单,界面也比较直观,故不多介绍。朋友们可自行参考相关资料。

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » JUnit实施–5.JUnit简介-JSP教程,资料/其它
分享到: 更多 (0)