程序员每天工作的基本流程:
1、从svn检出代码;
2、运行单元测试,测试无误,进入下一步;
3、开始一天的代码编写工作;
4、代码提交到服务器之前进行单元测试;
5、单元测试通过提交到svn服务器。
一些关于测试的概念:1、集成测试;2、验收测试、压力测试
由此引出了单元测试的最基本的需求是:实现自动化测试。
该门课程的主要内容:
单元测试
1、自动化测试
(1)通过断言的方式来确定结果是否正确 Assert;
(2)引入 junit 的 jar 包;
(3)创建一个操作类
2、基于测试开发的方式和优点
3、stub 和 mock
4、在容器中测试
(1)jetty
(2)catcus
5、dbunit
接下来我们进行简单的操作
第一步建立一个java工程,导入junit 4.0版本以上的java包,最好不要使用eclipse自带的java包,将该java添加进入工程中
第二步:编写一个我们要进行测试类。我们使用加减操作
package com.weiyuan.test; /** * 需要测试的类用于增删改查操作 * */ public class Calcuate { public int add(int a,int b){ return a+b; } public int minus(int a,int b){ return a-b; } public int divide(int a,int b){ return a/b; } public int mul(int a,int b){ return a/b; } }
第三步:创建我们的测试类,我们在eclipse中创建sourefoder文件夹,命名为test文件夹
默认情况下:
source folder是用来存放Java源代码的,其下的所有Java源文件都会被时时编译成class文件。对于JavaSE的项目会被编译到项目目录下的bin目录下,对于JavaEE项目会被编译到相应的/WEB-INF/classes文件夹中
在test目录下建立包文件,包名称和我们需要测试的类一样,这样编译之后,会把test目录下生成的class文件和src目录下生成的class文件都放在bin目录下的com/weiyuan/test目录下
例如我们要测试cacluate中的add方法,对应的测试方法就像testAdd()开头
package com.weiyuan.test; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class TestCalcuate { private Calcuate calcuate; /** * * 执行任何测试方法之前都会调用该方法 * */ @Before public void setUp(){ calcuate = new Calcuate(); } /** * 为了兼容junit3 * 按照testXX方法命名 * public int (int a,int b){ * */ @Test public void testAdd(){ int result = calcuate.add(12, 20); Assert.assertEquals("加法有问题", result, 32); } }
在junit3中由于测试类继承了了TestCase方法,在调用的时候直接就使用了下面这种形式
@Test public void testAdd(){ int result = calcuate.add(12, 20); assertEquals("加法有问题", result, 32); }
为了能够兼容junit3,使用上面一样的方法,我们可以使用静态导入Assert类来解决上面的问题
package com.weiyuan.test; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.*; public class TestCalcuate { private Calcuate calcuate; /** * * 执行任何测试方法之前都会调用该方法 * */ @Before public void setUp(){ calcuate = new Calcuate(); } /** * 为了兼容junit3 * 按照testXX方法命名 * public int (int a,int b){ * */ @Test public void testAdd(){ int result = calcuate.add(12, 20); assertEquals("加法有问题", result, 32); } }
接下来我们就可以测试
点击
绿色表示正常通过
表示有异常
接下来我们来看junit检查异常
package com.weiyuan.test; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.*; public class TestCalcuate { private Calcuate calcuate; /** * * 执行任何测试方法之前都会调用该方法 * */ @Before public void setUp(){ calcuate = new Calcuate(); } /** * 为了兼容junit3 * 按照testXX方法命名 * public int (int a,int b){ * */ @Test public void testAdd(){ int result = calcuate.add(12, 20); assertEquals("加法有问题", result, 32); } @Test public void testDivide(){ int result = calcuate.divide(12, 0); assertEquals("触发有问题", result, 4); } }
我们在上面除法的时候被除数不能为0,这里肯定会抛出异常
导致上面的用例失败,如果我们要让该用例通过,可以采用下面的方法
标准的JUnit的org.junit.Test注解提供了一个expected属性,你可以用它来指定一个Throwble类型,如果方法调用中抛出了这个异常,这条测试用例就算通过了。
package com.weiyuan.test; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.*; public class TestCalcuate { private Calcuate calcuate; /** * * 执行任何测试方法之前都会调用该方法 * */ @Before public void setUp(){ calcuate = new Calcuate(); } /** * 为了兼容junit3 * 按照testXX方法命名 * public int (int a,int b){ * */ @Test public void testAdd(){ int result = calcuate.add(12, 20); assertEquals("加法有问题", result, 32); } @Test(expected=ArithmeticException.class) public void testDivide(){ int result = calcuate.divide(12, 0); assertEquals("触发有问题", result, 4); } }
这样运行的时候就可以通过测试
接下来我们讲讲性能测试的timeout
package com.weiyuan.test; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.*; public class TestCalcuate { private Calcuate calcuate; /** * * 执行任何测试方法之前都会调用该方法 * */ @Before public void setUp(){ calcuate = new Calcuate(); } /** * 为了兼容junit3 * 按照testXX方法命名 * public int (int a,int b){ * */ @Test public void testAdd(){ int result = calcuate.add(12, 20); assertEquals("加法有问题", result, 32); } @Test(expected=ArithmeticException.class) public void testDivide(){ int result = calcuate.divide(12, 0); assertEquals("触发有问题", result, 4); } /** * 如果测试方法执行超过200毫秒 * 就会报错 * */ @Test(timeout=200) public void testTimeout(){ try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
我们来运行下
@Before 来注释多个方法,这些方法都在每个测试之前运行:
@After来注释的多个方法,这些方法在每个测试方法之后被运行
1 注释(Annotations)
Annotation |
含义 |
@Test public void method() |
定义一个要测试的方法 |
@Before public void method() |
在每一个测试之前都会被执行的方法,这个方法常常用来进行一 些测试环境的准备,比喻说读入输入数据,初始化类 |
@After public void method() |
与@Before进行对应,做一个清理工作 |
@BeforeClass public void method() |
在所有的测试开始之前执行,这个方法在类运行的时候运行, 而且只会运行一次,所以常常用来做一些所有的方法都要依赖 到工作,比喻说,数据库的链接。 |
@AfterClass public void method() |
与@BeforeClass进行对应,做一些类级别的清理工作 |
@Ignore |
表明方法是被忽略的,这个方法非常实用,比喻你的方法已经 修改,但是对应的测试方法还没有得到一致的修改的时候,可以 忽略掉这个测试方法先。 |
@Test(expected=IllegalArgumentException.class) |
检查测试方法是不是抛出了对应的异常 |
@Test(timeout=100) |
如果方法的执行操作所耗费的毫秒数>100MS,那么方法失败。 |