1, junit的安裝和調試原則java
1)導入junit的jar包,這裏使用junit4.10, 不建議使用Eclipse自帶的.sql
2)建立測試類的原則:數據庫
在Eclipse中建立一個source folder 命名爲testapi
建立測試類所在的包,包名與要測試的類的包名一致ide
3)Junit3 和Junit4的區別是比較大的工具
在Junit3中,若是某個類是測試類,必須繼承TestCase,若是某個方法是測試方法,這個方法必須是testXXX的形式;性能
在Junit3中,若是但願指定某個測試方法運行以前運行某個初始化方法,這個方法的名稱必須是setUp(),若是但願在某個測試方法運行以後運行某個釋放資源的方法,這個方法的名稱必須是 tearDown.測試
在Junit4中,一個Pojo類就是一個測試類,測試方法經過@Test標識,初始化方法經過@Before標識,釋放資源的方法經過@After標識。可是爲了讓Junit4中的測試類在Junit3中也可使用,習慣上把初始化方法命名爲setUp,釋放資源的方式命名爲tearDown,測試方法也一樣以test開頭.spa
3)斷言的使用調試
在Junit4中提供了一個Assert的類,這個類中有大量的方法進行斷言處理,在Junit3中因爲繼承了TestCase類,TestCase類提供了大量的assert方法.
2, 第一個簡單的Junit測試例子
package com.yangw.util; public class Calcuate { public int add(int a,int b){ return a+b; } public int divide(int a,int b){ return a/b; } }
package com.yangw.util; import static junit.framework.Assert.*; import org.junit.Before; import org.junit.Test; public class TestCalcuate { Calcuate cal; // 執行任意測試方法以前都會執行該方法 @Before public void setUp(){ cal = new Calcuate(); } @Test public void testAdd(){ /** * 簡單斷言的編寫 * 參數1: 表示若是出差給出的錯誤信息 * 參數2:表示方法執行完成以後預期的一個值 * 參數3:表示實際值 */ //Assert.assertEquals("加法有問題", cal.add(1, 2),3); // 將Assert全部的靜態方法靜態導入,這樣不用添加類名從而有效兼容junit3 assertEquals("加法有問題", cal.add(1, 2),3); } @Test public void testDivide(){ assertEquals("除法有問題", cal.divide(4, 2),2); } //表示這個方法應該拋出ArithmeticException異常,若是不拋出就報錯 @Test(expected=ArithmeticException.class) public void testDivideException(){ cal.divide(4, 0); } //表示這個方法要在300毫秒之內完成. // 能夠進行簡單的性能測試. @Test(timeout=300) public void testTime() throws Exception{ Thread.sleep(500); } }
3,dbunit的使用.
1), 導入 dbunit-2.4.9.jar、slf4j-api-1.6.1.jar
2), 建立dbunit的測試數據xml文件
<?xml version="1.0" encoding="UTF-8"?> <!-- dataset根標籤 --> <dataset> <!-- 表信息 --> <!-- 第一種方式 基於節點的方式--> <!-- <t_user> <id>1</id> <username>yangw</username> <password>123456</password> </t_user> --> <!-- 第二種方式 --> <!-- 基於屬性的方式 --> <t_user id="1" username="yangw" password="123456" /> </dataset>
3), 建立dbunit的Connection
dbunit的Connection是用來對數據文件進行操做的,這個Connection必須依賴於目前項目中所使用的Connection.
IDatabaseConnection conn=new DatabaseConnection(DBUtil.getConnection());
4), 建立IDataSet,經過DataSet來獲取測試數據文件中的數據
//若是xml是基於節點的使用XmlDataSet ,若是是基於屬性的使用 FlatXmlDataSet IDataSet ds = new FlatXmlDataSet(new FlatXmlProducer(new InputSource(TestDbunit.class.getClassLoader().getResourceAsStream("t_user.xml"))));
5), 初始化數據而且完成測試
// 清空數據庫中的數據,插入xml中的數據 DatabaseOperation.CLEAN_INSERT.execute(conn, ds); //DatabaseOperation.DELETE 刪除數據庫中存在的xml數據 //DatabaseOperation.DELETE_ALL 刪除數據庫中全部的數據 //DatabaseOperation.INSERT 插入xml中的測試數據 //DatabaseOperation.NONE 什麼都不作 //DatabaseOperation.REFRESH 刷新數據庫中的數據 //DatabaseOperation.TRUNCATE_TABLE 清空數據庫表中的數據 //DatabaseOperation.UPDATE 把數據庫中的數據更新爲xml中目前指定的數據 //從Dao中獲取數據並完成測試 IUserDao ud = new UserDao(); User u = ud.load("yangw"); Assert.assertEquals(u.getId(), 1); Assert.assertEquals(u.getUsername(), "yangw"); Assert.assertEquals(u.getPassword(), "123456");
6) 備份和還原數據庫
6.1. 備份:
/** * 備份數據庫中全部的表 */ @Test public void testBackup(){ try { IDatabaseConnection conn=new DatabaseConnection(DBUtil.getConnection()); //根據Conn來建立DataSet,這個DataSet包含了全部的表 IDataSet ds =conn.createDataSet(); //將ds中的數據經過FlatXmlDataSet格式寫到文件中 FlatXmlDataSet.write(ds, new FileWriter("d://test.xml")); } catch (DataSetException e) { e.printStackTrace(); } catch (DatabaseUnitException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
/** * 備份某些指定的表 */ @Test public void testBackupOne(){ try { IDatabaseConnection conn=new DatabaseConnection(DBUtil.getConnection()); //根據Conn來建立DataSet,這個DataSet包含了全部的表 QueryDataSet qds =new QueryDataSet(conn); //添加t_user這張表爲要備份的表 qds.addTable("t_user"); //將ds中的數據經過FlatXmlDataSet格式寫到文件中 FlatXmlDataSet.write(qds, new FileWriter("d://test.xml")); } catch (DataSetException e) { e.printStackTrace(); } catch (DatabaseUnitException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
6.2 還原
/** * 還原數據庫 */ @Test public void testResume(){ try { IDatabaseConnection conn=new DatabaseConnection(DBUtil.getConnection()); //根據備份文件建立dataset IDataSet ds = new FlatXmlDataSet(new FlatXmlProducer(new InputSource(new FileInputStream("d://test.xml")))); // 清空數據庫中的數據,插入xml中的數據 DatabaseOperation.CLEAN_INSERT.execute(conn, ds); } catch (DatabaseUnitException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
將備份、還原操做寫成一個工具測試類,之後其它測試類只要繼承它便可.
package frame.base.util; import static org.junit.Assert.assertNotNull; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.sql.SQLException; import org.dbunit.DatabaseUnitException; import org.dbunit.database.DatabaseConnection; import org.dbunit.database.IDatabaseConnection; import org.dbunit.database.QueryDataSet; import org.dbunit.dataset.DataSetException; import org.dbunit.dataset.IDataSet; import org.dbunit.dataset.xml.FlatXmlDataSet; import org.dbunit.dataset.xml.FlatXmlProducer; import org.dbunit.operation.DatabaseOperation; import org.junit.AfterClass; import org.junit.BeforeClass; import org.xml.sax.InputSource; /** * 基於DBunit的測試工具類 * @author yangw@eastcom.com * */ public class AbstractDBUtilTestCase { // dbunit的數據庫鏈接 public static IDatabaseConnection dbunitConn; private File tempFile; @BeforeClass // 在構造以前執行,僅僅執行一次 public static void init() throws DatabaseUnitException, SQLException{ dbunitConn = new DatabaseConnection(JdbcUtil.getDBConnection()); } /** * 根據指定的測試文件(xml)獲取IDataSet * @param tname ,通常狀況下,測試的xml文件就用表名命名. * @return * @throws DataSetException * @throws IOException */ protected IDataSet createDataSet(String tname) throws DataSetException, IOException{ InputStream is=AbstractDBUtilTestCase .class .getClassLoader() .getResourceAsStream("dbunit_xml/"+tname+".xml"); assertNotNull("dbunit的基本數據文件不存在!", is); //若是xml是基於節點的使用XmlDataSet ,若是是基於屬性的使用 FlatXmlDataSet return new FlatXmlDataSet(new FlatXmlProducer(new InputSource(is))); } /** * 備份數據庫全部的表 * @throws DataSetException * @throws IOException * @throws SQLException */ protected void backupAllTable() throws DataSetException, IOException, SQLException{ IDataSet ds = dbunitConn.createDataSet(); writeBackupFile(ds); } /** * 備份數據庫指定的表 * @param tNames 表名 * @throws DataSetException * @throws IOException * @throws SQLException */ protected void backupCustomTable(String[] tNames) throws DataSetException, IOException, SQLException{ QueryDataSet qds =new QueryDataSet(dbunitConn); for(String tName:tNames){ qds.addTable(tName); } writeBackupFile(qds); } /** * 備份一張指定的表 * @param tName 表名 * @throws DataSetException * @throws IOException * @throws SQLException */ protected void backupOneTable(String tName) throws DataSetException, IOException, SQLException{ backupCustomTable(new String[]{tName}); } private void writeBackupFile(IDataSet ds) throws DataSetException, IOException{ //將ds中的數據經過FlatXmlDataSet格式寫到文件中 tempFile = File.createTempFile("back", "xml"); FlatXmlDataSet.write(ds, new FileWriter(tempFile)); } /** * 還原數據庫 * @throws FileNotFoundException * @throws DatabaseUnitException * @throws SQLException */ protected void resumeTable() throws FileNotFoundException, DatabaseUnitException, SQLException{ InputStream is = new FileInputStream(tempFile); IDataSet ds = new FlatXmlDataSet(new FlatXmlProducer(new InputSource(is))); // 清空數據庫中的數據,插入xml中的數據 DatabaseOperation.CLEAN_INSERT.execute(dbunitConn, ds); } @AfterClass public static void destory(){ if(dbunitConn!=null){ try { dbunitConn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }