ATDD 는 무엇인가? ATDD 클린코드

최근 개발자라면 많이 듣는 것 중 하나가 TDD, 테스트 주도 개발입니다. ATDD는 Acceptance 즉, 인수 테스트를 의미합니다. 오늘 다룰 내용은 인수 테스트 주도 개발(ATDD)에 대한 내용입니다.

ATDD Cycle
ATDD 는 무엇인가? ATDD 클린코드 8

이런 상황 있지 않은가요?

개발을 하다 보면 요구사항 분석이 필수로 들어갑니다. PM이나 기획에서 넘어온 요구사항을 파악하고, 고객이 어떤 기능을 원하는 것인지 기획서를 보고 파악합니다. 그리고 파악한 내용을 토대로 기능을 개발하고 고객에게 나가게 됩니다.

다행히 TDD가 보급되면서 가능하다면 테스트 코드를 작성하고, 테스트를 돌려봅니다. 테스트는 개발자가 정해둔 조건에 따라 동작하며, 기존의 기능을 수정하더라도 테스트를 통해 빠르게 검증이 가능합니다.

하지만 이 테스트는 개발자 관점의 테스트입니다. 기획자나 PM이 설정한 Use Case와는 다른 테스트를 진행합니다. 개발자는 요구사항에 맞춰 자신의 판단에 의존해서 테스트를 작성합니다. 여기에는 사용자 관점이 빠져있습니다. 가장 고객과 접점이 많은 기획자나 PM이 정해준 Use Case로 테스트로 하면 원하는 방향대로 테스트가 진행되지 않습니다.

그렇다면 어떻게 테스트를 해야 할까요?

가장 좋은 방법은 처음부터 다양한 관점을 하나로 모아 테스트를 구성하는 것입니다. 기존의 TDD는 이러한 요구사항을 충족시키지 못했습니다. 서로 다른 관점의 차이로 테스트를 하더라도 원하는 결과가 나오지 않았고, 불필요한 테스트 코드를 양성했죠. 여기서 나온 방법론이 ATDD입니다. 이제 ATDD에 대해 알아보죠.

ATDD(Acceptance Test Driven Development)란?

ATDD(인수 테스트 주도 개발)은 다양한 관점을 가진 사람들(고객, 개발자, 기획자 등등)이 함께 협업하기 위한 애자일 방법 중 하나입니다. ATDD의 가장 큰 목적은 요구 사항을 명확하게 하는 것이며, 모든 팀원이 요구사항에 대해 공통적인 이해를 통해 개발을 진행하는 방법입니다.

기존 TDD와 가장 큰 차이점은 구현할 대상에 대해 고객 관점에서 이해하고 개발자가 테스트를 구현한다는 점입니다. 인수 테스트를 작성한 후 테스트 코드를 완성합니다. 

그다음 테스트를 통과했다면 기능 개발은 끝난 것이죠. 또한, 고객 입장에서 본인이 생각한 상황에서 오류가 없기 때문에 이슈가 발생했다면 정말 예상하지 못한 케이스에 대한 이슈가 됩니다. 이에 대해서는 개발자가 빠른 대응이 가능하며, 해당 이슈가 발생한 상황에 대해 테스트를 만들어가면서 더욱 견고한 코드를 만들 수 있습니다.

개발 합의 과정
ATDD 는 무엇인가? ATDD 클린코드 9

ATDD 깊게 알아보기

앞서 인수 테스트는 고객의 관점에서 테스트를 작성한다고 했습니다. 그렇기 때문에 인수 테스트에서 가장 중요한 것은 고객(기획자)입니다. 하지만 중요하다고 다른 사람들이 중요하지 않다는 것은 아닙니다. ATDD는 결국 함께하는 팀원들의 합의를 이끌어 내기 위한 방법론입니다. 그렇기 때문에 서로가 보는 관점을 맞추는 것이 중요합니다.

이 관점을 맞추는 과정을 통해서 산출되는 결과물이 사용자 스토리입니다. 그리고 이 사용자 스토리를 기반으로 인수 조건을 도출합니다. 도출된 인수 조건은 개발자가 좀 더 고객이 원하는 사항을 명확히 이해하고 테스트 코드를 만들 수 있습니다. 테스터 또한 고객의 입장에서 테스트를 정교하게 할 수 있게 됩니다.

결국 같은 수준으로 이해하기라는 공통된 목적을 가지고 ATDD를 구현하게 됩니다.

ATDD의 장점

  • 개발자, 이해관계자 및 제품 개발에 참여하는 모든 구성원 간의 이해도가 올라갑니다.
  • 개발된 제품이 사용자의 요구와 기대를 충족하는지 확인하는데 도움이 됩니다.
  • 요구 사항이 발전함에 따라 제품 개발이 빠르게 반복될 수 있습니다.
  • 한번 개발된 테스트는 새로운 사람이 오더라도 빠르게 파악할 수 있습니다.
  • 사용자 입장에서 만든 테스트이기 때문에 개발자가 이슈 파악 및 대응이 빠릅니다.

ATDD의 단점

  • 새로운 기능을 구현하기 전에 인수 테스트를 작성하고 실행해야 하기 때문에 시간이 많이 걸립니다.
  • 요구사항이 복잡하거나 지속적이고, 빠르게 변화하는 상황에서는 구현이 어렵습니다.
  • 이해관계간의 협의가 많이 필요합니다. 개발자 혼자서 작업하는 것이 아닌 이해 관계자 전부가 참여해야 하기 때문에 의견 충돌 및 협의에 많은 시간이 소요될 수 있습니다.
  • 추가적인 업무를 해야 할 수 있습니다.

ATDD 프로세스

ATDD는 4가지 행위와 4가지 산출물, 하나의 결과물을 가지고 있습니다.

4가지의 행위는 Discuss, Distill, Develop, Demo로 구성됩니다. 산출물은 User Story, Acceptance Criteria, Tests, Working Software로 구성됩니다. 결과물은 Business Value를 생성합니다.

ATDD Cycle
ATDD 는 무엇인가? ATDD 클린코드 10

사용자 스토리 작성하기

사용자 스토리는 who, why, what을 기준으로 작성합니다. 사용자 스토리는 ATDD를 만들기 위한 초석으로 가장 중요한 사용자 경험을 설명합니다. 사용자가 어떤 환경에서 어떤 생각으로 행동하는지 분석하여 스토리를 작성합니다.

사용자 스토리가 제대로 작성되면 ATDD의 행위를 작성하는데 도움이 됩니다. 특히, 의미 없는 테스트 코드를 작성하는 것을 방지하고, 정확한 상황을 인지하고 개발자가 코드를 작성할 수 있게 됩니다.

사용자 스토리의 예시는 다음과 같습니다.

처음 화면에 들어온 사용자는 제품을 검색하고 싶습니다.

Discuss

  • 사용자 스토리를 바탕으로 예시를 만들고, 인수 조건을 도출하는 과정입니다.
  • 비즈니스 이해 관계자와 함께 협의를 시작하는 단계입니다.
  • 사용자 스토리에서 나온 내용을 좀 더 구체화하는 작업을 합니다.
  • 이를 통해 테스트 자동화를 위해 전반적인 관점을 통일시키는 과정입니다.
  • 결과로는 인수 조건이 나옵니다.
    • 제품을 보기 위해서는 로그인이 필요합니다.
    • 회원 가입을 안 했다면 회원 가입 페이지로 안내해야 합니다.
    • 회원 가입 시 쿠폰을 제공해야 합니다.
  • 각 유스케이스를 작성하며, 사용자 스토리를 기반으로 만들어집니다.
  • 유스케이스는 고객과 개발자가 함께 바라보는 기능 정의서입니다.
  • 만약 대여서비스를 만든다고 가정합니다.
    • 책을 반납합니다. 고객은 책을 반납하는 기능을 요구합니다. 개발자는 해당하는 기능을 코드로 구현합니다.
    • 책을 반납하고, 재고를 맞춥니다. 관리자가 반납받은 책에 대한 재고를 자동적으로 맞춰주길 희망합니다. 개발자는 관리자가 요구하는 데로 앞서 반납받은 책을 토대로 재고를 맞춰주는 코드를 작성합니다.
  • 이런 단계를 걸쳐 인수 조건을 만들어갑니다.

사용자 시나리오는 사용자와 시스템 간의 교류를 단계적으로 나타냅니다. 유스케이스는 시스템의 기능적인 요구사항을 잡아냅니다.

Distill

앞서 결정된 인수 조건을 통해 인수 테스트를 작성합니다.

사용자 관점을 나타내는 인수 테스트는 요구 사항 형태로 작동하며, 시스템이 의도 한대로 작동하는지 확인하는 방법으로도 사용됩니다.

테스트는 Given-When-Then 형식으로 작성합니다.

Given <설정> 
When <이벤트나 동작> 
Then <예상되는 결과>

위 코드와 같이 테스트 코드 구조를 작성하게 됩니다.

Given은 선처리 조건(Pre-condition), When은 주 경로(Main Course), Then은 후처리 조건(Post-condition)으로 이야기할 수 있습니다.

여기서 작성하는 인수테스트는 다음과 같이 작성될 수 있습니다.

복권 프로세스 정리
    * [ ] 복권을 구매한다.
    * [ ] 입력 값으로 복권 구입 금액, 복권 리스트를 입력 받는다.
    * [ ] 구입 금액이 1000미만이거나 10000으로 나누어 떨어지지 않거나 숫자가 아닐 경우, 예외를 발생시킨다. (복권 1장 가격은 10000원)
    * [ ] 구매한 복권에는 당첨여부가 이미 등록되어 있다. 제대로 당첨, 미추천, 일치가 나오는 지 확인한다.
		* [ ] 100000번을 돌려 당첨 확률이 근접하게 나오는지 확인하다. 오차율은 당첨확률의 1/10 이상 차이나지 않는다.
    * [ ] 회차별 구매 내역과 구매한 복권들이 DB에 저장된다.
    * [ ] 복권 결과는 DB에 등록된다.
		* [ ] 회차 당첨이 없다면 관리자에게 알림이 가야한다.
  * [ ] 복권의 회차는 매주 월요일 오후 7시 자동으로 증가한다.
  * [ ] 관리자는 회차별로 당첨 개수를 지정할 수 있다.
    * [ ] 당첨 확률은 최대 0.01%까지 설정할 수 있으며, 그 이상을 넘어가면 예외를 발생시킨다.
    * [ ] 당첨 확률이 0%면 재입력 시킨다.
		* [ ] 매주 수요일 오후 10시전까지 입력이 완료되어야 하며, 입력되지 않았다면 알림이 관리자에게 알림이 가야한다.
		* [ ] 매주 목요일 오후 2시까지 입력되지 않는다면 이번 회차는 무시한다.
  * [ ] 복권 당첨 결과를 조회한다.
    * [ ] 결과에는 미추첨, 낙첨, 일치가 있다.
    * [ ] 미추첨이란, 현재 시간이 아직 해당 회차의 당첨결과 조회 가능 시간(매주 월요일 오후 7시)이 되지 않았거나 아직 당첨번호가 입력되지 않은 상태이다.

복권 프로세스를 간략히 정리한 인수 테스트 내용입니다.

이 내용을 기준으로 테스트를 구현할 수 있으며, Jest를 기준으로 코드를 작성하면 아래와 같이 작성할 수 있습니다.

describe('복권 프로세스 정리', () => {
	beforAll(() => {});
	describe('복권을 구매한다.', () => { 
		it('입력 값으로 복권 구입 금액, 복권 리스트를 입력 받는다.', () => {

		});

		it('구입 금액이 1000미만이거나 10000으로 나누어 떨어지지 않거나 숫자가 아닐 경우, 예외를 발생시킨다. (복권 1장 가격은 10000원)', () => {

		});

		// ...
	});

	describe('복권의 회차는 매주 월요일 오후 7시 자동으로 증가한다.', () => {});
	describe('관리자는 회차별로 당첨 개수를 지정할 수 있다.', () => {
		it('당첨 확률은 최대 0.01%까지 설정할 수 있으며, 그 이상을 넘어가면 예외를 발생시킨다.', () => {
		
		});

		// ...
	});
));

위와 같은 형태로 작성합니다. 그렇게 되면 아래와 같은 결과가 나옵니다.

Test Result
ATDD 는 무엇인가? ATDD 클린코드 11

이 테스트 결과를 본다면 어떤 이해관계자가 보더라도 테스트를 이해할 수 있게 됩니다. 안에 구현된 자세한 코드는 개발자만 알 수 있더라도, 테스트 결과만 보더라도 이해 관계자가 원하는 테스트를 수행했다는 것을 알 수 있습니다. 자세한 코드 내용은 개발팀 내부에서 코드 리뷰를 통해 단단하게 만들 수 있습니다.

Distill 단계에서 인수테스트까지 작성했다면 다음 단계로 넘어갈 수 있습니다.

Develop

실질적인 개발과 문서 작업을 병행하는 단계입니다.

앞서 인수테스트는 테스트 시나리오를 작성한 단계이기 때문에 아직 테스트 코드는 작성하지 않았습니다.

그렇기에 TDD로 개발을 시작하면서 문서화를 진행합니다.

  • 문서화
    • 문서화는 함께 작업하는 개발자 간의 소통을 원활하게 합니다.
    • 문서화는 필수는 아니지만 필요에 의해 작성하며 기준을 정해야 합니다.
  • TDD 개발
    • 인수 테스트 기반으로 하나씩 기능 개발을 진행합니다.
    • 중간중간 변경이 필요하다면 빠르게 변경 후 이해 관계자에게 전파합니다.
      • 변경은 개발 과정에서 필수로 발생하기 때문에 어렵게 생각하지 말고 전파합니다.
      • 개발자만 변경하지 않습니다. 기획자나 고객이 요청할 수도 있습니다.
    • 결과물 – 완성된 프로그램
ATDD 프로세스
ATDD 는 무엇인가? ATDD 클린코드 12

Demo

인수 테스트에 기반하여 작성된 테스트 코드가 정상적으로 작동된다면 해당 작업은 완료가 됩니다.

추후 해당 작업에 참여하지 않은 개발자도 어떤 기능인지, 어떤 조건으로 코드를 작성했는지 알기 쉽습니다.

또한, 새로운 이해관계자가 오더라도 기존에 만들어 놓은 문서들과 인수 테스트를 보면서 기능 파악을 빠르게 할 수 있습니다.

인수 테스트 완료 개수는 PM이나 기획자가 개발자의 개발 완료 상태를 파악하는 데 쉽습니다. 테스트가 통과된 기능들은 개발 완료로 볼 수 있기 때문입니다.

인수 테스트가 완료되더라도 추가적인 조건들과 확장해서 문제를 해결해야 하는 것이 있습니다. 그런 문제들은 심각한 내용이 아니라면 일정 조정을 통해 작업을 진행할 수 있습니다.

TDD 정의

ATDD 정리

TDD는 많은 개발자들이 중요하게 여기고 있는 가치 중 하나입니다. 그러다 보니 많은 테스트 코드를 작성하면서 안정성 높은 코드를 작성하려고 합니다. 그중에서도 ATDD는 개발자만 하는 것이 아닌 다른 이해관계자들과 함께하는 점에서 테스트 코드 작성을 하나의 팀이 만든다는 점에서 좋은 방법론이라 보고 있습니다.

다만, 앞서 말했던 것처럼 단점이 확실하기 때문에 무조건적인 도입은 지양해야 합니다. 필요한 곳에 제대로 활용한다면 앞으로의 개발자의 삶이 좀 더 편안해지지 않을까 생각해 봅니다.

실무에서 도입할 때는 익숙해지기 위한 시간과 다양한 환경들이 있겠지만 융통성 있게 하나씩 도입하면서 확장해 나가면 좋을 것 같습니다.

함께보면 좋은 글

참고 사항

ATDD는 무엇인가?

https://mslim8803.tistory.com/58

https://data-make.tistory.com/724

https://www.simplilearn.com/agile-acceptance-test-driven-development-article

https://testomat.io/blog/atdd-vs-tdd-understanding-the-key-differences/

https://boorownie.github.io/1

Leave a Comment