• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • NUnit快速入門

    發表于:2007-05-05來源:作者:點擊數: 標簽:原著v2.1nunit快速入門
    原著:NUnit v2.1 原文:NUnit文檔之QuickStart.doc 翻譯:lover_P -------------------------------------------------------------------------------- [譯者序] 縱觀軟件的 開發 , java script:;" onClick="javascript:tagshow(event, '%B2%E2%CA%D4');"
    原著:NUnit v2.1
    原文:NUnit文檔之QuickStart.doc
    翻譯:lover_P
    --------------------------------------------------------------------------------
    [譯者序]
        縱觀軟件的開發,javascript:;" onClick="javascript:tagshow(event, '%B2%E2%CA%D4');" target="_self">測試已經日益成為軟件開發過程中的重要環節,通常一個軟件的開發周期中測試要占到一半時間甚至更多。而在測試過程中,單元測試更是萬里長征第一步,單元測試進行得是否完善,直接影響到后期集成測試的效率。進行單元測試,有許多軟件可以自動完成,NUnit就是其中之一。這是一款與JUnit齊名的,同屬于xUnit家族的單元測試軟件(在http://www.NUnit.org我們可以免費得到這款軟件)。

    [正文]

        讓我們從一個簡單的例子開始。假設我們正在編寫一個銀行應用程序,而我們有一個這一領域的基本類——Aclearcase/" target="_blank" >ccount。Account支持存款、取款和資金轉帳。這個Account類看起來會是這個樣子:

    namespace bank {
        public class Account {
            private float balance;

            public void Deposit(float amount) {
                balance += amount;
            }

            public void Withdraw(float amount) {
                balance -= amount;
            }

            public void TransferFunds(Account destination, float amount) {
            }

            public float Balance {
                get {
                    return balance;
                }
            }
        }
    }

        現在我們來為這個類寫一個測試——AccountTest。我們要測試的第一個類方法是TransferFunds。

    namespace bank {
        using NUnit.Framework;

        [TestFixture]
        public class AccountTest {

            [Test]
            public void TransferFunds() {
                Account source = new Account();
                source.Deposit(200.00F);
                Account destination = new Account();
                destination.Deposit(150.00F);

                source.TransferFunds(destination, 100.00F);
                Assert.AreEqual(250.00F, destination.Balance);
                Assert.AreEqual(100.00F, source.Balance);
            }
        }
    }

        首先要注意的是這個類關聯了一個[TestFixture]特性(attribute)——這表示這個類包含了測試代碼(這個特性可以被繼承)。這個類必須是公有的,但他的父類并不受限制。這個類還必須有一個默認構造函數。

        類中唯一的一個方法——TransferFunds(),關聯了一個[Test]特性——這表示它是一個測試方法。測試方法的返回值必須為void并且不能帶有參數。在我們的測試方法中,我們對被測試的對象進行了一般的初始化,執行了被測試的方法并檢查了對象的狀態。Assert類定義了一組方法用于檢查給定的條件,在我們的例子中我們使用了AreEqual()方法來確保交易過后兩個賬戶都有正確的余額(這個方法有很多重載,我們在這個例子中使用的版本帶有兩個參數:第一個參數是我們的期望值,第二個參數是實際值)。

        編譯并運行這個例子。假設你已經將你的測試代碼編譯為bank.dll。打開NUint Gui(安裝程序會在你的桌面和“程序”菜單中建立一個快捷方式),打開GUI后,選擇File->Open菜單項,找到你的bank.dll并在“Open”對話框中選中它。bank.dll裝載后你會在左邊的面板中看到一個測試樹結構,還有右邊的一組狀態面板。單擊Run按鈕,狀態條和測試樹種的TransferFunds節點變成了紅色——我們的測試失敗了?!癊rrors and Failures”面板顯示如下消息——“TransferFunds: expected <250> but was <150>”,在它正下方的堆棧跟蹤面板報告了測試失敗的語句在代碼中的位置——“at bank.AccountTest.TransferFunds() in C:\nunit\BankSampleTests\AccountTest.cs:line 17”

        這正是預期的結果,因為我們還未實現TransferFunds()方法?,F在我們來搞定它。不要關閉GUI,回到你的IDE并修改代碼,使你的TransferFunds()方法看起來像這樣:

    public void TransferFunds(Account destination, float amount) {
        destination.Deposit(amount);
        Withdraw(amount);
    }

        現在重新編譯你的代碼并再次在GUI中點擊Run按鈕——狀態條和數節點變綠了。(注意GUI會自動地為你重新加載程序集;我們可以一直開著GUI而在IDE中繼續工作并寫更多的測試)。

        讓我們來為我們的Account的代碼添加一些錯誤檢測。為賬戶添加一個最小余額限制,通過你的最小透支保護費來維持它的持續運作。首先我們來為Account類添加一個最小余額保護屬性:

    private float minimumBalance = 10.00F;

    public float MinimumBalance {
        get {
            return minimumBalance;
        }
    }

        我們使用一個異常來指出透支:

    namespace bank {
        using System;

        public class InsufficientFundsException : ApplicationException {
        }
    }

        向我們的AccountTest類添加一個新的方法:

    [Test]
    [ExpectedException(typeof(InsufficientFundsException))]
    public void TransferWithInsufficientFunds() {
        Account source = new Account();
        source.Deposit(200.00F);
        Account destination = new Account();
        destination.Deposit(150.00F);
        source.TransferFunds(destination, 300.00F);
    }

        這個測試方法除了[Test]特性之外還關聯了一個[ExpectedException]特性——這指出測試代碼希望拋出一個指定類型的異常;如果在執行過程中沒有拋出這樣的一個異?!摐y試將會失敗。編譯你的代碼并回到GUI。由于你編譯了你的測試代碼,GUI會變灰并重構了測試樹,好像這個測試還沒有被運行過(GUI可以監視測試程序集的變化,并在測試樹結構發生變化時進行更新——例如,添加了新的測試)。點擊“Run”按鈕——我們又一次得到了一個紅色的狀態條。我們得到了下面的失敗消息:“TransferWithInsufficentFunds: InsufficientFundsException was expected”。我們來再次修改Account的代碼,象下面這樣修改TransferFunds()方法:

    public void TransferFunds(Account destination, float amount) {
        destination.Deposit(amount);

        if(balance - amount < minimumBalance)
            throw new InsufficientFundsException();

        Withdraw(amount);
    }

        編譯并運行測試——綠了。成功!不過等等,看看我們剛寫的代碼,我們會發現銀行在每一筆不成功的轉賬操作時都虧錢了。讓我們來寫一個測試來確認我們的猜測。添加這個測試方法:

    [Test]
    public void TransferWithInsufficientFundsAtomicity() {
        Account source = new Account();
        source.Deposit(200.00F);
        Account destination = new Account();
        destination.Deposit(150.00F);

        try {
            source.TransferFunds(destination, 300.00F);
        }
        catch(InsufficientFundsException expected) {
        }

        Assert.AreEqual(200.00F,source.Balance);
        Assert.AreEqual(150.00F,destination.Balance);
    }

        我們測試了方法的交易屬性——是否所有的操作都成功了。編譯并運行——紅條。是的,我們平白無故地損失了300塊錢——source賬戶有正確的余額150.00,但destination賬戶顯示:$450.00。我們該如何修改?我們能夠只將最小余額檢查的調用放到數據更新的前面么:

    public void TransferFunds(Account destination, float amount) {
        if(balance - amount < minimumBalance) {
            throw new InsufficientFundsException();
        }
        destination.Deposit(amount);
        Withdraw(amount);
    }

        如果Withdraw()方法拋出了另外一個異常呢?我們應該在catch塊中執行一個補救處理,還是依賴我們的交易管理器來重新裝載對象的狀態?某些時候我們必須回答這樣的問題,但不是現在;可我們眼前如何應付這個失敗的測試呢——刪除它?一個不錯的方法是臨時忽略它在你的測試方法中添加下面的特性:

    [Test]
    [Ignore("Need to decide how to implement transaction management in the application")]
    public void TransferWithInsufficientFundsAtomicity() {
        // code is the same
    }

        編譯并運行——黃條。單擊“Test Not Run”選項卡,你會看到bank.AccountTest.TransferWithInsufficientFundsAtomicity()連同這個測試被忽略的原因一起列在列表中。

        看看我們的測試代碼,我們可以看到一些適宜的重構。所有的方法共享一組公共的測試對象。讓我們來將這些初始化代碼放到一個setup方法中并在所有的測試中重用它們。我們的測試類的重構版本像下面這樣:

    namespace bank {
        using System;
        using NUnit.Framework;

        [TestFixture]
        public class AccountTest {
            Account source;
            Account destination;

            [SetUp]
            public void Init() {
                source = new Account();
                source.Deposit(200.00F);
                destination = new Account();
                destination.Deposit(150.00F);
            }

            [Test]
            public void TransferFunds() {
                source.TransferFunds(destination, 100.00f);

                Assert.AreEqual(250.00F, destination.Balance);
                Assert.AreEqual(100.00F, source.Balance);
            }

            [Test]
            [ExpectedException(typeof(InsufficientFundsException))]
            public void TransferWithInsufficientFunds() {
                source.TransferFunds(destination, 300.00F);
            }

            [Test,
             Ignore (
                "Need to decide how to implement transaction management in the application"
            )]
            public void TransferWithInsufficientFundsAtomicity() {
                try {
                    source.TransferFunds(destination, 300.00F);
                }
                catch(InsufficientFundsException expected) {
                }

                Assert.AreEqual(200.00F,source.Balance);
                Assert.AreEqual(150.00F,destination.Balance);
            }
        }
    }

        注意這個初始化方法擁有通用的初始化代碼,它的返回值類型為void,沒有參數,并且由[SetUp]特性標記。編譯并運行——同樣的黃條!

    ============全文完==========

        如果你安裝了NUnit V2.1,可以在 開始->程序->NUnit V2.1->QuickStart 處得到原文(英文版)。

    原文轉自:http://www.kjueaiud.com

    ...

    熱門標簽

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>