2012-02-11 4 views
3

단위 테스트를 할 때마다 머리를 감싸려고 노력했으며 매개 변수 집합에 따라 반환 값이 달라지는 함수를 단위 테스트로 처리하려고합니다. 이 그러나 많은 정보 그리고 그것은 조금 압도적 ..여러 입력을 이용한 단위 테스트

다음과 같은 고려의 :

나는 가격의 컬렉션을 가진 클래스 Article을 보유하고 있습니다. 그것은 몇 가지 규칙에 따라 현재의 가격을 결정하는 방법을 GetCurrentPrice 있습니다

public class Article 
{ 
    public string Id { get; set; } 
    public string Description { get; set; } 
    public List<Price> Prices { get; set; } 

    public Article() 
    { 
     Prices = new List<Price>(); 
    } 

    public Price GetCurrentPrice() 
    { 
     if (Prices == null) 
      return null; 

     return (
      from 
      price in Prices 

      where 

      price.Active && 
      DateTime.Now >= price.Start && 
      DateTime.Now <= price.End 

      select price) 
      .OrderByDescending(p => p.Type) 
      .FirstOrDefault(); 
    } 
} 

PriceType 열거하고 Price 클래스 :

public enum PriceType 
{ 
    Normal = 0, 
    Action = 1 
} 

public class Price 
{ 
    public string Id { get; set; } 
    public string Description { get; set; } 
    public decimal Amount { get; set; } 
    public PriceType Type { get; set; } 
    public DateTime Start { get; set; } 
    public DateTime End { get; set; } 
    public bool Active { get; set; } 
} 

내가 GetCurrentPrice 방법에 대한 단위 테스트를 만들려고합니다. 기본적으로 모든 규칙 조합을 테스트하고 싶기 때문에 여러 가지 조합으로 가격을 조합하여 여러 가지 기사를 작성해야합니다.

[TestMethod()] 
public void GetCurrentPriceTest() 
{ 
    var articles = getTestArticles(); 
    foreach (var article in articles) 
    { 
     var price = article.GetCurrentPrice(); 
     // somehow compare the gotten price to a predefined value 
    } 
} 
  • 내가 '악마 다수가 주장하는'읽었습니다,하지만 난 그들에게 필요하지 않습니다 :

    나는 그런이 (의사)와 같은 단위 테스트를 생각하고 여기에서 모든 조건을 테스트 할 수 있습니까? 또는 조건 당 테스트 단위가 별도로 필요합니까? ?

  • 단위 테스트에 일련의 테스트 데이터를 제공하는 방법은 무엇입니까? 저장소를 조롱해야합니까? 또한 해당 데이터에 예상 값이 포함되어야합니까?

답변

3

이 예제에서는 저장소를 사용하지 않으므로 아무 것도 모방 할 필요가 없습니다. 당신이 할 수있는 것은 다른 가능한 입력에 대해 여러 단위 테스트를 작성하는 것입니다 :

[TestMethod] 
public void Foo() 
{ 
    // arrange 
    var article = new Article(); 
    // TODO: go ahead and populate the Prices collection with dummy data 


    // act 
    var actual = article.GetCurrentPrice(); 

    // assert 
    // TODO: assert on the actual price returned by the method 
    // depending on what you put in the arrange phase you know 
} 

그래서 당신은 가능한 각 입력에 대한 arrangeassert 단계를 변경하는 다른 단위 테스트를 추가 할 수 있습니다에.

+0

이 경우 '단위'는 무엇입니까? GetCurrentPrice가 제대로 작동하는지 알고 싶습니다. 서로 다른 모든 입력이 '단위'입니까? 그리고 이러한 모든 단위 테스트가 통과하는 방식의 정확성은 무엇입니까? 아니면 방법 자체가 단위입니까? – diggingforfire

+0

@diggingforfire에는 '단위'가 없습니다. 하지만 그것은 코드가 '단위'가 없도록 설계 되었기 때문입니다. 'Article' 클래스는 2 가지 작업을 수행합니다. 즉, 일부 데이터를 보유하는 속성이 있으며이 데이터를 조작하는 메서드가 포함되어 있습니다. 그래서 당신은 단위 테스트를 분리해서 수행 할 수 없습니다. 이러한 책임을 분리하고 싶다면 별도의 저장소 클래스에'GetCurrentPrice'를 정의하면'Article' 인스턴스를 인수로 사용할 수 있습니다. –

+0

빈혈 도메인 모델로 이어지지 않습니까? 나는 그 논리를 포함하기 위해'Article' 자체를 선호 할 것이다. 그것은 단위 테스트를 조금 더 어렵게 만드는 것 같습니다. – diggingforfire

2

다중 어설 션이 필요하지 않습니다. 각각 하나의 어설트만으로 여러 테스트가 필요합니다.

+0

나는 여기에 동의하지 않을 것이다. 동일한 결과가 예상되는 한 테스트 데이터를 결합 할 수 있다고 생각합니다.반복 패턴 내에서 단일 테스트에서 같은 것을 달성 할 수있을 때 100 단위 테스트를 작성할 이유가 없습니다. 이것은 각각에 대한 테스트 결과가 동일해야한다고 가정합니다. 예를 들어, 메소드에 전달 된 각 키의 테스트 데이터로 사용 된 키 값 쌍 사전입니다. 메소드 리턴 값은 키 값 쌍의 값이어야합니다. 이것이 효과적이지 않은 이유는 없습니다. – tsells

+0

하루가 끝날 때 - 같은 데이터 평가가 수행됩니다 - 실패한 경우 - 이유를 파악해야합니다 - 따라서 디버거를 가동하고 테스트를 조사하십시오. 같은 결과 - 유지하기가 훨씬 쉬워 ..... – tsells

+0

@tsells : 단일 단위 테스트를 만든 다음 두 번째 단위 테스트를 만든 다음 리팩터링을 시작합니다. 하나의 테스트가 실패하면 나머지 테스트가 실행되지 않는다는 단점이 있지만 반복 테스트의 수준에 도달 할 수 있습니다. –

2

각 시작 조건 및 단일 어설 션에 대한 새로운 테스트, f. 단위 테스트에 대한 경계

에 대한

[Test] 
public void GetCurrentPrice_PricesCollection1_ShouldReturnNormalPrice(){...} 

[Test] 
public void GetCurrentPrice_PricesCollection2_ShouldReturnActionPrice(){...} 

또한 시험은 내가 당신이 datadriven 테스트가 필요하다고 생각 패턴을

MethodName_UsedData_ExpectedResult() 
+0

그럼 모든 가능한 입력에 대한 테스트를하고 각각의 결과를 얻을 수 있을까요? 그것은 논리적으로 들린다. 모두 설정하려면 많은 수동 코딩이 필요합니다. 그러한 데이터로 테스트를 쉽게 제공 할 수있는 방법이 있습니까? – diggingforfire

+0

우리는 iam이 모든 것을 테스트하지 않는다는 것을 말할 수 있습니다 (거의 불가능합니다). 경계에 집중해야합니다 (예 : 같은 날짜이지만 가격이 다른 가격). 일반적인 일은 많은 것을 테스트 할 가치가 없습니다. 예를 들어 유효한 PriceCollection을 만들기 위해 공장을 많이 사용하지만 좀 더 코드를 작성해야하지만 솔루션을 리팩토링하기 시작할 때 단위 테스트 마녀로 이해할 수 있습니다. – Ivan

+0

Resharper는 그 단위 테스트 패턴에 대해 당신에게 비명을 지릅니다. 그냥 호기심 - 거기에 메서드 이름이 필요한 이유는 무엇입니까? 테스트 중에 메서드가 호출되는 것을 볼 수 있습니까? – tsells

2

를 사용합니다. vsts에는 Datasource라는 속성이 있습니다.이 속성을 사용하면 테스트 메소드에 여러 테스트 케이스를 보낼 수 있습니다. 다중 어설 션을 사용하지 마십시오. 여기에 하나의 MSDN 링크가 있습니다. http://msdn.microsoft.com/en-us/library/ms182527.aspx

희망이 있으면 도움이 될 것입니다.

+0

왜 데이터가 구동? 이것은 데이터베이스를 테스트하지 않습니다. – tsells

+0

우리는 여러 입력이있는 메소드를 테스트해야 할 때 데이터 기반 테스트를 사용합니다. 어떤 방법이든 가능합니다. –

관련 문제