2017-12-25 3 views
0

임의성을 사용하는 단위 테스트 함수에 대한 모범 사례 기술에 관심이 있습니다. 명확하게하기 위해 난 이 아니며 난수 생성기의 분포를 테스트하는 데 관련된이 아닙니다. 장난감 예를 들어 임의성을 사용하는 함수를 단위 테스트하는 방법은 무엇입니까?

,의이 기능을 살펴 보자 : this question

// Returns a random element from @array. @array may not be empty. 
int GetRandomElement(int[] array); 

답변은 우리가 의미가 난수의 모의 소스를 삽입 할 수 있음을 시사한다. 하지만 모의 사용 방법을 정확히 모르겠습니다. 예를 들어, 우리는이 인터페이스를 가지고 있다고 가정하자 :

// A mock-friendly source of randomness. 
interface RandomnessSource { 
    // Returns a random int between @min (inclusive) and @max (exclusive). 
    int RandomInt(int min, int max); 
} 

을 ... 그리고 여기에 GetRandomElement()의 서명을 변경

:

// Returns a random element from @array, chosen with @randomness_source. 
// @array may not be empty. 
int GetRandomElement(int[] array, RandomnessSource randomness_source); 

모든 이제 시험처럼 잘 볼 수 있었다

MockRandomnessSource mock = new MockRandomnessSource(); 
mock.ExpectCall(RandomnessSource::RandomInt(0, 5)).Return(2); 
AssertEquals(GetRandomElement({0, 10, 20, 30, 40}, mock), 20); 

... 구현이 다음과 같이 보이는 경우에만 작동합니다.

마음에 도약

// Less intuitive, but still a conforming implementation. 
int GetRandomElement(int[] array, RandomnessSource randomness_source) { 
    // Pick a random number between [1..n+1), only to subtract 1 from it. 
    return array.Get(randomness_source.RandomInt(1, array.Length() + 1) - 1); 
} 

하나 개의 아이디어 우리가 더 같이, 함수의 계약을 제한 할 수 있다는 것이다 :

는 ...하지만 기능 사양의 것도이 같은 구현이 방지되지

// Returns a random element from @array, chosen with @randomness_source by 
// by calling @RandomnessSource::RandomInt to pick a random index between 
// 0 and the length of @array. 
int GetRandomElement(int[] array, RandomnessSource randomness_source); 

...하지만 함수 계약에 너무 많은 제한을 두는 인상을 완전히 넘을 수는 없습니다.

RandomnessSource 호출자를 단위 테스트에보다 잘 적용 할 수 있도록 인터페이스를 정의하는 데 더 좋은 방법이 있을지도 모르겠다.하지만 나는 무엇을 어떻게하는지 잘 모르겠습니다.

... 임의성을 사용하는 단위 테스트 기능을위한 최상의 연습 기법 (있는 경우)은 무엇입니까?

+0

"무작위"는 정의하기 어렵습니다. 따라서 질문은 "왜 '무작위'가 필요한가? 예를 들어, GetRandomElement를 테스트하려면 반드시 임의의 소스가 필요하지 않습니다. –

+0

@JamesKPolk 좀 더 자세히 설명해 주시겠습니까? 단위 테스트 GetRandomElement()의 예를 들어 주시겠습니까? –

+0

'RandomnessSource'의 테스트 버전은 범위의 극단에서 값을 반환하고 중간 값으로 반환해야합니다. 원하는 테스트 커버리지에 대한 결정을 내릴 수 있습니다. 결정 론적이지만 "임의"로 보이는 시퀀스를 사용할 수도 있습니다.고정 시드와 함께 java.util.Random 클래스 (Java를 사용하는 경우)와 같은 것을 통합합니다. –

답변

0

일반적으로 단위 테스트 "임의성"을 원하지 않습니다. 단위 테스트는 주로 예상 입력이 예상 결과를 제공하는지 여부를 결정하기위한 것입니다. 매우 정의되고 구조화되어 있습니다. 당신은 단위 테스트가 매우 예측 가능하고 테스트를 실행할 때마다 똑같은 방식으로 행동하기를 원합니다.

정말로 테스트하고 싶다면 질문은 정확히 어떻게 테스트 하시겠습니까? 두 테스트 사이에 결과가 다른 경우 어떻게됩니까? 성공적인 테스트와 실패한 테스트를 어떻게 정의합니까?

이러한 질문은 결과가 매우 명확하고 사전에 잘 정의 된 일반 단위 테스트에서 더욱 분명합니다.

+0

질문에 대답하려면 : 예, 단위 테스트를 결정적으로하고 싶습니다. 좀 더 구체적으로 말하면, 일반적으로 시간 소스를 모의 클럭으로 대체하여 시간 간격에 의존하는 함수를 테스트하는 것과 마찬가지로 결과가 결정적으로 소스를 대체하여 임의성의 소스에 일반적으로 의존하는 함수를 테스트하고 싶습니다. 두 가지 테스트 결과가 다른 경우 비 결정 성을 제거하기 위해 테스트를 다시 작성하고 싶습니다. 합격/불합격 구분은 주변 테스트 하네스 (예 : JUnit의 경우 예외를 throw하지 않고 복귀)에 지정된 것과 일치해야합니다. –

+0

@JaeHeonLee 그렇다면이 테스트를 작성하십시오. 이것이 당신의 질문에 어떻게 대답하지 않는지 확실하지 않습니다. –

+0

단위 테스트가 구현 세부 사항이 아닌 계약을 확인하도록 임의성의 소스를 조롱하는 방법을 구상하는 데 어려움을 겪고 있습니다. 즉, GetRandomElement() 코드가 "매우 직관적 인 구현"스 니펫에서 "덜 직관적이지만 여전히 준수하는 구현"으로 전환 되더라도 다시 작성하지 않아도되는 테스트를 작성하고 싶습니다. 원래 게시물의 스 니펫. –

관련 문제