您的位置:軟件測(cè)試 > 開源軟件測(cè)試 > 開源單元測(cè)試工具 > junit
JUnit多個(gè)testCase只執(zhí)行一次setup和tearDown
作者:網(wǎng)絡(luò)轉(zhuǎn)載 發(fā)布時(shí)間:[ 2014/2/27 10:20:03 ] 推薦標(biāo)簽:JUnit testCase

每個(gè)testCase都需要使用某一種初始化比較耗時(shí)的對(duì)象(資源),舉例如數(shù)據(jù)庫(kù)連接、Spring Context。我們遇到的問題是Selenium測(cè)試中開啟和關(guān)閉瀏覽器,如果一個(gè)test啟動(dòng)關(guān)閉(我們的程序還需要登錄和注銷),這樣測(cè)試的時(shí)間會(huì)拖的很長(zhǎng),給持續(xù)集成帶來(lái)了困難。
所以,我們需要在每組不會(huì)沖突的test中間共享一個(gè)瀏覽器窗口,這樣也需要一個(gè)全局的setUp和tearDown。問題是JUnit 3.8.1里面的setUp和tearDown是在每個(gè)test之前和之后運(yùn)行的,如果在里面初始化和關(guān)閉瀏覽器會(huì)造成上面所說(shuō)的問題。要解決它,產(chǎn)生了如下3種思路:
1、升級(jí),使用JUnit4
JUnit4從TestNG里面吸取了兩個(gè)注釋:@BeforeClass和@AfterClass
用它們注釋過的方法會(huì)只初始化一次,完全符合我們的需求。


public class SeleniumTestCase extends SeleneseTestCase4 {
    protected static final Log log = LogFactory.getLog(SeleniumTestCase.class);
    protected static Selenium selenium = null;
    /** *//**
     * 包含了登錄的代碼,保證在一個(gè)測(cè)試內(nèi)部只執(zhí)行一次開啟瀏覽器并登錄操作
     * @throws Exception
     */
    @BeforeClass
    public static void startSelenium() throws Exception {
        log.debug("Starting Selenium");
        selenium = SeleniumSession.getCurrentSession().getSelenium();
    }
    /** *//**
     * 在該類包含的所有測(cè)試結(jié)束之后關(guān)閉瀏覽器
     * @throws Exception
     */
    @AfterClass
    public static void stopSelenium() throws Exception {
        log.debug("Stoping Selenium");
        selenium.stop();
    }
}
 
這個(gè)里面的selenium = SeleniumSession.getCurrentSession().getSelenium();其實(shí)是個(gè)singleton,第一次open new,后來(lái)直接返回selenium的instance(具體參考其它文章)。
這樣做非常舒服,因?yàn)橥耆皇荰rick,而是新的feature,用起來(lái)踏實(shí)。這樣,這個(gè)類的所有@Test會(huì)公用一個(gè)selenium打開的瀏覽器了。
那么缺點(diǎn)是什么呢?缺點(diǎn)是放到CI環(huán)境的時(shí)候如果使用我們習(xí)慣的Ant寫執(zhí)行腳本的話必須將Ant升級(jí)到1.7Beta3,因?yàn)锳nt 1.6.5的Junit task不支持JUnit4……當(dāng)然升級(jí)并不會(huì)帶來(lái)代碼的變化,但是問題在于Ant 1.7還是Beta,而且JUnit4需要JDK5的Annotation,你的PM估計(jì)要撇嘴了

2、JVM級(jí)別鉤子法
因?yàn)镴VM支持關(guān)閉時(shí)執(zhí)行制定代碼的鉤子,而static代碼會(huì)在類初始化時(shí)執(zhí)行,再加上Ant調(diào)用的是類似命令行的java命令,實(shí)際上每一個(gè)測(cè)試運(yùn)行在一個(gè)完整的JVM啟動(dòng)關(guān)閉周期里面,所以也產(chǎn)生了這種解決方案。
public abstract class SomeTestCase extends TestCase {
  static {
    // perform. the "global" set up logic
    //這里的代碼會(huì)在類初始化時(shí)執(zhí)行,所以相當(dāng)于BeforeClass
    log.debug("Starting Selenium");
        selenium = SeleniumSession.getCurrentSession().getSelenium();
    // and now register the shutdown hook for tear down logic
    //將一個(gè)匿名方法寫到這里,相當(dāng)于AfterClass
    Runtime.getRuntime().addShutdownHook(
       new Thread(){
           public void run() {
             log.debug("Stoping Selenium");
             selenium.stop();
           }
       }
     );
  }
}
 
3、還有別的方法,這個(gè)來(lái)自Selenium網(wǎng)站,似乎是不錯(cuò)的中庸方案。
JAVA代碼:
import junit.framework.*;
import junit.extensions.TestSetup;
public class AllTestsOneTimeSetup {
    public static Test suite() {
        TestSuite suite = new TestSuite();
        suite.addTest(SomeTest.suite());
        suite.addTest(AnotherTest.suite());
        TestSetup wrapper = new TestSetup(suite) {
            protected void setUp() {
                oneTimeSetUp();
            }
            protected void tearDown() {
                oneTimeTearDown();
            }
        };
        return wrapper;
    }
    public static void oneTimeSetUp() {
        // one-time initialization code
    }
    public static void oneTimeTearDown() {
        // one-time cleanup code
    }
}

這個(gè)好像是比較正統(tǒng)的方案,不好意思我并沒有試驗(yàn),但是看起來(lái)這的確可能是限定用JDK 1.4或JUnit 3.8.1的佳解決方案。歡迎嘗試。相關(guān)的連接參考這里:http://www.cs.wm.edu/~noonan/junit/doc/faq/faq.htm#organize_3

軟件測(cè)試工具 | 聯(lián)系我們 | 投訴建議 | 誠(chéng)聘英才 | 申請(qǐng)使用列表 | 網(wǎng)站地圖
滬ICP備07036474 2003-2017 版權(quán)所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd