JavaME下的單元測試開發(fā)之JMUnit篇

字號:

摘要 不能因為Java Micro Edition缺乏反射能力就說Java Micro Edition開發(fā)者無法利用JUnit風格測試的優(yōu)點。其實,借助于具有JUnit風格的其它一些框架和工具,Java ME開發(fā)人員仍然能夠改進Java ME應用程序的開發(fā)質(zhì)量。本系列文章(兩篇)正是想詳細探討J2MEUnit和JMUnit這兩個開源框架在Java ME單元測試開發(fā)中的應用。
    一、 引言
    如今,JUnit測試正在逐漸成為大多數(shù)Java標準版(SE)和企業(yè)版(EE)應用程序開發(fā)中的基本組成部分-對于那些積極擁護測試驅(qū)動開發(fā)者尤其如此。Kent Beck和Eric Gamma的最初的Smalltalk框架變得如此流行和成功,以至于它被移植到很多編程語言中,包括Ada(AUnit)、C#(NUnit)、Python(PyUnit),甚至還有Fortran(fUnit)。實踐證明,Java的JUnit是所有的單元測試框架中最成功的并且已經(jīng)派生出許多JUnit"變種"(以各種"擴展"的形式),這些框架最終幫助在從多線程Java應用程序到高級企業(yè)Java應用程序的主流開發(fā)中實現(xiàn)單元測試。
    然而,使用JUnit或找到一種JUnit擴展用于Java Micro Edition開發(fā)一直以來卻是很難的事情。須知,JUnit框架依賴于Java反射API。由于Java ME環(huán)境中還不支持反射API,所以,典型的很大程度上依賴于反射的JUnit工具還不能幫助進行Java ME開發(fā)。盡管如此,已經(jīng)出現(xiàn)兩個專門針對設備應用程序開發(fā)者構建的Java ME JUnit擴展。值得注意的是,隨著NetBeans和NetBeans Mobility 5.5的發(fā)行,NetBeans和NetBeans Mobility Pack正在計劃合并一個Java ME JUnit風格的框架。這種新版本的IDE將以一種更為利索的方式在你的Java ME應用程序中加入單元測試。
    本文將通過使用Java ME JUnit框架向你介紹JUnit測試;通過本文,你會發(fā)現(xiàn),如何獲取這些工具,如何使用它們進行測試以及如何使用它們來構建質(zhì)量更好的軟件。
    二、 獲取Java ME單元測試框架
    如今,市場上存在兩個可用的JavaME JUnit測試框架,它們是J2MEUnit和JMUnit。這兩個工程都是可自由下載的開源框架,你可以從SourceForge.net上下載一個打包文件。
    然而,這兩個開源工程的工程主管(Elmar Sonnenschein和Brunno Silva,分別維護J2MEUnit和JMUnit),正在計劃把這兩個框架合并為一個。新的工程將在J2MEUnit工程基礎上得到進一步鞏固。根據(jù)Sonnenschein本人的說法,"因為更多的現(xiàn)有用戶的工程都是基于SourceForge上的J2MEUnit框架;所以,我們計劃基于Brunno的JMUnit 2.0創(chuàng)建一個J2MEUnit 2.0發(fā)行版本。"Silva在一次最近的新聞發(fā)布會上聲稱在今年年底可能無法完成產(chǎn)品的合并和一個2.0版本的發(fā)行。Silva進一步建議說,新的工程"不想破壞這兩個框架的當前用戶的原有代碼,因此,原始代碼會繼續(xù)存在,只是不再建議使用。新的單元框架應該展現(xiàn)出兩個框架-JMUnit和J2MEUnit-各自的特色。"
    三、 一個簡單的示例應用程序
    在分析各種單元測試框架之前,你需要一些簡單的代碼以備測試之用。在這個例子中,下面這個簡單的Conversion類能夠用于創(chuàng)建并測試Java ME單元測試。
    public class DistanceConversion {
    public static int feetToMeters(int ft){
    return (ft * 3048)/10000;
    }
    public static int metersToFeet(int meters){
    return (meters*3281)/1000;
    }
    public static int milesToKM(int miles){
    return (miles*1609)/1000;
    }
    public static int kmToMiles(int km){
    return (km*6214)/10000;
    }
    }
    public class TemperatureConversion {
    public static float fahrenheitToCelsius (float degrees){
    return ((degrees-32)/9)*5;
    }
    public static float celsiusToFahrenheit (float degrees){
    return ((degrees * 9)/5)+32;
    }
    public static boolean isHotter (float degFaren, float degCel){
    return ((fahrenheitToCelsius(degFaren))-degCel) > 0;
    }
    public static boolean isCooler (float degFaren, float degCel){
    return ((fahrenheitToCelsius(degFaren))-degCel) < 0;
    }
    }