iT邦幫忙

DAY 14
2

30天快速上手TDD系列 第 14

[Day 14]Refactoring - 驗貨

  • 分享至 

  • twitterImage
  •  

在上一篇文章中,重構第五式:「給你錢,趕快做」中,重點在於如何站在當下物件的角度,去思考自身職責該處理的邏輯,並思考非自身職責的部分,該委託給哪一個物件來處理。

「只管跟他要,而不管他怎麼做」,這就是第五式的精髓。

接下來這篇文章,則是怎麼驗證委託物件給的,真的是我們要的呢?

所以這一篇文章標題,定義為「驗貨」,重構第六式:「確定對方給的,是我要的」

我們將先透過建立測試案例,來確保物件回傳的結果,是如同我們所預期。

上一篇文章:[Day 13]Refactoring - 告訴我,你要什麼
本系列文章專區
@重構第六式:確定對方給的,是我要的

在前面已經定義出來『我們要什麼,跟誰要』,接著是要確定『物流商給我們的資訊,是不是我們要的』。

怎麼確定物流商給的資訊沒錯?對啦,就是用測試啦。

正所謂羊毛出在羊身上,建立單元測試的測試案例,往往可以從一開始的整合測試案例中找到蛛絲馬跡,也就是我們一開始錄影存證的部份。

Selenium test cases如下圖所示:

期望結果(以黑貓為例):

  1. 呼叫黑貓的GetsCompanyName方法,應該得到『黑貓』。
  2. 還沒呼叫黑貓計算運費前,呼叫黑貓的GetsFee方法,應該得到0。
  3. 當給了整合測試上的商品資訊後,呼叫黑貓的Calculate方法後,呼叫GetsFee方法,應該得到200。

依據測試案例,建立的單元測試程式碼如下:

/// <summary>
///GetsComapanyName 的測試
///</summary>
[TestMethod()]
public void GetsComapanyNameTest_v3()
{
    BlackCat target = new BlackCat();
    string expected = "黑貓";
    string actual;
    actual = target.GetsComapanyName();
    Assert.AreEqual(expected, actual);
}

/// <summary>
///GetsFee 的測試
///</summary>
[TestMethod()]
public void GetsFeeTest_v3()
{
    BlackCat target = new BlackCat();
    double expected = 0F;
    double actual;
    actual = target.GetsFee();
    Assert.AreEqual(expected, actual);
}

/// <summary>
///Calculate 的測試
///</summary>
[TestMethod()]
public void CalculateTest_v3()
{
    //從整合測試的test case,來當做單元測試的test case

    //arrange
    BlackCat target = new BlackCat()
    {
        ShipProduct = new Product
        {
            IsNeedCool = true,
            Name = "商品測試1",
            Size = new Size
            {
                Height = 10,
                Length = 30,
                Width = 20
            },
            Weight = 10
        }
    };

    //act
    target.Calculate();

    
    var expectedName = "黑貓";
    var expectedFee = 200;

    var actualName = target.GetsComapanyName();
    var actualFee = target.GetsFee();

    //assert
    Assert.AreEqual(expectedName, actualName);
    Assert.AreEqual(expectedFee, actualFee);
}

註:對Unit test還不熟的朋友,可以參考本系列前面的鐵人賽文章:[Day 3]動手寫Unit Test,或是[ASP.NET]重構之路系列v5 –單元測試, Just Do It!!

建立完我們預期物流商的行為,執行一下測試的結果,得到了9個紅燈,得到的例外都是『System.NotImplementedException: 方法或作業尚未實作』(因為我還沒發功啊)。如下圖所示:

看到紅燈,莫急莫慌莫害怕,因為這是我們所設定這一次動作的終點線。(同時也是起點線,笑...)

慢慢地,各位讀者就會了解到,看到紅燈有種莫名的快感,只要把紅燈轉綠,就至少可以交差的感覺,更是妙不可言。

@小結
雖然上面這一步碰到了九個紅燈,但是這個紅燈是一個很棒的里程碑,因為這是重構循環中,重要的一個紅燈。(基本上,也可以當作是TDD的紅燈)如下圖所示:

這一個紅燈,代表了我們已經邁出了第一步:「先思考好,使用者要什麼。」 接著,不管物件怎麼設計,程式寫的多爛、多沒彈性,我們都可以確定:「眼前這爛貨或是神蹟,到底能不能滿足我們的需求」。

TDD, Agile, Scrum,都有個重要的精神:小步前進,迅速回饋,擁抱變化,隨時調整。

相同的目標,都是做出最吻合使用者需求的軟體。任何需求的異動,架構的調整,程式的改善,都是讓系統品質更加進化的方式,只有最符合使用者需求,系統才有所謂的價值。
(順便推薦一本跟這相關的好書:浮現式設計-專業軟件開發的演進本質,原文書名:Emergent Design: The Evolutionary Nature of Professional Software Development

做再好的軟體,全世界沒人用,那就真的是一坨金子堆出來的廢物。亮晶晶,也很貴,但仍是廢物。

by the way, 眼尖的讀者朋友應該已經發現,重構系列中會開始不斷運用到本系列前面的第一大主題:測試的目的、技巧、工具與方式。這也是為什麼第一篇總綱,就先定義出TDD各大主題的學習順序,以及實際開發時的順序不相同。

TDD真的不難,但相關的每一份基本功,都要夠紮實,才不會因為碰到一些門檻,就嫌棄測試無用,這實在非測試之罪啊...


上一篇
[Day 13]Refactoring - 告訴我,你要什麼
下一篇
[Day 15]Refactoring - 食神歸位
系列文
30天快速上手TDD31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

我要留言

立即登入留言