픽스처

Fixture

산출물

테스트를 돌리기 전에 미리 깔아 두는 상태와 데이터로, 매번 같은 조건에서 시작하게 만들려고 본문에서 떼어 따로 적어 둔 것입니다.

등장 배경

테스트 코드는 검증하는 부분보다 준비하는 부분이 훨씬 깁니다. "문서 세 건이 올라가 있고 사용자 두 명이 초대된 팀" 에서 권한을 확인하려면, 확인하는 줄은 한 줄인데 팀을 만들고 사용자 둘을 초대하고 문서 세 건을 넣는 줄이 스무 줄쯤 됩니다.

이 스무 줄을 테스트마다 다시 적던 시절이 있었습니다. 비슷한 테스트가 쉰 개면 비슷한 준비 코드도 쉰 벌이었습니다. 문제는 준비 코드가 제품을 따라 바뀐다는 점입니다. 페이지덱에서 태오가 문서에 소유자 필드를 하나 추가했을 때, 기능은 멀쩡한데 테스트 마흔 개가 한꺼번에 빨간불이 됐습니다. 마흔 곳에 적힌 "문서를 만든다" 가 전부 새 필드를 모르는 옛날 코드였기 때문입니다. 고장 난 것은 제품이 아니라 준비 코드였고, 태오는 반나절 동안 같은 수정을 마흔 번 했습니다.

읽는 쪽도 힘들었습니다. 서른 줄짜리 테스트에서 스물다섯 줄이 준비라면 무엇을 확인하는 테스트인지 알려면 끝까지 내려가야 합니다.

픽스처는 이 준비 덩어리를 테스트 본문에서 꺼내 이름을 붙이고 한 곳에 모아 둔 것입니다. 쉰 개의 테스트가 같은 한 벌을 불러 쓰니 제품이 바뀌어도 고칠 자리가 한 곳이고, 본문에는 확인하는 줄만 남습니다.

구성 항목

픽스처 하나는 이름과 데이터와 절차와 범위, 네 가지로 이루어집니다.

  1. 이름 — 이 상태가 무엇인지 부르는 말입니다. team_with_three_docs 처럼 적어 두면 테스트 본문에 이름만 나와도 무엇이 깔려 있는지 읽힙니다. data1 처럼 지으면 결국 정의를 찾아 들어가 읽어야 해서 떼어 놓은 이득이 사라집니다.
  2. 초기 데이터 — 테스트가 시작할 때 이미 존재하는 값입니다. 사용자 두 명, 문서 세 건, 각각의 권한과 생성 시각이 여기 들어갑니다. 코드로 적기도 하고 JSON 파일로 빼 두기도 합니다.
  3. 준비 절차와 정리 절차 — 데이터를 실제로 깔고 치우는 동작입니다. 데이터베이스에 값을 넣거나 테스트용 서버를 띄우는 일이 준비 쪽이고, 그것을 지우고 내리는 일이 정리 쪽입니다. 정리를 빼먹으면 앞 테스트가 남긴 문서 세 건이 다음 테스트에 그대로 남아, 한 개를 기대하던 테스트가 네 개를 보고 실패합니다. 혼자 돌리면 통과하고 전체를 돌리면 깨지는 테스트는 대개 여기가 원인입니다.
  4. 범위 — 이 준비를 얼마나 자주 다시 하느냐입니다. 테스트마다 새로 깔면 간섭이 없는 대신 느리고, 파일 하나나 전체 실행에 한 번만 깔면 빠른 대신 앞 테스트가 건드린 상태가 뒤로 넘어갑니다. 값을 읽기만 하는 준비는 한 번만 깔고, 값을 고치는 준비는 매번 새로 깝니다.

데이터가 조금씩 다른 여러 벌이 필요해지면 복사하지 말고 만드는 함수를 둡니다. 기본값을 정해 두고 바꾸고 싶은 값만 넘기는 방식입니다. "만료된 초대" 가 필요하면 만료 시각만 넘기고 나머지 열 개 필드는 기본값을 쓰니, 테스트 본문에 중요한 값 하나만 남습니다.

작성자와 독자

픽스처를 쓰는 사람은 그 테스트를 쓰는 개발자 본인이고, 처음부터 공용으로 만들지는 않습니다. 자기 테스트 안에 준비 코드를 적어 두었다가, 다른 테스트가 같은 상태를 필요로 할 때 공용 자리로 옮기는 순서가 보통입니다. 한 번밖에 안 쓰는 준비를 미리 공용으로 빼 두면, 두 번째 사용처가 생겼을 때 모양이 안 맞아 결국 다시 씁니다.

읽는 사람은 셋입니다. 같은 영역을 만지는 개발자는 새 테스트를 쓸 때 쓸 만한 픽스처가 이미 있는지부터 봅니다. 코드 리뷰를 하는 사람은 테스트 본문만 읽고도 전제를 알 수 있는지를 보고, 이름이 상태를 말해 주지 않으면 이 자리에서 걸립니다. QA 엔지니어는 자동 테스트가 어떤 상황을 깔고 검증하는지 확인해 사람이 직접 볼 자리를 그 바깥에서 고릅니다.

주인이 흐려지기 쉬운 자산이기도 합니다. 공용 픽스처 하나를 테스트 여든 개가 쓰고 있으면 필드 하나를 바꿨을 때 어디가 깨질지 알 수 없어, 결국 비슷한 것을 새로 하나 더 만듭니다. 그렇게 늘어난 픽스처는 이름만 다르고 내용이 겹칩니다. 공용으로 올릴 때 무엇을 보장하는 상태인지 한 줄로 적어 두면 나중 사람이 고쳐도 되는 값과 건드리면 안 되는 값을 구분할 수 있습니다.

실무 용례

"그 테스트 픽스처에 권한 필드 좀 추가해 주세요. 제 쪽에서 그 값이 있어야 돌아가서요."

공용 준비 데이터에 항목을 하나 늘려 달라는 요청입니다.

"픽스처가 너무 무거워요. 문서 200건을 깔고 시작하던데, 실제로 보는 건 두 건이잖아요."

준비 데이터가 필요 이상으로 커서 느려졌고 테스트가 무엇을 전제하는지도 안 보인다는 지적입니다.

"로컬에선 통과하는데 전체로 돌리면 깨져요. 픽스처 정리가 안 되는 것 같습니다."

앞 테스트가 남긴 데이터가 다음 테스트로 넘어가고 있다는 진단입니다.

페이지덱에서는 새 기능의 테스트를 쓸 때마다 이 단어가 나옵니다. 태오가 공유 링크 만료 테스트에서 "이미 만료된 링크가 있는 상태" 를 준비하려다, 비슷한 준비가 초대 쪽 테스트에 이미 있는 것을 발견하고 공용으로 올려 둘이 함께 쓰는 식입니다. 올릴 때는 그 픽스처를 쓰던 기존 테스트도 같은 풀 리퀘스트에 담습니다. 준비가 바뀌면 그것을 쓰던 테스트도 같이 바뀌어야 하기 때문입니다.

흔한 오해

실제 서비스와 비슷할수록 좋은 준비라고 생각하기 쉽습니다. 운영 데이터베이스를 그대로 복사해 깔면 놓치는 경우가 없을 것 같기 때문입니다. 실제로는 반대로 움직입니다. 문서 200건을 깔고 시작하는 테스트는 지속적 통합이 한 바퀴 도는 시간을 늘리고, 그보다 나쁜 것은 무엇을 전제하는 테스트인지 아무도 모르게 된다는 점입니다. 200건 중 어느 한 건에 기대 통과하고 있었다면 그 한 건이 바뀌는 날 원인을 찾는 데 하루가 갑니다.

한 번 만들어 두면 손댈 일이 없다고 여기는 것도 흔합니다. 제품 코드가 아니라 곁다리로 보여 관리 대상에서 빠지기 때문입니다. 그러나 이것도 제품을 따라 낡습니다. 필드가 늘고 기본값이 바뀌는데 준비 데이터가 옛날 모양으로 남아 있으면, 테스트는 현실에 없는 상태를 검증하며 계속 초록불을 냅니다. 실제로는 깨진 기능인데 테스트가 통과하는 상태는 테스트가 아예 없는 것보다 위험합니다. 없으면 사람이 직접 확인하기라도 합니다.

자주 헷갈리는 용어

용어무엇을 대신하는가픽스처와의 차이
목호출하면 정해진 답을 돌려주는 가짜 객체목은 테스트 도중의 동작을 대신하고 픽스처는 시작 시점의 상태를 만듭니다. 결제사에 요청을 보내는 대신 성공이라고 답하게 하는 것이 목이고, 결제할 문서와 사용자가 이미 있는 상태를 깔아 두는 것이 픽스처입니다

같이 보면 좋은 페이지

  • 테스트

    픽스처가 어떤 활동을 받치는 도구인지 전체 지형을 봅니다

  • 목

    테스트에서 진짜를 대신하는 또 다른 방식입니다

마지막 업데이트 2026-09-16