當(dāng) JUnit 不必區(qū)分其運(yùn)行的是一個(gè)或多個(gè)測試用例時(shí),能夠輕松地解決這個(gè)問題的模式就
是 Composite(組合)模式。摘引其意圖,"將對(duì)象組合成樹形結(jié)構(gòu)以表示'部分-整體'的層次
結(jié)構(gòu)。Composite 使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。"在這里'部分-整體'
的層次結(jié)構(gòu)是解決問題的關(guān)鍵,可以把單個(gè)的 TestCase 看作部分,而把復(fù)合的 TestCase 看
作整體(稱為 TestSuit) 。這樣使用該模式便可以恰到好處得解決了這個(gè)難題。
Composite 模式引入以下的參與者:
? Component:這是一個(gè)抽象角色,它給參加組合的對(duì)象規(guī)定一個(gè)接口。這個(gè)角色,
給出共有的接口和默認(rèn)行為。其實(shí)就我們的 Test 接口,它定義出 run 方法。
? Composite:實(shí)現(xiàn)共有接口并維護(hù)一個(gè)測試用例的集合。就是復(fù)合測試用例 TestSuit
? Leaf:代表參加組合的對(duì)象,它沒有下級(jí)子對(duì)象,僅定義出參加組合的原始對(duì)象的
行為,其實(shí)就是單一的測試用例 TestCase,它僅實(shí)現(xiàn) Test 接口的方法。
其實(shí) componsite 模式根據(jù)所實(shí)現(xiàn)的接口類型區(qū)分為兩種形式,分別稱為安全式和透明式。
JUnit 中使用了安全式的結(jié)構(gòu),這樣在 TestCase 中沒有管理子對(duì)象的方法。
composite 模式告訴我們要引入一個(gè) Component 抽象類,為 Leaf 對(duì)象和 composite 對(duì)象
定義公共的接口。這個(gè)類的基本意圖就是定義一個(gè)接口。在 Java 中使用 Composite模式時(shí),
優(yōu)先考慮使用接口,而非抽象類,因此引入一個(gè) Test 接口。當(dāng)然我們的 leaf 就是 TestCase
了。其源代碼如下:
//composite模式中的Component角色
public interface Test {
public abstract void run(TestResult result);
}
//composite模式中的Leaf角色
public abstract class TestCase extends Assert implements Test {
public void run(TestResult result) {
result.run(this);
}
}
下面,列出 Composite 源碼。將其取名為 TestSuit 類。TestSuit 有一個(gè)屬性 fTests (Vector
類型)中保存了其子測試用例,提供 addTest 方法來實(shí)現(xiàn)增加子對(duì)象 TestCase ,并且還提供
estCount 和 tests 等方法來操作子對(duì)象。最后通過 run()方法實(shí)現(xiàn)對(duì)其子對(duì)象進(jìn)行委托
(delegate) ,最后還提供 addTestSuite 方法實(shí)現(xiàn)遞歸,構(gòu)造成樹形。
public class TestSuite implements Test {
private Vector fTests= new Vector(10);
public void addTest(Test test) {
fTests.addElement(test);
}
public Enumeration tests() {
return fTests.elements();
}
public void run(TestResult result) {
for (Enumeration e= tests(); e.hasMoreElements(); ) {
Test test= (Test)e.nextElement();
runTest(test, result);
}
}
public void addTestSuite(Class testClass) {
addTest(new TestSuite(testClass));
}
}
注意所有上面的代碼是對(duì) Test 接口進(jìn)行實(shí)現(xiàn)的。 由于 TestCase 和 TestSuit兩者都符合 Test
接口,我們可以通過 addTestSuite 遞歸地將 TestSuite 再組合成 TestSuite,這樣將構(gòu)成樹形結(jié)
構(gòu)。所有開發(fā)者都能夠創(chuàng)建他們自己的 TestSuit。測試人員可創(chuàng)建一個(gè)組合了這些測試用例
的 TestSuit 來運(yùn)行它們所有的 TestCase。
public static Test suite() {
TestSuite suite1 = new TestSuite("我的測試TestSuit1");
TestSuite suite2 = new TestSuite("我的測試TestSuit2");
suite1.addTestSuite(untitled6.Testmath.class);
suite2.addTestSuite(untitled6.Testmulti.class);
suite1.addTest(suite2);
return suite1;
}