2011-12-27 10 views
6

我跟隨有沒有一種方法可以保護遵循MethodName_Condition_ExpectedBehaviour模式的單元測試名稱不受重構的影響?

MethodName_Condition_ExpectedBehaviour

的命名慣例,當談到命名我的單元測試,測試的具體方法。

例如:

[TestMethod] 
public void GetCity_TakesParidId_ReturnsParis(){...} 

但是,當我需要重命名測試方法,如ReSharper的工具,不給我重命名這些測試。

有沒有辦法來防止重命名後出現這種情況?就像改變ReSharper設置或更好的單元測試命名約定等一樣?

+0

這與Java有什麼關係?應該從標籤中刪除'java'標籤。無論如何,如果你爲特定的方法編寫測試,那麼在Java中(例如使用JUnit),那麼測試和測試中的方法以及Eclipse,NetBeans等之間將沒有任何關聯。將不會提供您重構測試方法的名稱。我無法評論ReSharper的行爲。 – 2011-12-27 11:12:44

+0

「更改方法名稱」是一個很好的用例嗎?如果它是..也許你可以從你的測試名稱中省略這個變化磁鐵。例如。 TestCityRepository具有測試方法ShouldRetrieveCityById。通過這種方式,您可以與實現方法名稱隔離.. – Gishu 2011-12-28 05:11:57

回答

7

最近的模式是通過測試方法將測試分組到內部類中。

例如(省略測試屬性):

public CityGetterTests 
{ 
    public class GetCity 
    { 
     public void TakesParidId_ReturnsParis() 
     { 
      //... 
     } 

     // More GetCity tests 
    } 
} 

詳見Structuring Unit Tests from Phil Haack's blog

這個佈局的好處是,當方法名稱發生變化時,您只需更改內部類的名稱而不是所有的 單個測試。

+0

我真的很喜歡這個主意!你從哪裏瞭解到這種模式?任何資源或文章或...? (謝謝!) – pencilCake 2012-01-04 12:04:50

1

我也從這個轉換開始,但結果感覺不是很好。現在我使用BDD風格的名字,如should_return_Paris_for_ParisID

這使得我的測試更具可讀性和alsow讓我不用擔心我的測試:)

+0

因此,您沒有提到單元測試名稱中的方法名稱? – pencilCake 2011-12-30 06:51:23

+0

不,這讓我可以在沒有任何副作用的情況下重新命名它:)我認爲我測試的是場景,而不是特定的方法 – 2011-12-30 11:05:07

+0

也許你的方式可以連接到如下的評論:方法在測試:GetCity。因此,當您重命名您的方法時,ReSharper將提供重命名此TEXT。 – pencilCake 2011-12-30 11:08:58

0

我認爲,這裏的關鍵是什麼,你應該測試重構方法名。

你已經在標籤中提到了TDD,所以我希望我們在這裏試圖堅持。由範式,你寫的測試有兩個目的:

  1. 支持你的代碼一旦寫的,所以你可以不用擔心,你已經打破東西

  2. 重構指導我們設計組件的更好方式 - 首先編寫測試確實迫使您考慮解決手頭問題的必要條件。

我知道起初它看起來像這個問題是關於第一點,但我真的認爲這是關於第二點。你遇到的問題是你有你正在測試的具體組件,而不是合同。

在代碼方面,這意味着,我認爲我們應該測試接口,而不是類的方法,否則我們暴露了我們的測試,各種與試驗有關的問題組件,而不是合同 - 繼承策略,對象建設,在這裏,重命名。

確實接口名稱也會改變,但它們會比方法名稱更嚴格。 TDD給我們的不僅僅是通過測試工具支持變化的一種方式 - 它提供了洞察力,意識到我們可能會以錯誤的方式去改變它!

就拿代碼塊,你給:

[TestMethod] 
public void GetCity_TakesParidId_ReturnsParis(){...} 
{ 
    // some test logic here 
} 

而且我們說我們我們的對象測試方法GetCity()CityObtainer - 我什麼時候設置此對象嗎?我爲什麼這麼做?如果我意識到GetMatchingCity()是一個更好的名字,那麼你有上面列出的問題!

我提出的解決方案是,我們想想這個方法確實意味着在這個過程中早期,通過使用接口:

public interface ICityObtainer 
{ 
    public City GetMatchingCity(); 
} 

通過這種「由外而內」的風格寫作方式,我們不得不在思考過程中早些時候從對象那裏得到什麼,並且成爲焦點應該減少其波動性。這並不能消除你的問題,但它可能會有所緩解(而且,我認爲這是一個更好的方法)。

理想的情況下,我們走了一步,我們甚至沒有開始測試之前編寫任何代碼

[TestMethod] 
public void GetCity_TakesParId_ReturnsParis 
{ 
    ICityObtainer cityObtainer = new CityObtainer(); 
    var result = cityObtainer.GetCity("paris"); 

    Assert.That(result.Name, Is.EqualTo("paris"); 
} 

這樣一來,我可以看到我真正想組件甚至在我開始寫它之前 - 如果GetCity()不是我真正想要的,而是GetCityByID(),它會在這個過程中變得更加明顯。正如我上面所說,這不是萬無一失的,但它可能會減少這種特殊情況下的痛苦。

一旦你通過了,我覺得,如果你改變的方法的名稱,這是因爲你改變合同的條款,這意味着你應該去返回並重新考慮測試(因爲可能你不想改變它)。 (作爲快速附錄,如果我們在考慮TDD的情況下進行測試,那麼GetCity()中會發生一些事情,這些事件有大量邏輯在進行。合同有助於我們將意圖從執行中分離出來 - 無論我們改變界面,測試都將保持有效

相關問題