Yahtzee 게임을 어떻게 TDD해야합니까?


36

Yahtzee 게임 TDD 스타일을 작성한다고 가정 해 봅시다. 5 개의 다이 롤 세트가 풀 하우스인지 여부를 판별하는 코드 부분을 테스트하려고합니다. 내가 아는 한, TDD를 수행 할 때 다음 원칙을 따르십시오.

  • 먼저 테스트를 작성하십시오
  • 가능한 가장 간단한 것을 작성하십시오
  • 세분화 및 리팩터링

따라서 초기 테스트는 다음과 같습니다.

public void Returns_true_when_roll_is_full_house()
{
    FullHouseTester sut = new FullHouseTester();
    var actual = sut.IsFullHouse(1, 1, 1, 2, 2);

    Assert.IsTrue(actual);
}

"가장 간단한 것을 작성하십시오"를 따르면, 다음 IsFullHouse과 같이 메소드를 작성해야 합니다.

public bool IsFullHouse(int roll1, int roll2, int roll3, int roll4, int roll5)
{
    if (roll1 == 1 && roll2 == 1 && roll3 == 1 && roll4 == 2 && roll5 == 2)
    {
        return true;
    }

    return false;
}

이로 인해 친환경 테스트가 이루어 지지만 구현이 불완전합니다.

전체 주택에 대해 가능한 모든 유효한 조합 (값과 위치 모두)을 단위 테스트해야합니까? 그것은 IsFullHouse코드가 완전히 테스트되고 정확 하다는 것을 절대적으로 확신하는 유일한 방법처럼 보이지만 그렇게하는 것은 미친 듯이 들립니다.

이런 식으로 어떻게 단위 테스트를 하시겠습니까?

최신 정보

Erik과 Kilian은 초기 구현에서 리터럴을 사용하여 친환경 테스트를받는 것이 가장 좋은 방법은 아니라고 지적합니다. 왜 그런 짓을했는지 설명하고 싶습니다. 그 설명은 주석에 맞지 않습니다.

단위 테스트 (특히 TDD 접근 방식 사용)에 대한 나의 실제 경험은 매우 제한적입니다. 나는 Tekpub에서 Roy Osherove의 TDD 마스터 클래스를 녹화 한 것을 본 적이 있습니다. 에피소드 중 하나에서 그는 문자열 계산기 TDD 스타일을 만듭니다. 문자열 계산기의 전체 사양은 여기에서 찾을 수 있습니다 : http://osherove.com/tdd-kata-1/

그는 다음과 같은 테스트로 시작합니다.

public void Add_with_empty_string_should_return_zero()
{
    StringCalculator sut = new StringCalculator();
    int result = sut.Add("");

    Assert.AreEqual(0, result);
}

Add방법의 첫 번째 구현 결과는 다음과 같습니다.

public int Add(string input)
{
    return 0;
}

그런 다음이 테스트가 추가됩니다.

public void Add_with_one_number_string_should_return_number()
{
    StringCalculator sut = new StringCalculator();
    int result = sut.Add("1");

    Assert.AreEqual(1, result);
}

그리고 Add방법은 리팩토링됩니다.

public int Add(string input)
{
    if (input.Length == 0)
    {
        return 0;
    }

    return 1;
}

각 단계 후에 Roy는 "작동하는 가장 간단한 것을 작성하십시오"라고 말합니다.

그래서 나는 TDD 스타일의 Yahtzee 게임을 할 때이 접근법을 시도해 볼 것이라고 생각했습니다.


8
"작동 가능한 가장 간단한 것을 작성하십시오"는 실제로 약어입니다. 올바른 조언은 " 완전히 뇌사되지 않고 작동 하지 않는 가장 간단한 것을 작성하십시오 "입니다. 그래서, 당신은 쓰지 말아야합니다if (roll1 == 1 && roll2 == 1 && roll3 == 1 && roll4 == 2 && roll5 == 2)
Carson63000

3
에릭의 대답을 요약 해 주셔서 감사합니다.
Kristof Claes

1
@ Carson63000과 같이 "가장 간단한 것을 작성하십시오"는 실제로 단순화 된 것입니다. 실제로 그렇게 생각하는 것은 위험합니다. 그것은 악명 높은 Sudoku TDD debacle (google it)로 연결됩니다. 맹목적으로 따랐을 때, TDD는 실제로는 뇌졸중입니다. "가장 간단한 것"을 맹목적으로 수행하여 사소한 알고리즘을 일반화 할 수는 없습니다 ... 실제로 생각해야합니다! 불행히도 XP와 TDD의 혐의자조차도 때때로 맹목적으로 따랐습니다.
Andres F.

1
@AndresF. 3 일 이내에 "Soduko TDD debacle"에 대한 많은 의견보다 Google 검색에서 귀하의 의견이 더 많이 표시되었습니다. 그럼에도 불구하고 스도쿠를 해결하지 않는 방법은 요약했습니다. TDD는 정확성이 아니라 품질을위한 것입니다. 코딩을 시작하기 전에, 특히 TDD를 사용하여 알고리즘을 해결해야합니다. (저도 코드 우선 프로그래머가 아닙니다.)
Mark Hurd

1
pvv.org/~oma/TDDinC_Yahtzee_27oct2011.pdf 에 관심이있을 수 있습니다.

답변:


40

이 질문에 대한 좋은 답변이 이미 많이 있으며, 그 중 몇 가지를 언급하고 찬성했습니다. 그래도 몇 가지 생각을 추가하고 싶습니다.

유연성은 초보자를위한 것이 아닙니다

OP는 분명히 TDD에 경험이 없다고 명시하고 있으며, 좋은 대답은 그것을 고려해야한다고 생각합니다. Dreyfus 기술 습득 모델의 용어 에서 그는 아마도 초보자 일 것입니다 . 초보자가되는 데 아무런 문제가 없습니다. 새로운 것을 배우기 시작할 때 우리 모두는 초보자입니다. 그러나 Dreyfus 모델이 설명하는 것은 초보자가

  • 교칙 또는 계획을 엄격히 준수
  • 재량 적 판단의 행사가 없다

그것은 성격 결핍에 대한 설명이 아니기 때문에 부끄러워 할 이유가 없습니다. 새로운 것을 배우기 위해 우리 모두가 거쳐야 할 단계입니다.

이것은 TDD에도 해당됩니다.

나는 여기에 TDD가 독단적 일 필요는 없으며 때로는 다른 방법으로 일하는 것이 더 유익 할 수 있다는 다른 많은 답변에 동의하지만, 누군가 처음 시작하는 데 도움이되지는 않습니다. 경험이 없을 때 어떻게 재량적인 판단을 내릴 수 있습니까?

초보자가 때때로 TDD를하지 않아도된다는 조언을 받아 들인다면, TDD를 건너 뛰는 것이 괜찮은 시점을 어떻게 알 수 있습니까?

경험이나지도없이 초보자가 할 수있는 유일한 일은 너무 어려워 질 때마다 TDD를 건너 뛰는 것입니다. 그것은 인간의 본성이지만 배우는 좋은 방법은 아닙니다.

시험 들어 봐

TDD가 어려워 질 때마다 건너 뛰는 것은 TDD의 가장 중요한 이점 중 하나를 놓치는 것입니다. 테스트는 SUT의 API에 대한 초기 피드백을 제공합니다. 테스트를 작성하기 어려운 경우 SUT를 사용하기 어렵다는 것이 중요합니다.

이 중 가장 중요한 메시지 중 하나가 이유입니다 GOOS가 :있다 당신의 검사 결과를 듣고!

이 질문의 경우 Yahtzee 게임의 제안 된 API를 볼 때의 첫 번째 반응 과이 페이지에서 찾을 수있는 조합에 대한 토론은 이것이 API에 대한 중요한 피드백이라는 것입니다.

API가 주사위 롤을 순서가 지정된 정수 시퀀스로 나타내야합니까? 나에게, 원시적 집착의 냄새 . 그래서 키스톤의 Roll수업에 대한 소개를 제안한 답변을보고 기뻤습니다 . 나는 그것이 훌륭한 제안이라고 생각합니다.

그러나 그 대답에 대한 주석 중 일부가 잘못되었다고 생각합니다. TDD가 제안하는 것은 일단 Roll수업이 좋은 아이디어라는 생각을 갖게되면 원래 SUT에 대한 작업을 중단하고 Roll수업 에 TDD에 대한 작업을 시작한다는 것 입니다.

TDD가 포괄적 인 테스트를 목표로하는 것보다 '행복한 길'을 목표로한다는 것에 동의하지만 시스템을 관리 가능한 단위로 세분화하는 데 여전히 도움이됩니다. Roll뭔가 같은 수준의 사운드는 훨씬 더 쉽게 완료 TDD 수 있습니다.

그런 다음 Roll수업이 충분히 진화되면 원래 SUT로 돌아가 Roll입력 측면에서 육체를 만들어 내겠습니까?

테스트 도우미 의 제안이 반드시 임의성을 의미하는 것은 아닙니다. 테스트를 더 읽기 쉽게 만드는 방법 일뿐입니다.

Roll인스턴스 측면에서 입력에 접근하고 모델링하는 또 다른 방법 은 테스트 데이터 빌더 를 도입하는 것 입니다.

레드 / 그린 / 리 팩터는 3 단계 프로세스입니다

나는 (TDD에 충분히 경험이 있다면) 일반적인 감정에 동의하지만 TDD를 엄격하게 고수 할 필요는 없지만 Yahtzee 운동의 경우 조언이 좋지 않다고 생각합니다. 나는 Yahtzee 규칙의 세부 사항을 알지 못하지만 Red / Green / Refactor 프로세스를 엄격하게 유지할 수는 없지만 여전히 적절한 결과에 도달한다는 설득력있는 주장은 없습니다.

여기에서 대부분의 사람들이 잊어 버린 것처럼 보이는 것은 Red / Green / Refactor 프로세스의 세 번째 단계입니다. 먼저 테스트를 작성하십시오. 그런 다음 모든 테스트를 통과하는 가장 간단한 구현을 작성하십시오. 그런 다음 리팩터링합니다.

이 세 번째 주에서는 모든 전문 기술을 습득 할 수 있습니다. 여기에서 코드를 반영 할 수 있습니다.

그러나, 나는 당신이 " 완전히 뇌사하지 않고 분명히 작동 하지 않는 가장 간단한 것을 작성해야한다"고 말한 것으로 보인다. 미리 구현에 대해 충분히 알고 있다면 완전한 솔루션이 부족한 모든 것이 분명히 잘못 될 것 입니다. 조언이가는 한, 이것은 초보자에게는 쓸모가 없습니다.

실제로 발생하는 것은 모든 테스트가 명백히 잘못된 구현으로 통과 할 수 있다면 다른 테스트를 작성해야한다는 피드백입니다 .

얼마나 자주 당신이 처음 생각했던 것과는 완전히 다른 구현으로 당신을 이끈다는 것은 놀라운 일입니다. 때로는 그와 같이 성장하는 대안이 원래 계획보다 나을 수도 있습니다.

Rigor는 학습 도구입니다

배우는 한 Red / Green / Refactor와 같은 엄격한 프로세스를 고수하는 것이 합리적입니다. 학습자가 쉬울 때뿐만 아니라 어려운 경우에도 TDD에 대한 경험을 얻도록 강요합니다.

모든 어려운 부분 을 숙달 한 경우에만 '진정한'경로에서 벗어날시기에 대한 정보를 바탕으로 결정을 내릴 수 있습니다. 그때 당신은 당신의 자신의 길을 형성하기 시작합니다.


'다른 TDD 초보자도 여기에 시도하는 데 대한 모든 일반적인 오해가 있습니다. 모든 테스트를 명백히 잘못된 구현으로 통과시킬 수 있다면 흥미를 가지게됩니다. 즉, 다른 테스트를 작성해야한다는 피드백입니다. "braindead"구현을 테스트하는 것은 불필요하게 바쁘다는 인식을 해결하는 좋은 방법 인 것 같습니다.
shambulator

1
우와 고마워. 나는 사람들이 TDD (또는 다른 분야)의 초보자에게 "규칙에 대해 걱정하지 말고 가장 기분이 좋은 일을하라"고 말하는 경향이 정말 두렵습니다. 지식이나 경험이 없을 때 기분이 가장 좋은 것을 어떻게 알 수 있습니까? 또한 변환 우선 순위 원칙을 언급하고 싶거나 테스트가 더 구체화 될수록 코드가 더 일반화되어야합니다. uncle bob과 같은 가장 어려운 TDD 지지자들은 "모든 테스트에 대해 새로운 if-statement를 추가하십시오"라는 개념을지지하지 않을 것입니다.
sara

41

면책 조항으로, 이것은 내가 연습 할 때 TDD이며, Kilian이 적절하게 지적했듯이, 나는 그것을 연습하는 올바른 방법이 하나 있다고 제안한 사람에 대해 경계 할 것입니다. 그러나 아마도 그것은 당신을 도울 것입니다 ...

우선, 테스트를 통과하기 위해 할 수있는 가장 간단한 방법은 다음과 같습니다.

public bool IsFullHouse(int roll1, int roll2, int roll3, int roll4, int roll5)
{
    return true;
}

이것은 약간의 TDD 연습 때문이 아니라 모든 리터럴을 하드 코딩하는 것이 실제로 좋은 생각이 아니기 때문에 중요합니다. TDD로 머리를 감싸기 가장 어려운 점 중 하나는 포괄적 인 테스트 전략이 아니라는 것입니다. 코드를 단순하게 유지하면서 회귀를 막고 진행 상황을 표시하는 방법입니다. 그것은의 개발 전략이 아닌 테스트 전략.

이 차이점에 대해 언급 한 이유는 작성해야 할 테스트를 안내하는 데 도움이되기 때문입니다. "어떤 테스트를 작성해야합니까?" "코드를 원하는 방식으로 얻는 데 필요한 테스트는 무엇이든" TDD를 사용하여 코드에 대한 알고리즘과 이유를 알아낼 수 있습니다. 테스트와 "간단한 녹색"구현을 고려할 때 다음 테스트는 무엇입니까? 당신은 풀 하우스 인 것을 설립했습니다. 그래서 풀 하우스가 아닌 것은 언제입니까?

public void Returns_true_when_roll_is_full_house()
{
    FullHouseTester sut = new FullHouseTester();
    var actual = sut.IsFullHouse(1, 2, 3, 4, 5);

    Assert.IsFalse(actual);
}

이제 의미있는 두 가지 테스트 사례를 구별 할 수있는 방법을 찾아야 합니다. 나는 개인적으로 "테스트 패스를 만드는 가장 간단한 일을한다"는 정보를 약간 설명하고 "구현을 촉진시키는 테스트 패스를 만드는 가장 간단한 일을한다"고 말합니다. 실패한 테스트를 작성하는 것은 코드를 변경하는 구실이므로 각 테스트를 작성하려고 할 때 "내 코드가 원하는 것을 수행하지 않는 방법과 해당 결함을 어떻게 노출시킬 수 있습니까?" 또한 코드를 강력하게 만들고 에지를 처리하는 데 도움이 될 수 있습니다. 발신자가 넌센스를 입력하면 어떻게합니까?

public void Returns_true_when_roll_is_full_house()
{
    FullHouseTester sut = new FullHouseTester();
    var actual = sut.IsFullHouse(-1, -2, -3, -4, -5);

    //I dunno - throw exception, return false, etc, whatever you think it should do....
}

요약하면, 모든 값 조합을 테스트하는 경우 거의 확실하게 잘못하고 있습니다 (조건 문의 조합 폭발로 이어질 수 있습니다). TDD와 관련하여 원하는 알고리즘을 얻는 데 필요한 최소 테스트 사례를 작성해야합니다. 작성하는 추가 테스트는 모두 녹색으로 시작하여 본질적으로 TDD 프로세스의 일부가 아닌 문서화됩니다. 요구 사항이 변경되거나 버그가 노출 된 경우에만 추가 TDD 테스트 사례를 작성합니다.이 경우 테스트로 결함을 문서화 한 다음 통과시킵니다.

최신 정보:

귀하의 업데이트에 대한 의견으로 이것을 시작했지만 꽤 오래 걸리기 시작했습니다 ...

나는 문제가 문자, 마침표의 존재가 아니라 '가장 단순한'것이 5 부분의 조건부라는 것입니다. 당신이 그것에 대해 생각할 때, 5 부분으로 된 조건부는 실제로 꽤 복잡합니다. 빨강-녹색 단계에서 리터럴을 사용한 다음 리 팩터 단계에서 상수로 추상화하거나 나중에 테스트에서 일반화하는 것이 일반적입니다.

TDD와의 여정에서 나는 중요한 구별이 있다는 것을 깨달았습니다. "간단한"과 "불분명 한"을 혼동하는 것은 좋지 않습니다. 즉, 처음 시작할 때 사람들이 TDD를 수행하는 것을 보았고 "테스트를 통과하기 위해 가장 멍청한 일을하고있는 것"이라고 생각했고 "간단한"것이 미묘하게 다르다는 것을 깨달을 때까지 한동안 그것을 모방했습니다. "obtuse"보다 때로는 겹치지 만 종종 그렇지 않습니다.

따라서 리터럴의 존재가 문제라는 인상을 주면 사과하십시오. 나는 5 절과 조건의 복잡성이 문제라고 말합니다. 첫 번째 빨강에서 초록까지는 "참으로 돌아 가기"일 수 있습니다. 왜냐하면 그것은 단순하기 때문입니다 (그리고 우연의 일치). (1, 2, 3, 4, 5)가있는 다음 테스트 사례는 false를 반환해야합니다. 여기에서 "obtuse"를 남기기 시작합니다. "(1, 1, 1, 2, 2)가 풀 하우스이며 (1, 2, 3, 4, 5)가 아닌 이유는 무엇입니까?" 가장 간단한 것은 하나의 시퀀스 요소 5 또는 두 번째 시퀀스 요소 2가 있고 다른 하나는 그렇지 않은 것입니다. 그것들은 단순하지만, (필요하게) 불분명합니다. 당신이 정말로 운전하고 싶은 것은 "동일한 숫자가 몇 개입니까?"입니다. 따라서 반복이 있는지 여부를 확인하여 두 번째 테스트를 통과 할 수 있습니다. 반복되는 사람에게는 완전한 집이 있고 다른 사람에게는없는 집이 있습니다. 이제 테스트가 통과하고 반복이 있지만 알고리즘을 세분화 할 풀 하우스가 아닌 다른 테스트 사례를 작성합니다.

당신이 갈 때 리터럴로 이것을 할 수도 있고하지 않을 수도 있습니다. 그렇다면 괜찮습니다. 그러나 일반적인 아이디어는 사례를 더 추가할수록 알고리즘을 '유기적으로'늘리는 것입니다.


리터럴 방식으로 시작한 이유에 대한 정보를 추가하기 위해 질문을 업데이트했습니다.
Kristof Claes

9
이것은 좋은 대답입니다.
tallseth

1
사려 깊고 잘 설명 된 답변에 감사드립니다. 제가 생각하기에 실제로 많은 의미가 있습니다.
Kristof Claes

1
철저한 테스트가 모든 조합을 테스트한다는 의미는 아닙니다. 이 특정한 경우에는 특정 풀 하우스 또는 2와 2 개의 비 풀 하우스를 가져 가십시오. 또한 문제를 일으킬 수있는 특수 조합 (예 : 5 가지).
Schleis

3
이 대답 뒤에 1 개 원칙은 로버트 C. 마틴의 변환 우선 순위 전제로 설명되어 있습니다 cleancoder.posterous.com/the-transformation-priority-premise
마크 시만을

5

특정 조합에서 5 개의 특정 리터럴 값을 테스트하는 것은 열이 나는 뇌에 "가장 단순하지"않습니다. 문제에 대한 해결책이 정말로 명백한 경우 (당신이 수 있는지 정확히 3과 정확히 두의 어떤 모든 수단 가서 코드 솔루션 것으로, 일부 테스트를 작성하여 값), 그 함께 실수로 만족 매우 어려울 것 작성한 코드의 양 (즉, 다른 리터럴과 다른 순서의 트리플과 더블).

TDD 맥심은 실제로 종교적 믿음이 아니라 도구입니다. 그들의 요점은 정확하고 체계적인 코드를 신속하게 작성하는 것입니다. 맥심이 분명히 그 길에 서 있다면 다음 단계로 넘어 가십시오. 프로젝트에 적용 할 수있는 분명하지 않은 비트 가 많이 있습니다.


5

에릭의 대답은 훌륭하지만 테스트 작문에서 트릭을 공유 할 수 있다고 생각했습니다.

이 테스트로 시작하십시오.

[Test]
public void FullHouseReturnsTrue()
{
    var pairNum = AnyDiceValue();
    var trioNum = AnyDiceValue();

    Assert.That(sut.IsFullHouse(trioNum, pairNum, trioNum, pairNum, trioNum));
}

이 테스트는 Roll5 개의 매개 변수를 전달하는 대신 클래스 를 만들면 더욱 향상됩니다 .

[Test]
public void FullHouseReturnsTrue()
{
    var roll = AnyFullHouse();

    Assert.That(sut.IsFullHouse(roll));
}

그것은이 구현을 제공합니다 :

public bool IsFullHouse(Roll toCheck)
{
    return true;
}

그런 다음이 테스트를 작성하십시오.

[Test]
public void StraightReturnsFalse()
{
    var roll = AnyStraight();

    Assert.That(sut.IsFullHouse(roll), Is.False);
}

일단 통과하면 다음을 작성하십시오.

[Test]
public void ThreeOfAKindReturnsFalse()
{
    var roll = AnyStraight();

    Assert.That(sut.IsFullHouse(roll), Is.False);
}

그 후, 나는 더 이상 쓸 필요가 없다고 생각합니다.

분명히 모든 메소드를 구현하여 기준에 맞는 임의의 롤을 반환하십시오.

이 방법에는 몇 가지 이점이 있습니다.

  • 특정 값에 갇히는 것을 막기위한 목적으로 테스트를 작성할 필요가 없습니다.
  • 테스트는 당신의 의도를 정말 잘 전달합니다
  • 그것은 문제의 고기를 다루는 시점으로 빠르게 당신을 데려갑니다.
  • 때때로 그것은 당신이 생각하지 않은 경우를 알아 차릴 것입니다

이 방법을 사용하면 Assert.That 문에서 로그 메시지를 개선해야합니다. 개발자는 어떤 입력에서 오류가 발생했는지 확인해야합니다.
Bringer128

이것이 닭 또는 계란 딜레마를 만들지 않습니까? AnyFullHouse를 구현할 때 (TDD도 사용) 정확성을 확인하기 위해 IsFullHouse가 필요하지 않습니까? 특히 AnyFullHouse에 버그가있는 경우 IsFullHouse에서 해당 버그를 복제 할 수 있습니다.
waxwing

AnyFullHouse ()는 테스트 케이스의 메소드입니다. 일반적으로 테스트 케이스를 TDD합니까? 또한, 존재 여부를 테스트하는 것보다 풀 하우스 (또는 다른 롤)의 임의 예제를 작성하는 것이 훨씬 간단합니다. 물론 테스트에 버그가있는 경우 프로덕션 코드에서 버그를 복제 할 수 있습니다. 그래도 모든 테스트에 적용됩니다.
tallseth

AnyFullHouse는 테스트 사례에서 "도우미"방법입니다. 그것들이 일반적인 도우미 메소드라면 테스트를 받아야합니다!
Mark Hurd

IsFullHouse정말로 그렇다면 반환 true해야 pairNum == trioNum 합니까?
recursion.ninja

2

테스트 할 때 고려해야 할 두 가지 주요 방법을 생각할 수 있습니다.

  1. 유효한 풀 하우스 세트에 대해 "일부"더 많은 테스트 사례 (~ 5)를 추가하고 동일한 양의 예상되는 오해 ({1, 1, 2, 3, 3}는 좋은 것입니다. 예를 들어 5 개는 잘못된 구현으로 "같은 + 쌍의 3"으로 인식됨). 이 방법은 개발자가 테스트를 통과하려는 것이 아니라 실제로 올바르게 구현한다고 가정합니다.

  2. 가능한 모든 주사위 세트를 테스트하십시오 (252 개의 다른 주사위 만 있음). 물론 이것은 당신이 예상되는 답이 무엇인지 알 수있는 방법이 있다고 가정합니다 (테스트에서 이것을이라고합니다 oracle.) 이것은 동일한 기능 또는 인간의 참조 구현 일 수 있습니다. 정말 엄격하고 싶다면 각 예상 결과를 수동으로 코딩하는 것이 좋습니다.

그것이 일어날 때, 나는 Yahtzee AI를 한 번 작성했는데, 물론 규칙을 알아야했습니다. 스코어 평가 부분에 대한 코드는 여기 에서 찾을 수 있습니다 . 구현은 스칸디나비아 버전 (Yatzy)을위한 것이며, 구현시 주사위가 정렬 된 순서로 제공된다고 가정합니다.


백만 달러짜리 질문은 순수한 TDD를 사용하여 Yahtzee AI를 도출 했습니까? 내 내기는 당신이 할 수 없다는 것입니다; 당신은 : 블라인드없는 정의에있는 도메인 지식을 사용하는
안드레스 F.

그래, 네 말이 맞아 이는 예상치 못한 충돌과 처리되지 않은 예외 만 테스트하려는 경우가 아니라면 테스트 케이스에 예상 출력이 필요한 TDD의 일반적인 문제점입니다.
ansjob

0

이 예제는 실제로 요점을 놓칩니다. 우리는 여기서 소프트웨어 디자인이 아닌 하나의 간단한 기능에 대해 이야기하고 있습니다. 조금 복잡합니까? 예, 당신은 그것을 분해합니다. 그리고 1, 1, 1, 1, 1에서 6, 6, 6, 6, 6, 6까지 가능한 모든 입력을 절대 테스트하지는 않습니다. 문제의 기능은 순서가 필요하지 않으며 조합, 즉 AAABB가 필요하지 않습니다.

200 개의 개별 로직 테스트가 필요하지 않습니다. 예를 들어 세트를 사용할 수 있습니다. 거의 모든 프로그래밍 언어가 내장되어 있습니다.

Set set;
set.add(a);
set.add(b);
set.add(c);
set.add(d);
set.add(e);

if(set.size() == 2) { // means we *must* be of the form AAAAB or AAABB.
    if(a==b==c==d) // eliminate AAAAB
        return false;
    else
        return true;
}
return false;

유효한 Yahtzee 롤이 아닌 입력을 받으면 내일이없는 것처럼 던져야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.