bnv

十二种法宝帮你找bug(一)(译)

上一篇 / 下一篇  2008-01-04 15:58:03

原文http://today.java.net/pub/a/today/2004/01/22/DozenWays.html
如需转载,请与译者联系chdwu@bestreme.com
测试驱动开发最近越来越受到大家的关注,而且我相信大家对它的兴趣会越来越浓厚,一个很重要的原因就是:每个人都知道测试是很重要的,现在也有一些比较专业的开发人员主张测试先行,他们认为这样可以做出更好的软件。这些人也很快发现测试驱动开发让他们的效率提高很多,也减少了很多压力。他们只需要用很少的时间就可以创造出一系列通过的测试和优秀的设计。听起来不错吧?试一试吧,你一定会受益匪浅的!
    这篇文章列出了十二种关于怎样开始写测试和怎样持续下去的实用方法。前面的两个技巧是教你怎样推翻自己已经写出来的代码,因此你不必一下子甩开代码去专注于测试,这样可能会比较容易接受吧。接下来的两个是让你尝试一下进一步了解测试驱动开发的好处的,其余的技巧则是帮你更加有效地完成你的测试。

1 让你的计算机去做那些让人厌烦的事情
 
开始写测试用例的最简单的方法就是将自己可以看到结果的情形都列出来,然后用自动化的方式取代手动方式去验证它们。不要说我懒,我会用计算机来完成这些事情,这样会比手动执行会更加可靠。有些时候可能会碰到比较麻烦的情况,这时候当然还是需要你亲自出马了,那就不要从这种地方开始测试,你应该从那些比较容易的地方开始,那样你可以先找到一点bug来涨涨自信。我发现一般情况下使用main()方法的测试代码比较适合自动化测试的,我不是指我们应用程序的入口点,我们需要的是一个测试的入口以及将测试结果输出来的方式。(用Main()再合适不过了^^)

例如假设你正在写一个java类,它的功能只是实现一个电子表格,一个表格的单元格是用类似"A1"这种用行和列的标帜来定义,这个单元格可以用来存放一些数据,我们利用这个电子表格来实现数据的存储和查找等功能。这里有一个关于main()方式的测试用例:
public static void main(String args[]) {
       
    Spreadsheet sheet = new Spreadsheet();
       
    System.out.println("Cell reference:");
    sheet.put("A1", "5");
    sheet.put("A2", "=A1");
    System.out.println("A2 = " + sheet.get("A2"));
       
    System.out.println("\nCell change propagates:");
    sheet.put("A1", "10");
    System.out.println("A2 = " + sheet.get("A2"));
       
    System.out.println("\nFormula calculation:");
    sheet.put("A1", "5");
    sheet.put("A2", "2");
    sheet.put("B1", "=A1*(A1-A2)+A2/3");
    System.out.println("B1 = " + sheet.get("B1"));
}
或许你会发现对这个很熟悉或者你以前也写过类似的用例,这样做的目的很简单,我们获得了期望得到的结果,然后我们对自己的代码就有了一定的信心而已。这些年来这种方式一直是我的必备武器,它很简单所以我也推荐你们也来用,但是我们也要注意,这种方法可能会耗费自己大量的时间,因为每次只要牵扯到电子表格的代码改变我们就要跑一次这样的测试来检验这些改动是否影响到这里,显然如果我再次运行测试并看到了下面的输出结果我会对自己的改动充满信心。(因为测试证明我的改动没有破坏其他的地方)
Cell reference:
A2 = 5

Cell change propagates:
A2 = 10

Formula calculation:
B1 = 15

这种测试方法有一个很明显的问题:需要我每次都要看看结果然后才能确定我们的测试是否通过,更糟糕的是当我们大量采用这种方式的时候,这种劳动会让你更加痛苦。这样导致的最终结果是让你自己感觉到厌倦甚至会因此而放弃测试。人工检查结果还要求我们在测试运行的时候记住我们所希望看到的结果,这样如果你需要检查的结果由十几个部分组成的时候?……还记得住吗?如果我们记不住,我们的测试就失去了意义.

JUnit,这个工具可以帮你解决这个问题。如果你从来没有用过它,没关系,JUnit FAQ(http://junit.sourceforge.net/doc/faq/faq.htm)可以帮上你的忙,让你快速处理测试。运用JUnit可以让计算机帮你运行这些测试并帮你验证测试结果。下面是在JUnit中运行的测试代码:

import junit.framework.TestCase;

public class SpreadsheetTest extends TestCase {
   
    public void testCellReference() {
        Spreadsheet sheet = new Spreadsheet();
        sheet.put("A1", "5");
        sheet.put("A2", "=A1");
        assertEquals("5", sheet.get("A2"));
    }

    public void testCellChangePropagates() {
        Spreadsheet sheet = new Spreadsheet();
        sheet.put("A1", "5");
        sheet.put("A2", "=A1");
        sheet.put("A1", "10");
        assertEquals("10", sheet.get("A2"));
    }

    public void testFormulaCalculation() {
        Spreadsheet sheet = new Spreadsheet();
        sheet.put("A1", "5");
        sheet.put("A2", "2");
        sheet.put("B1", "=A1*(A1-A2)+A2/3");
        assertEquals("15", sheet.get("B1"));
    }
}

请注意:结果的验证已经用assertEquals()方法来处理了,这个方法帮你验证我们所期望的值是否和测试运行后的结果一致,这样就不需要你痛苦地记忆那些数据了。

JUnit有文本和图形化两种,不管是哪一种都能为你提供简约而精确的输出。如果使用文本形式的,当所有的测试都通过(预期结果与实际运行结果一致)的时候你可看到:

> java junit.textui.TestRunner SpreadsheetTest

...
Time: 0.04

OK (3 tests)

如果是使用具有图形界面的,这时候你会看到一个绿色的条:
Green bar
Figure 1. Green is good
如果期望与实际运行结果不符,JUnit会迅速作出反应,根据选用的JUnit形式不同,看到的可能是一个刺眼的失败信息或者一个红色的条,同时会提供关于测试详细信息。

自动化测试是多此一举?现在你有了一个自动化测试方法来取代那些让你深感痛苦的人工测试(想想你要同时记住十五个数据吧),它还可以让你有充足的时间去设计更加全面的测试。有本书Pragmatic UnitTestinghttp://www.pragmaticprogrammer.com/starter_kit/ut/index.html)可以帮助你提升你的测试技巧从而写出更好的测试,如果你写了很多测试,你也不需要多花很多时间来运行这些测试,实际上随着项目测试的逐渐深入,自动化测试的价值会逐渐提升,还是因为它节省时间,从而让你有充足的时间写出好的测试。


TAG:

 

评分:0

我来说两句

Open Toolbar