Junit in Action 笔记 第一章

 Never in the field of software development was so much owed by so many to so few lines of code.
                    ---- Martin Fowler

大家都知道,所有的代码都有经过测试才可以交付使用.今天我们就进入Junit In Action  Chapter 1, Junit JumpStart.

首先:让我们看一个简单的类
Calculator 类:

public class Calculator
{
  public double add(double number1, double number2)
  {
    return number1 + number2;
  }
}

很简单,对吧 :-) .简单到你都怀疑这还要测试吗? 基本的程序员也不会写错哦.是的,我们这只是个例子,真正的代码并没有这么简单.下面我们看看怎么测试吧.

在没有Junit以前我们可能编写什么样的测试代码呢?
下面是一个测试实现:
TestCalculator 类

public class TestCalculator
{
  public static void main(String[] args)
  {
    Calculator calculator = new Calculator();
    double result = calculator.add(10, 50);
    if (result != 60)
    {
      System.out.println("Bad result: " + result);
    }
  }
}

测试类也很简单,如果结果不符合你的期望,就在标准输出设备上输出消息.

现在运行这个程序,一切正常,符合你的要求: 但是如果你改变了代码,要使得测试失败,那又会如何呢? 你必须小学地监视输出以找出错误消息.你可能不需要提供输入,但你还是在测试自己监视程序输出的能力.你要测试的是代码,不是测试你自己 :-) !

另外一个解决办法就是, 利用java中的异常机制,测试失败抛出一个异常. 同时,还可以改进代码,使之模块化,更加通用 可以方便的测试Calculator的其他的方法(这里没有给出).让我们看看改进后的测试吧:
一个好一点的TestCalculator类

public class TestCalculator2
{
  private int nbErrors = 0;

  public void testAdd()
  {
    Calculator calculator = new Calculator();
    double result = calculator.add(10, 50);
    if (result != 60)
    {
      throw new RuntimeException("Bad result: " + result);
    }
  }

  public static void main(String[] args)
  {
    TestCalculator2 test = new TestCalculator2();
    try
    {
      test.testAdd();
    }
    catch (Throwable e)
    {
      test.nbErrors++;
      e.printStackTrace();
    }

    if (test.nbErrors > 0)
    {
      throw new RuntimeException("There were " + test.nbErrors
        + " error(s)");
    }
  }
}

改进的代码,把测试独立为一个方法,好处就是可以更简单的关注测试的事情,还具有通用性.在main方法中,当有错误时,输出栈跟踪信息并抛出一个终结性异常.

以上的测试类,已经具备良好的单元测试框架的一些必备要素了.这些要素如下;
  1. 每个单元测试都必须独立于其他的单元测试
  2. 必须以单项测试为单位来检测和报告错误
  3. 必须易于定义要运行的那些单元测试
但是也不缺点:例如当测试方法增多时,急剧增加的Try/catch会让程序员不可接受的.

还好有Junit,Junit 给我们提供了一个很好的测试框架.下面让我们来看看用Junit该怎么测试吧(关于Junit如何安装,请大家baidu一下就知道了).

用Junit编写的TestCalculator程序

import junit.framework.TestCase;

public class TestCalculator3 extends TestCase
{
  public void testAdd()
  {
    Calculator calculator = new Calculator();
    double result = calculator.add(10, 50);
    assertEquals(60, result, 0);
  }
}

该类我们扩展Junit的标准测试类 junit.framework.TestCase 作为开始.这个基类包含了Junit自动运行测试所需要的框架代码.测试方法命名遵守 testXXX() 模式.Junit会自动执行testXXX() 方法.
为了检测结果,我们调用了 assertEquals()方法,这是Junit框架起作用的地方,该方法的javaDoc如下:
  assertEquals
public static void assertEquals(double expected,
                                double actual,
                                double delta)Asserts that two doubles are equal concerning a delta. If the expected value is infinity then the delta value is ignored.

在测试中,符合期望的结果,所有一切运行正常.
注意: 上面函数中的delta 参数.该参数是比较的不确定度范围.在大多数时候可以是0.但如果涉及到浮点运算可以利用delta参数,例如:expected = 1.0009 由于计算机子长的原因可能得不到精确值,可以利用delta设置一个匹配范围,例如delta = 0.0004 这样当actual在(expected - delta, expected + delta)范围内,就认为测试成功.

如何运行Junit:
  假设代码位于 E:/junitbook/jumpstart目录, 下载到的Junit包解压到E:/junit3.8.1目录. 进入到E:/junitbook/jumpstart目录下,则在Windows上可以输入 javac -cp ../../junit3.8.1/junit.jar *.java 编译.
如何用以下命令启动Junit Swing TestRunner 测试.
  java -cp .;../../junit3.8.1/junit.jar junit.swingui.TestRunner TestCalculator
测试结果如图:
测试结果 测试结果图片
可以看到横跨屏幕的绿色进度条,这就是Junit著名的"green bar" .Junit的格言是:
Keep the bar green to keep the code clean.

由于Eclipse提供了与Junit很好的集成,也可以直接在Eclipse中运行,并且在Eclipse中可以节约你的开发时间.Eclipse运行结果如下:
测试结果

 注意: 该测试使用Junit3.8.1及以上版本,在以前版本中,要增加如下的一个构造函数.
public TestCalculator(String name) {super(name);}

本章小节:
    每个开发者都会执行某种测试,以确保代码可以正常工作.由于手工编写代码测试比较繁琐,Junit是一个很好的单元测试框架(也是事实上的java单元测试标准),使得创建,运行和修改单元测试变得简单.
   在本章我们通过一个简单的例子,使用了Junit.Junit还可以做很多事情,以后我们会慢慢谈到.
   在下一章中我们将深入到Junit框架内部,了解Junit如何协同工作以使单元测试变得高效而且充满乐趣.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值