[프로젝트] 테스트 코드 중복 줄이기 : 픽스쳐(Fixture) 활용하기

nemo·2025년 8월 31일
post-thumbnail

▶️ 인사말

안녕하세요!! nemo입니다!! 🐢

하반기 공채 시즌이 왔습니다!!
자소서 준비하고 프로젝트도 마무리 단계다 보니 할게 많네요

조금은 정신이 없지만 이번주도 열심히 해보겠습니다!!

▶️ 개요

테스트 코드를 짜다 보면 똑같은 코드를 여러번 쓰게 됩니다

특히 이번 프로젝트는 한명의 사용자(member)는 여러개의 그룹(community)에 들어갈 수 있고
그룹(community)에 들어가 참여자(associate)가 될 수 있습니다

(대...충 이런 느낌...)

모든 서비스를 이용하기 위해서는 참여자(associate) 상태여야 하기 때문에 테스트 코드 하나마다
member 생성 -> community 생성 -> associate 생성을 해줘야 합니다

		Member member = Member.builder()
			.name("example")
			.email("example@example.com")
			.kakaoId(123L)
			.birthday(LocalDate.of(1999, 1, 1))
			.build();
		memberRepository.save(member);

		Community community = Community.builder()
			.member(member)
			.name("example")
			.build();
		communityRepository.save(community);

		Associate associate = Associate.builder()
			.community(community)
			.member(member)
			.nickname("example")
			.build();
		associateRepository.save(associate);

이렇게 작성하면 매 테스트마다 동일한 도메인 생성 코드가 반복되면서 테스트가 장황해지고, 유지보수성이 떨어집니다

▶️ 픽스쳐(Fixture) 도입하기

🟢 픽스쳐(Fixture)란?

테스트 코드에서 픽스처(Fixture) 는 테스트를 실행하기 위해 필요한 고정된 환경이나 데이터를 말합니다

소프트웨어 테스팅 일반 정의:
→ “테스트를 반복적으로 실행할 수 있도록 일정한 상태로 맞춰 놓은 준비물.”

단위/통합 테스트에서의 관점:
→ “테스트가 실행되기 전에 필요한 객체, 데이터, 환경을 미리 준비해둔 것.”

예를 들어, 회원 가입 테스트를 하려면 기본 회원 객체가 필요합니다. 이때 매번 new Member(...) 코드를 작성하는 대신, 미리 준비된 생성 로직(픽스처) 을 두고 가져다 쓰면 됩니다.

🟢 예시 코드

Member

public class MemberFixtures {

	private static final String NAME = "김싸피";
	private static final String EMAIL = "example@naver.com";
	private static final LocalDate BIRTHDAY = LocalDate.of(1999, 1, 1);
	private static final Long KAKAO_ID = 1L;

	public static Member member() {
		return Member.create(NAME, EMAIL, BIRTHDAY, KAKAO_ID);
	}
}

Community

public class CommunityFixtures {

	private static final String NAME = "community";
	public static Community community(Member member) {
		return Community.builder()
			.name(NAME)
			.member(member)
			.build();
	}
}

Associate

public class AssociateFixtures {

	private static final String NICKNAME = "nickname";
	public static Associate associate(Member member, Community community) {
		return Associate.builder()
			.nickname(NICKNAME)
			.member(member)
			.community(community)
			.build();
	}
}

픽스처(Fixtures) 클래스를 따로 만들어, 테스트에서 필요한 엔티티를 쉽게 생성하도록 합니다

그럼 픽스처를 사용하면 원래 코드는 어떻게 바뀔까요??

🟢 픽스처 적용 후 테스트 코드

		Member member = MemberFixtures.member();
		memberRepository.save(member);

		Community community = CommunityFixtures.community(member);
		communityRepository.save(community);

		Associate associate = AssociateFixtures.associate(member, community);
		associateRepository.save(associate);

매번 객체를 생성할 때 마다 builder를 사용해 값을 넣어줄 필요 없이 Fixture 매서드 호출로 간단하게 테스트용 객체를 만들 수 있습니다

🟢 픽스처 확장

지금까지는 기본 값으로만 객체를 생성하는 픽스처를 봤습니다
하지만 실제 테스트를 작성하다 보면, 같은 도메인이라도 특정 속성만 다르게 주고 싶을 때가 많습니다

예를 들어, 이름만 다른 Member를 여러 명 생성해야 한다고 해봅시다
이때도 매번 builder를 직접 호출하기보다는, 확장 메서드를 픽스처에 추가하면 더 깔끔해집니다

public class MemberFixtures {
    private static final String DEFAULT_EMAIL = "example@naver.com";
    private static final LocalDate DEFAULT_BIRTHDAY = LocalDate.of(1999, 1, 1);
    private static final Long DEFAULT_KAKAO_ID = 1L;

    // 기본 회원 생성
    public static Member member() {
        return Member.create("김싸피", DEFAULT_EMAIL, DEFAULT_BIRTHDAY, DEFAULT_KAKAO_ID);
    }

    // 이름만 바꿔서 회원 생성
    public static Member memberWithName(String name) {
        return Member.create(name, DEFAULT_EMAIL, DEFAULT_BIRTHDAY, DEFAULT_KAKAO_ID);
    }

    // 이메일만 바꿔서 회원 생성
    public static Member memberWithEmail(String email) {
        return Member.create("김싸피", email, DEFAULT_BIRTHDAY, DEFAULT_KAKAO_ID);
    }
}

이렇게 확장해두면 테스트에서 아주 직관적으로 사용할 수 있습니다.

    Member member1 = MemberFixtures.memberWithName("홍길동");
    Member member2 = MemberFixtures.memberWithName("임꺽정");

    memberRepository.saveAll(List.of(member1, member2));

픽스처를 너무 고정적으로만 쓰지 말고, 필요하다면 유연하게 확장해서 사용하는 게 좋습니다
이렇게 하면 테스트 코드가 훨씬 더 읽기 쉽고, “의도에 맞는 데이터”를 빠르게 준비할 수 있습니다

▶️ 픽스처의 사용

🟢 장점

중복 제거: 테스트마다 같은 도메인 생성 로직을 반복할 필요 없음
ex) new Member(...) → MemberFixtures.member() 로 치환

가독성 향상: 테스트 코드에서 “무슨 객체를 준비했는지” 보다 “무엇을 검증하는지” 에 집중할 수 있습니다
테스트 본연의 의도가 더 잘 드러나므로, 읽는 사람 입장에서 이해하기 훨씬 쉬워집니다

유지보수 용이: 도메인 생성 방식이 변경되더라도 픽스처 클래스만 수정하면 전체 테스트에 반영됩니다
테스트 코드가 수십, 수백 개여도 일일이 고칠 필요가 없으니 유지보수 비용이 크게 줄어듭니다

확장성: 상황별로 조금씩 다른 데이터를 만들어야 할 때, 메서드를 확장하면 됩니다
이렇게 하면 “테스트 시나리오에 맞는 데이터”를 직관적으로 준비할 수 있어 편리합니다
ex) MemberFixtures.memberWithName("홍길동")

이런 장점들 덕분에, 픽스처는 테스트 코드의 품질을 한 단계 끌어올려주는 핵심 도구라고 할 수 있습니다

🔴 단점 및 주의점

픽스처는 테스트 코드를 간결하게 해주지만, 몇 가지 주의할 점도 있습니다.

픽스처 남용: 너무 많은 픽스처를 만들면 오히려 관리가 어려워지고, 어떤 데이터가 생성되는지 파악하기 힘들어질 수 있습니다

유연성 부족: 항상 같은 값만 반환하는 픽스처는 상황에 따라 다른 데이터를 만들어야 하는 테스트에 적합하지 않을 수 있습니다
이 경우에는 Test Data Builder 패턴이나 Factory 메서드와 함께 사용하는 게 더 효과적입니다

가독성 역효과: 픽스처 내부 로직이 복잡해지면, 테스트 코드를 읽을 때 “이 객체가 어떤 상태인지” 바로 이해하기 힘들어질 수 있습니다

▶️ 마무리

테스트 코드를 작성할 때 픽스처(Fixture) 를 잘 활용하면 불필요한 중복을 줄이고, 훨씬 깔끔하고 유지보수하기 좋은 코드를 만들 수 있습니다

다만 무조건 픽스처로만 해결하려 하기보다는, 상황에 따라 Builder 패턴이나 Factory 메서드 같은 다른 방법과 병행하는 게 더 좋은 경우도 있습니다

저도 이번 프로젝트를 진행하면서 픽스처를 적극적으로 도입해보고 있는데, 확실히 테스트 코드가 읽기 편해지고 관리하기 수월해졌습니다

앞으로 테스트 작성할 때 꼭 한 번 써보시길 추천드립니다!

긴글 읽어주셔서 갑사합니다!! 🐢

profile
거북이 개발자

0개의 댓글