BDD와 TDD의 차이

알림: 이 포스트는 BDD 연작 시리즈 중 첫번째입니다.

BDD(Behaviour-Driven Development)TDD(Test-Driven Development)는 애자일 소프트웨어 개발 방법론에서 가장 널리 쓰이는 것들이다. 사실 xDD(X-Driven Development)라고 해서 수많은 X가 있긴 하지만 이들 중 거의 대부분은 TDD를 기반으로 한다. 그렇다면 BDD와 TDD는 어떤 차이가 있을까?

StackExchange의 이 질문과 대답에 따르면, BDD와 TDD는 거의 차이가 없다. 차이가 있다면 TDD는 테스트 자체에 집중하여 개발하는 반면, BDD는 비즈니스 요구사항에 집중하여 테스트 케이스를 개발한다는 것이다. Dan North의 글 Introducing BDD는 BDD에 대한 충분한 설명을 볼 수 있다. 이 글은 이홍주님이 한국어로도 번역해 놓았다.

좀 더 간략하게 BDD에 대해 설명을 하자면, BDD는 테스트 케이스를 작성함에 있어서 좀 더 자연어에 가깝게 작성한다는 것이다. 대표적인 것이 바로 User Story 기법이 있다. 여기글을 참고하여 아래 User Story를 살펴보도록 하자.

위와 같이 User Story를 작성한다고 하면 전형적인 As a ..., I want ..., So that ... 구문을 따르고 있다. 이렇게 비즈니스 요구사항이 만들어진다면 이것을 바탕으로 시나리오를 아래와 같이 만들 수 있다.

이렇게 만들어진 시나리오를 바탕으로 유닛테스트를 작성하면 그것이 바로 BDD를 적용한 소프트웨어 개발이 될 것이다. 이어지는 포스트에서는 어떻게 이 User Story가 유닛테스트로 변환이 되는지에 대해 설명한다.

You might be interested in...

One Pingback/Trackback

  • Jin-Wook Chung

    먼저 좋은 글 공유 감사드립니다. 글을 읽다가 의문점이 하나있어서 이렇게 댓글 남깁니다.

    BDD로 우리는 unit-testing 뿐 만아니라, integration-testing, acceptance-testing과 같은 테스트를 수행할 수 있습니다. 이 관점에서 본다면, BDD는 unit-testing과 독립적인 것으로 봐야 할 것 같은데, 본문에서 “이렇게 만들어진 시나리오를 바탕으로 유닛테스트를 작성하면”(본문 맨 마지막 부분) 라고 쓰여있어서, BDD와 unit-testing관계를 어떻게 봐야할지 조금 혼돈이 오네요.

    • 단위테스트, 통합테스트, 인수테스트 모두 결국은 단위테스트를 기반으로 하는 것인데요, 제가 보는 관점을 말씀드리자면, 단위테스트는 메소드별로 테스트를 하기 때문에 해당 메소드 이외의 내용은 거의 대부분 mocking을 해서 사용합니다. 따라서, 해당 메소드 이외의 기능에는 관심이 없습니다. 통합테스트는 메소드별로 테스트를 한다는 것에는 변함이 없으나 mocking을 하지 않고 실제 비즈니스 로직에 중점을 두어 진행합니다. 인수테스트는 고객이 진행하는 테스트이니 사용자가 어떤 행위를 했을 때 어떤 결과가 나오는가에 중점을 두고 있죠. BDD는 사실 그래서 인수테스트를 개발자 관점에서 진행하는 것이기도 합니다.

      이건 어디까지나 제 관점이니 다르게 생각하시는 부분이 있다면 말씀해 주시면 좋겠네요.

  • Jin-Wook Chung

    우선 제 생각을 정리해서 말씀드릴 필요가 있겠네요.

    1. 제 생각에는 TDD와 BDD가 테스트를 언제(구현 후, 구현 전) 작성할 것인가를 말해 주는 것이라면,

    2. 단위테스트, 통합테스트, 인수테스트는 얼마만큼 테스트할 것인가를 말해 주는 것이라 생각합니다.

    따라서, TDD방법으로 단위테스트를 할 수도 있고, 인수테스트(이 경우 ATDD 함)를 할 수도 있다고 생각합니다. 물론 BDD도 마찬가지일 것입니다. 그래서 저는 1번과 2번의 관계는 독립이라고 생각합니다.

    다만, 인수테스트 작성에 있어 TDD보다 BDD로 작성된 것을 많이 보았습니다. 그렇다고 TDD방식으로 인수테스트를 작성하지 못한다는 말은 아닐 것입니다.

    본 문에서 “User uses wrong password” 시나리오 자체를 하나의 테스트로 생각해야 하지 않을까 합니다. 해당 시나리오는 단위테스트보다는 범위가 큰 통합이나 Funtional테스트에 가깝다고 생각됩니다. 그런데 글 하단에서 단위테스트란 말 나오는데 그 의미를 잘 모르겠습니다.

    정확히 살펴보지 않아서 잘 모르겠지만 SpecFlow(with NUnit)는 실제 아래와 비슷하게 작동하지 않을까 생각되는데요.

    [Test]

    public void UserUsesWrongPassword()

    {

    Given…();

    When….();

    Then….();

    }

    NUnit으로 단위테스트처럼 동작하지만, 통합 또는 Funtional테스트를 했다고 생각해야하지 않을까요?

    혹 서로 같은 얘기를 달리 말하고 있는 건 아니지 모르겠습니다…

    • 좋은 말씀 주셔서 고맙습니다. 그런데, 제가 지식이 미천해서 그런지 말씀하신 바를 잘 이해하지 못하겠습니다. 특히 번호를 매겨주신 부분에 대한 내용을 이해하기가 어렵네요.

      다만 말씀드릴 수 있는 부분은 SpecFlow를 한 번 굴려보신다면 위에 언급하신 그런 코드가 나오지 않는다는 것을 아실 수 있을 겁니다. 각각의 시나리오에서 Given, When, Then 부분이 각각 하나의 메소드가 되어 나오기 때문에 단위테스트, 통합테슽, 인수테스트 모두에서 사용할 수 있습니다.

      • Jin-Wook Chung

        “제가 지식이 미천해서 그런지 말씀하신 바를 잘 이해하지 못하겠습니다. ”

        송구합니다. 제가 괜히 혼란만 가져다준 게 아닌가 심려됩니다.

        “특히 번호를 매겨주신 부분에 대한 내용을 이해하기가 어렵네요.”

        제가 저의 생각을 잘 설명을 못 드린것 같습니다. 또 다음에 좋은 기회가 있다면 더 좋은 말씀 나누었으면 합니다.

        “다만 말씀드릴 수 있는 부분은 SpecFlow를 한 번 굴려보신다면 위에 언급하신 그런 코드가 나오지 않는다는 것을 아실 수 있을 겁니다. 각각의 시나리오에서 Given, When, Then 부분이 각각 하나의 메소드가 되어 나오기 때문에 단위테스트, 통합테슽, 인수테스트 모두에서 사용할 수 있습니다.”

        제가 위에서 말씀드린 코드는 실제 생성된 코드를 말씀 드린 것이 아니라 SpecFlow(NUnit)에서 내부적으로 이렇게 동작하지 않을까하는 생각에서 말씀드린 것이었습니다. 실제로 살펴보니 이렇게 작동하는 것을 확인할 수 있었습니다. 아래링크는 SpecFlow에서 제공하는 example로 볼링KATA의 한 시나리오에 대해서 SpecFlow(NUnit)를 통해서 생성된 코드입니다. 코드에서 한 시나리오를 NUnit을 통한 하나의 테스트로 취급하고 있다는 것을 확인할 수 있었습니다.

        https://github.com/techtalk/SpecFlow-Examples/blob/master/BowlingKata/BowlingKata-Nunit/Bowling.Specflow/ScoreCalculation.feature.cs#L56-L71

  • Pingback: [2016-12-07] 4차 산업혁명, 인공지능 그리고 웹 | CCL FREE()