欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
利用 ant 和 junit 進(jìn)行增量開(kāi)發(fā)
使用單元測試來(lái)逐步改進(jìn)代碼

Malcolm Davis
顧問(wèn)
2000 年 11 月

軟件開(kāi)發(fā)習慣中一個(gè)細微更改都可能會(huì )對軟件質(zhì)量產(chǎn)生巨大改進(jìn)。將單元測試合并到開(kāi)發(fā)過(guò)程中,然后從長(cháng)遠角度來(lái)看它可以節省多少時(shí)間和精力。本文通過(guò)使用代碼樣本說(shuō)明了單元測試的種種好處,特別是使用 Ant 和 JUnit 帶來(lái)的各種方便。

測試是大型開(kāi)發(fā)過(guò)程中的基本原則之一。在任何職業(yè)中,驗證都是一個(gè)重要部分。醫生要通過(guò)驗血來(lái)確診。波音公司在研制 777 的過(guò)程中對飛機的每個(gè)組件都進(jìn)行了精心測試。為什么軟件開(kāi)發(fā)就應該例外呢?

以前,由于在應用程序中將 GUI 和商業(yè)邏輯緊密聯(lián)系在一起,這就限制了創(chuàng )建自動(dòng)測試的能力。當我們學(xué)會(huì )通過(guò)抽象層將商業(yè)邏輯從界面中分離出來(lái)時(shí),各個(gè)單獨代碼模塊的自動(dòng)測試就替代了通過(guò) GUI 進(jìn)行的手工測試。

現在,集成開(kāi)發(fā)環(huán)境 (IDE) 能在您輸入代碼的同時(shí)顯示錯誤,對于在類(lèi)中快速查找方法具有智能探測功能,可以利用語(yǔ)法結構生成彩色代碼,而且具有許多其它功能。因此,在編譯更改過(guò)的代碼之前,您已經(jīng)全盤(pán)考慮了將構建的類(lèi),但您是否考慮過(guò)這樣的修改會(huì )破壞某些功能呢?

每個(gè)開(kāi)發(fā)者都碰到過(guò)更改“臭蟲(chóng)”。代碼修改過(guò)程可能會(huì )引入“臭蟲(chóng)”,而如果通過(guò)用戶(hù)界面手工測試代碼的話(huà),在編譯完成之前是不會(huì )發(fā)現它的。然后,您就要花費幾天的時(shí)間追蹤由更改所引起的錯誤。最近在我做的一個(gè)項目中,當我把后端數據庫由 Informix 更改到 Oracle 時(shí)就遇到了這種情況。大部分更改都十分順利,但由于數據庫層或使用數據庫層的系統缺少單元測試,從而導致將大量時(shí)間花費在嘗試解決更改“臭蟲(chóng)”上。我花了兩天的時(shí)間查到別人代碼中的一個(gè)數據庫語(yǔ)法更改。(當然,那個(gè)人仍是我的朋友。)

盡管測試有許多好處,但一般的程序員對測試都不太感興趣,開(kāi)始時(shí)我也沒(méi)有。您聽(tīng)到過(guò)多少次“它編譯了,所以它一定能用”這種言論?但“我思,故我在”這種原則并 適用于高質(zhì)量軟件。要鼓勵程序員測試他們的代碼,過(guò)程必須簡(jiǎn)單無(wú)痛。

本文從某人學(xué)習用 Java 語(yǔ)言編程時(shí)所寫(xiě)的一個(gè)簡(jiǎn)單的類(lèi)開(kāi)始。然后,我會(huì )告訴您我是如何為這個(gè)類(lèi)編寫(xiě)單元測試,以及在編寫(xiě)完它以后又是如何將單元測試添加到構建過(guò)程中的。最后,我們將看到將“臭蟲(chóng)”引入代碼時(shí)發(fā)生的情況。

從一個(gè)典型類(lèi)開(kāi)始
第一個(gè)典型的 Java 程序一般都包含一個(gè)打印 "Hello World" 的 main() 。在清單 1 中,我創(chuàng )建了一個(gè) HelloWorld 對象的實(shí)例并調用 sayHello() 方法,該方法會(huì )打印這句習慣說(shuō)法。

清單 1. 我的第一個(gè) Java 應用程序 "Hello world"
/* *  HelloWorld.java *  My first java program */class HelloWorld {    /**     * Print "Hello World"     */	void sayHello() {          System.out.println("Hello World");      }    /**     * Test     */    public static void main( String[] args ) {        HelloWorld world = new HelloWorld();        world.sayHello();    }}

main() 方法是我的測試。哦噢!我將代碼、文檔、測試和樣本代碼包含在了一個(gè)模塊中。保佑 Java!但隨著(zhù)程序越變越大,這種開(kāi)發(fā)方法很快就開(kāi)始顯現出了缺陷:

  • 混亂
    類(lèi)接口越大, main() 就越大。類(lèi)可能僅僅因為正常的測試而變得非常龐大。
  • 代碼膨脹
    由于加入了測試,所以產(chǎn)品代碼比所需要的要大。但我不想交付測試,而只想交付產(chǎn)品。
  • 測試不可靠
    既然 main() 是代碼的一部分, main() 就對其他開(kāi)發(fā)者通過(guò)類(lèi)接口無(wú)法訪(fǎng)問(wèn)的私有成員和方法享有訪(fǎng)問(wèn)權。出于這個(gè)原因,這種測試方法很容易出錯。
  • 很難自動(dòng)測試
    要進(jìn)行自動(dòng)測試,我仍然必須創(chuàng )建另一程序來(lái)將參數傳遞給 main() 。

類(lèi)開(kāi)發(fā)
對我來(lái)說(shuō),類(lèi)開(kāi)發(fā)是從編寫(xiě) main() 方法開(kāi)始的。我在編寫(xiě) main() 的時(shí)候就定義類(lèi)和類(lèi)的用法,然后實(shí)現接口。它的一些明顯的缺陷也開(kāi)始顯現出來(lái)。一個(gè)缺陷是我傳遞給 main() 來(lái)執行測試的參數個(gè)數。其次, main() 本身在進(jìn)行調用子方法、設置代碼等操作時(shí)變得很混亂。有時(shí) main() 會(huì )比類(lèi)實(shí)現的其余部分還要大。

更簡(jiǎn)單的過(guò)程
我原來(lái)的做法有一些很明顯的缺陷。因此,讓我們看看有什么別的方法可以使問(wèn)題簡(jiǎn)化。我仍然通過(guò)接口設計代碼并給出應用示例,正如原來(lái)的 main() 一樣。不同的是我將代碼放到了另一個(gè)單獨的類(lèi)中,而這個(gè)類(lèi)恰好是我的“單元測試”。這種技術(shù)有以下幾點(diǎn)好處:

  • 設計類(lèi)的一種機制
    因為是通過(guò)接口進(jìn)行開(kāi)發(fā),所以不太可能利用類(lèi)的內部功能。但因為我是目標類(lèi)的開(kāi)發(fā)者,我有到其內部工作的“窗口”,所以測試并不是個(gè)真正的黑箱。僅憑這一點(diǎn)就足夠推斷出需要開(kāi)發(fā)者本人在編寫(xiě)目標類(lèi)的同時(shí)負責測試的開(kāi)發(fā),而不是由其他任何人代勞。
  • 類(lèi)用法的示例
    通過(guò)將示例從實(shí)現中分離出來(lái),開(kāi)發(fā)者可以更快地提高速度,而且再不用在源代碼上糾纏不清。這種分離還有助于防止開(kāi)發(fā)者利用類(lèi)的內部功能,因為這些功能將來(lái)可能已經(jīng)不存在了。
  • 沒(méi)有類(lèi)混亂的 main()
    我不再受到 main() 的限制了。以前我得將多個(gè)參數傳遞給 main() 來(lái)測試不同的配置?,F在我可以創(chuàng )建許多單獨的測試類(lèi),每一個(gè)都維護各自的設置代碼。

接下來(lái)我們將這個(gè)單獨的單元測試對象放入構建過(guò)程中。這樣,我們就可以提供自動(dòng)確認過(guò)程的方法。

  • 確保所做的任何更改都不會(huì )對其他人產(chǎn)生不利影響。
  • 我們在進(jìn)行源碼控制之前就可以測試代碼,而無(wú)需等待匯編測試或在夜晚進(jìn)行的構建測試。這有助于盡早捕捉到“臭蟲(chóng)”,從而降低產(chǎn)生高質(zhì)量代碼的成本。
  • 通過(guò)提供增量測試過(guò)程,我們提供了更好的實(shí)現過(guò)程。如同 IDE 幫助我們在輸入時(shí)捕捉到語(yǔ)法或編譯“臭蟲(chóng)”一樣,增量單元測試也幫助我們在構建時(shí)捕捉到代碼更改“臭蟲(chóng)”。

使用 JUnit 自動(dòng)化單元測試
要使測試自動(dòng)化,您需要一個(gè)測試框架。您可以自己開(kāi)發(fā)或購買(mǎi),也可以使用某些開(kāi)放源代碼工具,例如 JUnit。我選擇 JUnit 出于以下幾個(gè)原因:

  • 不需要編寫(xiě)自己的框架。
  • 它是開(kāi)放源代碼,因此不需要購買(mǎi)框架。
  • 開(kāi)放源代碼社區中的其他開(kāi)發(fā)者會(huì )使用它,因此可以找到許多示例。
  • 它可以讓我將測試代碼與產(chǎn)品代碼分開(kāi)。
  • 它易于集成到我的構建過(guò)程中。

測試布局
圖 1 顯示了使用樣本 TestSuite 的 JUnit TestSuite 布局。每個(gè)測試都由若干單獨的測試案例構成。每個(gè)測試案例都是一個(gè)單獨的類(lèi),它擴展了 TestClass 類(lèi)并包含了我的測試代碼,即那些曾在 main() 中出現的代碼。在該例中,我向 TestSuite 添加了兩個(gè)測試:一個(gè)是 SkeletonTest,我將它用作所有新類(lèi)和 HelloWorld 類(lèi)的起點(diǎn)。

圖 1. TestSuite 布局

測試類(lèi) HelloWorldTest.java
按照約定,測試類(lèi)的名稱(chēng)中包含我所測試的類(lèi)的名稱(chēng),但將 Test 附加到結尾。在本例中,我們的測試類(lèi)是 HelloWorldTest.java 。我復制了 SkeletonTest 中的代碼,并添加了 testSayHello() 來(lái)測試 sayHello() 。請注意 HelloWorldTest 擴展了 TestCase。JUnit 框架提供了 assertassertEquals 方法,我們可以使用這些方法來(lái)進(jìn)行驗證。 HelloWorldTest.java 顯示在清單 2 中。

清單 2. HelloWorldTest.java
package test.com.company;import com.company.HelloWorld;import junit.framework.TestCase;import junit.framework.AssertionFailedError;/** * JUnit 3.2 testcases for HelloWorld */public class HelloWorldTest extends TestCase {    public HelloWorldTest(String name) {        super(name);    }    public static void main(String args[]) {        junit.textui.TestRunner.run(HelloWorldTest.class);    }    public void testSayHello() {        HelloWorld world = new HelloWorld();        assert( world!=null );        assertEquals("Hello World",  world.sayHello() );    }}

testSayHello() 看上去和 HelloWorld.java 中原來(lái)的 main 方法類(lèi)似,但有一個(gè)主要的不同之處。它不是執行 System.out.println 并顯示結果,而是添加了一個(gè) assertEquals() 方法。如果兩個(gè)值不同, assertEquals 將打印出兩個(gè)輸入的值。您可能已經(jīng)注意到這個(gè)方法不起作用!HelloWorld 中的 sayHello() 方法不返回字符串。如果我先寫(xiě)過(guò)測試,就會(huì )捕捉到這一點(diǎn)。我將 "Hello World" 字符串與輸出流聯(lián)結起來(lái)。這樣,按照清單 3 中顯示的那樣重寫(xiě)了 HelloWorld,去掉 main() ,并更改了 sayHello() 的返回類(lèi)型。

清單 3. Hello world 測試案例。
package com.company;public class HelloWorld {    public String sayHello() {        return "Hello World";    }}

如果我保留了 main() 并修改了聯(lián)系,代碼看上去如下:

   public static void main( String[] args ) {        HelloWorld world = new HelloWorld();        System.out.println(world.sayHello());    }

新的 main() 與我測試程序中的 testSayHello() 非常相似。是的,它看上去不象是一個(gè)現實(shí)世界中的問(wèn)題(這是人為示例的問(wèn)題),但它說(shuō)明了問(wèn)題。在單獨的應用程序中編寫(xiě) main() 可以改進(jìn)您的設計,同時(shí)幫助您設計測試?,F在我們已經(jīng)創(chuàng )建了一個(gè)測試類(lèi),讓我們使用 Ant 來(lái)將它集成到構建中。

使用 Ant 將測試集成到構建中
Jakarta Project 將 Ant 工具說(shuō)成“不帶 make 缺點(diǎn)的 make”。Ant 正在成為開(kāi)放源代碼世界中實(shí)際上的標準。原因很簡(jiǎn)單:Ant 是使用 Java 語(yǔ)言編寫(xiě)的,這種語(yǔ)言可以讓構建過(guò)程在多種平臺上使用。這種特性簡(jiǎn)化了在不同 OS 平臺之間的程序員的合作,而合作是開(kāi)放源代碼社區的一種需要。您可以在自己選擇的平臺上進(jìn)行開(kāi)發(fā) 構建。Ant 的特性包括:

  • 類(lèi)可擴展性 Java 類(lèi)可用于擴展構建特性,而不必使用基于 shell 的命令。
  • 開(kāi)放源代碼 因為 Ant 是開(kāi)放源代碼,因此類(lèi)擴展示例很充足。我發(fā)現通過(guò)示例來(lái)學(xué)習非常棒。
  • XML 可配置 Ant 不僅是基于 Java 的,它還使用 XML 文件配置構建過(guò)程。假設構建實(shí)際上是分層的,那么使用 XML 描述 make 過(guò)程就是其邏輯層。另外,如果您了解 XML,要學(xué)習如何配置構建就更簡(jiǎn)單一些。

圖 2 簡(jiǎn)要介紹了一個(gè)配置文件。配置文件由目標樹(shù)構成。每個(gè)目標都包含了要執行的任務(wù),其中任務(wù)就是可以執行的代碼。在本例中, mkdir是目標 compile的任務(wù)。 mkdir是建立在 Ant 中的一個(gè)任務(wù),用于創(chuàng )建目錄。 Ant 帶有一套健全的內置任務(wù)。您也可以通過(guò)擴展 Ant 任務(wù)類(lèi)來(lái)添加自己的功能。

每個(gè)目標都有唯一的名稱(chēng)和可選的相關(guān)性。目標相關(guān)性需要在執行目標任務(wù)列表之前執行。例如圖 2 所示,在執行 compile 目標中的任務(wù)之前需要先運行 JUNIT 目標。這種類(lèi)型的配置可以讓您在一個(gè)配置中有多個(gè)樹(shù)。

圖 2. Ant XML 構建圖

與經(jīng)典 make 實(shí)用程序的相似性是非常顯著(zhù)的。這是理所當然的,因為 make 就是 make。但也要記住有一些差異:通過(guò) Java 實(shí)現的跨平臺和可擴展性,通過(guò) XML 實(shí)現的可配置,還有開(kāi)放源代碼。

下載和安裝 Ant
首先下載 Ant(請參閱 參考資料 )。將 Ant 解壓縮到 tools 目錄,再將 Ant bin 目錄添加到路徑中。(在我的機器上是 e:\tools\ant\bin 。)設置 ANT_HOME 環(huán)境變量。在 NT 中,這意味著(zhù)進(jìn)入系統屬性,然后以帶有值的變量形式添加 ANT_HOME。ANT_HOME 應該設置為 Ant 根目錄,即包含 binlib 目錄的目錄。(對我來(lái)說(shuō),是 e:\tools\ant 。)確保 JAVA_HOME 環(huán)境變量設置為安裝了 JDK 的目錄。Ant 文檔有關(guān)于安裝的詳細信息。

下載和安裝 JUnit
下載 JUnit 3.2(請參閱 參考資料 )。解開(kāi) junit.zip ,并將 junit.jar 添加到 CLASSPATH。如果將 junit.zip 解包到類(lèi)路徑中,可以通過(guò)運行以下命令來(lái)測試安裝: java junit.textui.TestRunner junit.samples.AllTests

定義目錄結構
在開(kāi)始我們的構建和測試過(guò)程之前,需要一個(gè)項目布局。圖 3 顯示了我的樣本項目的布局。下面描述了布局的目錄結構:

  • build -- 類(lèi)文件的臨時(shí)構建位置。構建過(guò)程將創(chuàng )建這個(gè)目錄。
  • src -- 源代碼的位置。 Src 被分為 test 文件夾和 main 文件夾,前者用于所有的測試代碼,而后者包含可交付的代碼。將測試代碼與主要代碼分離提供了幾點(diǎn)特性。首先,使主要代碼中的混亂減少。其次,它允許包對齊。我就熱衷與將類(lèi)和與其相關(guān)的包放置在一起。測試就應該和測試在一起。它還有助于分發(fā)過(guò)程,因為你不可能打算將單元測試分發(fā)給客戶(hù)。

在實(shí)際中,我們有多個(gè)目錄,例如 distributiondocumentation 。我們還會(huì )在 main 下有多個(gè)用于包的目錄,例如 com.company.util 。

因為目錄結構經(jīng)常變動(dòng),所以在 build.xml 中有這些變動(dòng)的全局字符串常數是很重要的。

圖 3. 項目布局圖

Ant 構建配置文件示例
下一步,我們要創(chuàng )建配置文件。清單 4 顯示了一個(gè) Ant 構建文件示例。構建文件中的關(guān)鍵就是名為 runtests 的目標。這個(gè)目標進(jìn)行分支判斷并運行外部程序,其中外部程序是前面已安裝的 junit.textui.TestRunner 。我們指定要使用語(yǔ)句 test.com.company.AllJUnitTests 來(lái)運行哪個(gè)測試套件。

清單 4. 構建文件示例
    <property name="app.name"   value="sample" />    <property name="build.dir"  value="build/classes" />    <target name="JUNIT">        <available property="junit.present" classname="junit.framework.TestCase" />    </target>    <target name="compile" depends="JUNIT">        <mkdir dir="${build.dir}"/>        <javac srcdir="src/main/" destdir="${build.dir}" >            <include name="**/*.java"/>        </javac>    </target>    <target name="jar" depends="compile">        <mkdir dir="build/lib"/>        <jar jarfile="build/lib/${app.name}.jar"             basedir="${build.dir}" includes="com/**"/>    </target>    <target name="compiletests" depends="jar">        <mkdir dir="build/testcases"/>        <javac srcdir="src/test" destdir="build/testcases">            <classpath>                <pathelement location="build/lib/${app.name}.jar" />                <pathelement path="" />            </classpath>            <include name="**/*.java"/>        </javac>    </target>    <target name="runtests" depends="compiletests" if="junit.present">        <java fork="yes" classname="junit.textui.TestRunner"            taskname="junit" failonerror="true">            <arg value="test.com.company.AllJUnitTests"/>            <classpath>                <pathelement location="build/lib/${app.name}.jar" />                <pathelement location="build/testcases" />                <pathelement path="" />                <pathelement path="${java.class.path}" />            </classpath>        </java>    </target></project>

運行 Ant 構建示例
開(kāi)發(fā)過(guò)程中的下一步是運行將創(chuàng )建和測試 HelloWorld 類(lèi)的構建。清單 5 顯示了構建的結果,其中包括了各個(gè)目標部分。最酷的那部分是 runtests 輸出語(yǔ)句:它告訴我們整個(gè)測試套件都正確運行了。

我在圖 4 和圖 5 中顯示了 JUnit GUI,其中所要做的就是將 runtest 目標從 junit.textui.TestRunner 改為 junit.ui.TestRunner 。當您使用 JUnit 的 GUI 部分時(shí),您必須選擇退出按鈕來(lái)繼續構建過(guò)程。如果使用 Junit GUI 構建包,那么它將更難與大型的構建過(guò)程相集成。另外,文本輸出也與構建過(guò)程更一致,并可以定向輸出到一個(gè)用于主構建記錄的文本文件。這對于每天晚上都要進(jìn)行的構建非常合適。

清單 5. 構建輸出示例
E:\projects\sample>ant runtestsSearching for build.xml ...Buildfile: E:\projects\sample\build.xmlJUNIT:compile:    [mkdir] Created dir: E:\projects\sample\build\classes    [javac] Compiling 1 source file to E:\projects\sample\build\classesjar:    [mkdir] Created dir: E:\projects\sample\build\lib      [jar] Building jar: E:\projects\sample\build\lib\sample.jarcompiletests:    [mkdir] Created dir: E:\projects\sample\build\testcases    [javac] Compiling 3 source files to E:\projects\sample\build\testcasesruntests:    [junit] ..    [junit] Time: 0.031    [junit]    [junit] OK (2 tests)    [junit]BUILD SUCCESSFULTotal time: 1 second 

圖 4. JUnit GUI 測試成功

圖 5. JUnit GUI 測試失敗

了解測試的工作原理
讓我們搞點(diǎn)破壞,然后看看會(huì )發(fā)生什么事。夜深了,我們決定把 "Hello World" 變成一個(gè)靜態(tài)字符串。在更改期間,我們 不小心打錯了字母,將 "o" 變成了 "0",如清單 6 所示。

清單 6. Hello world 類(lèi)更改
package com.company;public class HelloWorld {    private final static String HELLO_WORLD = "Hell0 World";    public String sayHello() {        return HELLO_WORLD;    }}

在構建包時(shí),我們看到了錯誤。清單 7 顯示了 runtest 中的錯誤。它顯示了失敗的測試類(lèi)和測試方法,并說(shuō)明了為什么會(huì )失敗。我們返回到代碼中,改正錯誤后離開(kāi)。

清單 7. 構建錯誤示例
E:\projects\sample>ant runtestsSearching for build.xml ...Buildfile: E:\projects\sample\build.xmlJUNIT:compile:jar:compiletests:runtests:    [junit] ..F    [junit] Time: 0    [junit]    [junit] FAILURES!!!    [junit] Test Results:    [junit] Run: 2 Failures: 1 Errors: 0    [junit] There was 1 failure:    [junit] 1) testSayHello(test.com.company.HelloWorldTest) "expected:<Hello               World> but was:<Hell0 World>"    [junit]BUILD FAILEDE:\projects\sample\build.xml:35: Java returned: -1Total time: 0 seconds

并非完全無(wú)痛
新的過(guò)程并不是完全無(wú)痛的。為使單元測試成為開(kāi)發(fā)的一部分,您必須采取以下幾個(gè)步驟:

  1. 下載和安裝 JUnit。
  2. 下載和安裝 Ant。
  3. 為構建創(chuàng )建單獨的結構。
  4. 實(shí)現與主類(lèi)分開(kāi)的測試類(lèi)。
  5. 學(xué)習 Ant 構建過(guò)程。

但好處遠遠超過(guò)了痛苦。通過(guò)使單元測試成為開(kāi)發(fā)過(guò)程的一部分,您可以:

  • 自動(dòng)驗證以捕捉更改“臭蟲(chóng)”
  • 從接口角度設計類(lèi)
  • 提供干凈的示例
  • 在發(fā)行包中避免代碼混亂和類(lèi)膨脹。

實(shí)現 24x7
保證產(chǎn)品的質(zhì)量要花費很多錢(qián),但如果質(zhì)量有缺陷,花費的錢(qián)就更多。如何才能使所花的錢(qián)獲得最大價(jià)值,來(lái)保證產(chǎn)品質(zhì)量呢?

  • 評審設計和代碼。 評審可以達到的效果是單純測試的一半。
  • 通過(guò)單元測試來(lái)確認模塊可以使用。 盡管測試早就存在,但隨著(zhù)開(kāi)發(fā)實(shí)踐的不斷發(fā)展,單元測試逐漸成為日常開(kāi)發(fā)過(guò)程的一個(gè)部分。

在我 10 年的開(kāi)發(fā)生涯里,為 emageon.com 工作是最重要的部分之一。在 emageon.com 時(shí),設計評審、代碼評審和單元測試是每天都要做的事。這種日常開(kāi)發(fā)習慣造就了最高質(zhì)量的產(chǎn)品。軟件在客戶(hù)地點(diǎn)第一年的當機次數為零,是一個(gè)真正的 24x7 產(chǎn)品。單元測試就象刷牙:您不一定要做,但如果做了,生活質(zhì)量就更好。

參考資料

關(guān)于作者
Malcolm G. Davis 擁有自己的咨詢(xún)公司,并任公司的總裁,該公司位于美國阿拉巴馬州的伯明翰 (Birmingham)。他把自己看做是個(gè) Java 傳道者。在工作之余,他喜歡跑步,以及和他的孩子們一起玩耍。您可以通過(guò) malcolm@nuearth.com 與 Malcolm 聯(lián)系。
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
單元測試及覆蓋率
5分鐘了解Mockito
CSDN技術(shù)中心 在Eclipse中使用JUnit(翻譯)
每個(gè)Java程序員必備的8個(gè)開(kāi)發(fā)工具
菜鳥(niǎo)學(xué)Java(二十一)——如何更好的進(jìn)行單元測試——JUnit
Ant學(xué)習---第五節:Ant_Junit介紹(基于3的版本)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久