一、Junit
1.Junit簡介
JUnit是由 ErichGamma 和Kent Beck 編寫的一個迴歸測試框架(regressiontesting framework)。Junit測試是程序員測試,即所謂白盒測試,因爲程序員知道被測試的軟件如何(How)完成功能和完成什麼樣(What)的功能。Junit是一套框架,繼承TestCase類,就可以用Junit進行自動測試了。Junit環境搭建就不說了,網上一搜一大堆。
2.Demo
待測試類:
public class Math{
public int add(int a, int b){return a+b;}
public int sub(int a, int b){return a-b;}
}
測試類:
public class TestMath{
@Test
public void testAdd(){
assertEquals(9,new Math().add(6,3));
}
@Test
public void testSub(){
assertEquals(3,new Math().sub(6,3));
}
}
Run TestMath:
看~綠色的條條就對了~~~(本人用的Intelij IDEA 2016.2)
注:
*測試方法必須要用@Test註解
*測試方法必須使用public void 修飾,不能帶有任何的參數
*測試代碼區別被測試代碼存放(發佈時刪除測試代碼方便,不亂)
*測試方法必須可以進行獨立測試,不能有任何依賴
3.常用註解
->@beforeclass,afterclass:在所有方法被調用前,後執行的靜態方法,beforeclass適合加載配置文件,afterclass用於清理釋放資源(數據庫連接等)
->@before,@after:對類中每個方法前後各執行一次
->@Ingore:所註解的測試方法會被忽略
->@RunWith:用於更改測試運行器(自行更改測試運行器繼承org.junit.runner.Runner即可)
->@Test(timeout = 毫秒)
->@Test(expected = XX.class)
4.測試套件
如若測試的類很多很多,一一測試很是麻煩,那麼就可以使用測試套件組織測試類一起運行。
類1:
public class TestAdd{
@Test
public void testAdd(){
assertEquals(9,new Math().add(6,3));
}
}
類2:
public class TestSub{
@Test
public void testSub(){
assertEquals(3,new Math().sub(6,3));
}
}
}
測試套件類:
@RunWith(Suite.class)
@Suite.SuiteClasses({TestAdd.class,TestSub.class})
public class TestMath {
}
Run TestMath:
綠色的條條就對啦~~
注:
*@RunWith(suit.class)註解標記該類是測試套件入口類,入口類不包含任何方法
5.多組參數配置
一次只能測試一組數據多少有點不過癮啊,而且相信小夥伴也不會只測試一組數據就提交了吧 ~ 那麼,多組數據的參數配置就來啦~~
@RunWith(Parameterized.class)
public class TestMath {
int expect;
int num1;
int num2;
@Parameterized.Parameters
public static Collection<Object[]> t(){
return Arrays.asList(new Object[][]{
{3,1,2},
{4,2,2},
{0,0,0}
});
}
public TestMath(int expect, int num1, int num2){
this.expect = expect;
this.num1 = num1;
this.num2 = num2;
}
@Test
public void teatAdd(){
assertEquals(expect,new Math().add(num1,num2));
}
}
Run TestMath:
又是綠的,好煩。。。
注:
*更改默認的測試運行器爲@RunWith(Parameterized.class)
*聲明變量expect,num1,num2用於存放預期和結果值
*使用@Parameterized.Parameters註解返回值爲Collection的公共靜態方法
*測試類中添加帶參的公共構造函數,爲變量賦值
二、DbUnit
1.DbUnit簡介
DbUnit是一個基於Junit擴展的數據庫測試框架,它通過使用用戶自定義的數據集以及相關操作使數據庫處於一種可知的狀態,從而使得測試自動化、可重複和相對獨立
2.DbUnit工作流程
測試前:
*準備好測試用的準備數據和預想結果數據
*備份數據庫,並讀入準備數據
測試中:
*測試對象方法,比較實際執行結果跟預期結果
測試後:
*將數據庫還原到測試前狀態
3.Demo
Spring-dao.xml配置(加載驅動,執行DDL,DML):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd"
default-lazy-init="false" default-autowire="byName">
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:mem:bone;DB_CLOSE_DELAY=-1;MODE=MySQL" />
</bean>
<jdbc:initialize-database data-source="dataSource" ignore-failures="DROPS">
<jdbc:script location="classpath:ddl.sql" />
<jdbc:script location="classpath:dml.sql" />
</jdbc:initialize-database>
</beans>
DDL.sql:
CREATE TABLE `db_unit` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(100) NOT NULL,
`content` varchar(600) NOT NULL,
`createTime` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DML.sql:
insert into `db_unit` (`id`,`title`,`content`,`createTime`) values (1, 'title of first note', 'content of first note', NOW());
insert into `db_unit` (`id`,`title`,`content`,`createTime`) values (2, 'title of second note', 'content of second note', NOW());
insert into `db_unit` (`id`,`title`,`content`,`createTime`) values (3, 'title of third note', 'content of third note', NOW());
insert into `db_unit` (`id`,`title`,`content`,`createTime`) values (4, 'title of fourth note', 'content of forth note', NOW());
DbUnitMapper.java:
public interface DbunitMapper {
int insert(DbunitDomain note);
int delete(int noteId);
int update(DbunitDomain note);
DbunitDomain selectDbunitById(int id);
}
DbUintDaoTest.java:
/**
* DbunitMapper實現的測試類
*
* 這個類必須有@RunWith(SpringJUnit4ClassRunner.class)直接指定使用spring測試, @ContextConfiguration 註解指定要使用此單元測試類需要預先加載的spring配置文件
*
* Created by chenjie
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-dao.xml"})
public class DbunitDaoTest {
/**
* 使用@Autowired註解自動注入dbunitMapper測試類
*/
@Autowired
private DbunitMapper dbunitMapper;
/**
* 測試dbunitMapper的insert方法, 此處我們構造了一個dbunitDomain對象,然後將起insert到數據庫
*/
@Test
public void insertTest() {
DbunitDomain dbunitDomain = new DbunitDomain();
dbunitDomain.setTitle("test title");
dbunitDomain.setContent("test content");
dbunitDomain.setCreateTime(new Date());
dbunitMapper.insert(dbunitDomain);
//此處通過驗證note的id屬性是否爲正整數來驗證插入是否成功
Assert.assertTrue(dbunitDomain.getId() > 0);
}
/**
* 測試更新操作
*/
@Test
public void updateTest() {
DbunitDomain dbunitDomain = new DbunitDomain();
dbunitDomain.setId(1);
String newTitle = "new Title";
dbunitDomain.setTitle(newTitle);
String newContent = "new Content";
dbunitDomain.setContent(newContent);
int effectRows = dbunitMapper.update(dbunitDomain);
//此處通過update操作返回的受影響行數來斷定update操作是否執行成功
Assert.assertTrue (effectRows == 1);
}
/**
* 測試delete操作
*/
@Test
public void deleteTest() {
int wantDeleteId = 2;
int effectRows = dbunitMapper.delete(wantDeleteId);
//通過驗證受影響行數來斷定是否成功執行操作
Assert.assertEquals(1, effectRows);
}
/**
* 測試select操作
*/
@Test
public void selectTest() {
int selectId = 3;
DbunitDomain dbunitDomain = dbunitMapper.selectDbunitById(selectId);
//通過select出的dbunitDomain的id屬性來斷言是否成功
Assert.assertEquals(selectId, dbunitDomain.getId());
}
}
Run DbunitDaoTest:
還是綠的,很煩。。。
三、JMockit
1.JMockit簡介
JMockit是一個mock的輕量級框架,他允許你動態的改變已有的方法,這主要基於java 的Instrumentation框架,這樣便可以使得JMockit能夠適應幾乎所有的設計。
它允許你重定義private,static and final方法,甚至是no-arg constructors都能夠並輕易的重定義(其他的改天再說吧,太困了0.0)