读书人

JUnit3.8的Junit单元测试

发布时间: 2012-12-22 12:05:06 作者: rapoo

JUnit3.8的Junit单元测试.

注:转自JavaEye中zhouwendong006的博客http://zhouwendong006.iteye.com/blog/3727951.  建立一个工程,取名随意。2.  建立包(com.test.junit3),并建立一个计算类(Calculator),添加其相应的方法。完成后代码如下:Java代码 public class Calculator {           public int add(int a, int b) {            return a + b;        }           public int minus(int a, int b) {            return a - b;        }           public int multiply(int a, int b) {            return a * b;        }           public int divide(int a, int b) throws Exception {            if (0 == b) {                throw new Exception("除数不能为0!");            }            return a / b;        }    }   public class Calculator {public int add(int a, int b) {return a + b;}public int minus(int a, int b) {return a - b;}public int multiply(int a, int b) {return a * b;}public int divide(int a, int b) throws Exception {if (0 == b) {throw new Exception("除数不能为0!");}return a / b;}}这里面的方法比较简单,不在解释。3.  建立测试类。     a.  建立测试类的时候(我指的是使用Eclipse或者MyEclipse进行开发的时候),一般将测试类放到另外一个源文件夹中。在项目上点右键,选择new-->Source Folder。名字随意,一般取名字test。     b.  建立测试包。包名一般与需要被测试的类的包名相同,在这里,包名与Calculator类的包名相同(com.test.junit3)。     c.   建立测试类。测试类命名一般是需要被测试的类名加上后缀“Test”,这里为CalculatorTest。4.  测试类需要注意的方面。在这里,也就是CalculatorTest需要遵守的规则。     a.  测试类必须继承TestCase类。     b.  测试方法必须为public型的,void的,没有方法参数,且方法名必须以“test”为前缀,即以test开头(如果不以test开头,那该方法需要手动启动测试。运行测试类的时候,该方法是无法被自动进行测试的)。5. 实际的测试类。Java代码 package com.test.junit3;       import junit.framework.Assert;    import junit.framework.TestCase;       public class CalculatorTest extends TestCase{           private Calculator cal;                /**        * 执行每一个测试方法的时候,先执行setUp();        */       protected void setUp() throws Exception {            cal=new Calculator();               }           /**        * 执行每一个测试方法之后,执行tearDown();        */       protected void tearDown() throws Exception {            super.tearDown();        }                public void testAdd(){            int result=cal.add(1, 2);            //断言:assert            Assert.assertEquals(3, result);        }                public void testMinus(){            int result =cal.minus(1, 2);            Assert.assertEquals(-1, result);        }                public void testMultiply(){            int result =cal.multiply(2, 3);            Assert.assertEquals(6, result);        }                public void testDivied(){            int result=0;            try {                result = cal.divide(6, 4);            } catch (Exception e) {                e.printStackTrace();                Assert.fail();            }            Assert.assertEquals(1, result);        }                public void testDivied2(){            Throwable tx=null;            try {                cal.divide(4, 0);                Assert.fail();            } catch (Exception e) {                tx=e;            }                            //断言tx是否为空            Assert.assertNotNull(tx);                        //断言两个对象是否相同            Assert.assertEquals(Exception.class,tx.getClass());                        //断言String是否相同            Assert.assertEquals("除数不能为0!", tx.getMessage());        }    }   package com.test.junit3;import junit.framework.Assert;import junit.framework.TestCase;public class CalculatorTest extends TestCase{private Calculator cal;/** * 执行每一个测试方法的时候,先执行setUp(); */protected void setUp() throws Exception {cal=new Calculator();}/** * 执行每一个测试方法之后,执行tearDown(); */protected void tearDown() throws Exception {super.tearDown();}public void testAdd(){int result=cal.add(1, 2);//断言:assertAssert.assertEquals(3, result);}public void testMinus(){int result =cal.minus(1, 2);Assert.assertEquals(-1, result);}public void testMultiply(){int result =cal.multiply(2, 3);Assert.assertEquals(6, result);}public void testDivied(){int result=0;try {result = cal.divide(6, 4);} catch (Exception e) {e.printStackTrace();Assert.fail();}Assert.assertEquals(1, result);}public void testDivied2(){Throwable tx=null;try {cal.divide(4, 0);Assert.fail();} catch (Exception e) {tx=e;}//断言tx是否为空Assert.assertNotNull(tx);//断言两个对象是否相同Assert.assertEquals(Exception.class,tx.getClass());//断言String是否相同Assert.assertEquals("除数不能为0!", tx.getMessage());}}   a.  如果被测试的方法绝对不会有异常抛出(如:Calculator中的add(int a,int b)),那么在测试类(CalculatorTest)中可以像下面的代码一样,直接使用断言Assert类中的assertEquals(int expected, int actual)方法直接断言。该方法传入两个int参数,一个表示期望值,即按照设计应该得到的结果expected,一个表示实际值,即程序实际得到的结果actual。如果这两个结果相同,则表示被测试的类即(Calculator)中的该方法没有错误。Java代码 public void testAdd(){        int result=cal.add(1, 2);        //断言:assert        Assert.assertEquals(3, result);    }   public void testAdd(){int result=cal.add(1, 2);//断言:assertAssert.assertEquals(3, result);}       补充:Assert中的assertEquals()方法传入的参数基本可以是所有的类型,包括String、int、char等等,具体的自己看。注意:预期值和实际值的类型必须一致。    b.  如果被测试的方法有异常抛出(如:Calculator中的divied(int a,int b)),那么在测试类中如果直接使用断言Assert中的assertEquals(int expected, int actual)方法时,传入参数b为0的时候,如下:Java代码 public void testDivied(){        int result=0;        try {            result = cal.divide(6, 0);        } catch (Exception e) {            e.printStackTrace();            Assert.fail();        }        Assert.assertEquals(1, result);    }   public void testDivied(){int result=0;try {result = cal.divide(6, 0);} catch (Exception e) {e.printStackTrace();Assert.fail();}Assert.assertEquals(1, result);}       无论你的代码是否完善,是否已经正确无误了,TestBar显示仍为红条,表示该方法无法通过测试。正确的写法应该如下:Java代码 public void testDivied2(){           //Throwable为Exception和Error的父类.        Throwable tx=null;        try {            cal.divide(4, 0);            Assert.fail();        } catch (Exception e) {            tx=e;        }                //断言tx是否为空        Assert.assertNotNull(tx);                //断言两个对象是否相同        Assert.assertEquals(Exception.class,tx.getClass());                //断言异常信息是否为指定异常信息。tx.getMessage()获取异常抛出的信息        Assert.assertEquals("除数不能为0!", tx.getMessage());    }   public void testDivied2(){//Throwable为Exception和Error的父类.Throwable tx=null;try {cal.divide(4, 0);Assert.fail();} catch (Exception e) {tx=e;}//断言tx是否为空Assert.assertNotNull(tx);//断言两个对象是否相同Assert.assertEquals(Exception.class,tx.getClass());//断言异常信息是否为指定异常信息。tx.getMessage()获取异常抛出的信息Assert.assertEquals("除数不能为0!", tx.getMessage());}       “Assert.fail;”表示该方法测试失败,它的目的是:假如它被执行到了,那么表示divide(int a,int b)方法没有抛出异常,也就是方法中有bug。       “tx=e;”将异常e赋给tx,将局部变量赋给全局变量,以便进行下面操作。       “Assert.assertNotNull(tx);”断言tx是否为空,如果tx为空,则说明divide(int a,int b)方法没有将异常抛出,方法中存在bug。       “Assert.assertEquals(Exception.class,tx.getClass());”。tx.getClass()可以得到tx,也就是这个异常是哪个类,然后断言是否与你期望的异常类相同。如果不同,测试失败,方法抛出异常错误,方法中存在bug。其实到这里可以结束了,而“Assert.assertEquals("除数不能为0!",tx.getMessage());”是为了通过断言异常信息,更进一步判断该异常是否是你在方法中指定的异常。       这样,通过这些断言,可以保证你的方法目前没有发现bug存在,测试的时候,该方法会通过,表现方式为TestBar为绿色通过。6.  在测试的时候,再TestCase中有两个方法,一个为setUp(),表示初始化。该方法在每个测试方法执行之前将被首先执行。比如如果要执行testAdd()方法的时候,先要执行一遍setUp()方法。因此该方法一般进行一些初始化操作,比如对被测试类的实例化,如:Java代码 protected void setUp() throws Exception {        cal=new Calculator();       }   protected void setUp() throws Exception {cal=new Calculator();}         另一个方法为tearDown(),该方法在每个测试方法执行之后执行,因此该方法一般处理每个测试方法结束后的资源释放操作。       总的来说:如果测试类中有3个测试方法test1(),test2(),test3(),那么方法的执行顺序为       setUp()->test1()->tearDown()->setUp()->test2()->tearDown()->setUp()->test3()->tearDown()7.  测试的时候,一般要注意临界值的测试。如除数不能为0,索引越界等问题。8.  如果在没有IDE的情况下,可以通过使用TestRunner类进行测试,如以下代码所示Java代码 public static void main(String[] args) {        junit.awtui.TestRunner.run(CalculatorTest.class);    }   public static void main(String[] args) {junit.awtui.TestRunner.run(CalculatorTest.class);}       需要注意的是:在junit.awtui、junit.swingui和junit.textui三个包下均有TestRunner类,任何一个类都可以执行测试任务。只是表现的方式不同,看你喜欢用哪个了!9.  在执行多个测试类的时候,一个一个点运行,进行测试显然是非常费时的事情。junit提供了一个类TestSuite可以将多个测试类一起运行,进行测试。示例代码如下:Java代码 package com.test.junit3;       import junit.framework.Test;    import junit.framework.TestCase;    import junit.framework.TestSuite;       public class TestAll extends TestCase {                /**        * 该方法名称必须为suite(),不能更改        * 该方法中        * TestSuite对象不仅可以添加测试类,还可以包装suite对象        * @return        */       public static Test suite(){                        TestSuite suite=new TestSuite();            suite.addTestSuite(LargestTest.class);            suite.addTestSuite(CalculatorTest.class);                        return suite;        }    }   package com.test.junit3;import junit.framework.Test;import junit.framework.TestCase;import junit.framework.TestSuite;public class TestAll extends TestCase {/** * 该方法名称必须为suite(),不能更改 * 该方法中 * TestSuite对象不仅可以添加测试类,还可以包装suite对象 * @return */public static Test suite(){TestSuite suite=new TestSuite();suite.addTestSuite(LargestTest.class);suite.addTestSuite(CalculatorTest.class);return suite;}}         如注释所示,该静态方法名称必须为suite(),原因可以参看junit源代码。另外该方法返回Test对象。TestSuite中有两个方法很重要,一个是addTestSuite(),可以直接添加测试类。另一个方法为addTest(),可以添加TestSuite对象,所以,上面也可以通过下面的代码实现:Java代码 package com.test.junit3;       import junit.framework.Test;    import junit.framework.TestCase;    import junit.framework.TestSuite;       public class TestAll extends TestCase {                public static Test suite(){                        TestSuite suite=new TestSuite();                        TestSuite suite1=new TestSuite();            suite1.addTestSuite(LargestTest.class);                        TestSuite suite2=new TestSuite();            suite2.addTestSuite(CalculatorTest.class);                        suite.addTest(suite1);            suite.addTest(suite2);               return suite;        }    }   package com.test.junit3;import junit.framework.Test;import junit.framework.TestCase;import junit.framework.TestSuite;public class TestAll extends TestCase {public static Test suite(){TestSuite suite=new TestSuite();TestSuite suite1=new TestSuite();suite1.addTestSuite(LargestTest.class);TestSuite suite2=new TestSuite();suite2.addTestSuite(CalculatorTest.class);suite.addTest(suite1);suite.addTest(suite2);return suite;}}       这样我们可以方便的对多个测试类进行测试了。

?

读书人网 >编程

热点推荐