테스트 데이터에 실제 고객 정보를 쓰면 안 되는 이유

개발·QA 환경에 넣을 데이터가 필요할 때 가장 빠른 방법은 운영 데이터베이스에서 몇 건을 복사해 오는 것입니다. 그런데 그 순간부터 실제 사람의 이름과 연락처가 운영 환경 바깥으로 퍼지기 시작합니다.

결론부터 말하면 테스트에는 실재하지 않는 값을 넣어야 합니다. 다행히 "실제처럼 보이지만 절대 실재하지 않는 값"을 만드는 규칙은 상당 부분 표준으로 정해져 있어서, 지어낼 필요 없이 그대로 따라 쓰면 됩니다.

요약 ① 실데이터는 스테이징 DB·로그·버그 리포트·CI 아티팩트를 타고 복제되며, 한 번 퍼지면 어디까지 갔는지 되짚기 어렵습니다. ② 이메일과 도메인은 RFC 2606이 예약해 둔 이름을 씁니다. example.com·example.net·example.org.test·.example·.invalid·.localhost는 누구에게도 배정되지 않습니다. ③ 이름·주소는 후보 목록에서 무작위로 조합하고, UUID는 브라우저의 crypto.randomUUID()로 만들면 됩니다.

운영 데이터를 복사하면 어디까지 퍼지나

문제는 "복사해서 개발 DB에 넣었다"에서 끝나지 않는다는 점입니다. 그 데이터는 개발자가 의도하지 않은 경로로 계속 복제됩니다.

가장 흔한 복제 경로는 다섯 가지입니다.

  • 스테이징 DB 덤프 파일
  • 재현용으로 첨부한 버그 리포트
  • 로컬에서 찍어 채팅방에 올린 화면
  • CI가 남겨 두는 테스트 아티팩트
  • 저장소에 커밋된 시드(seed) 파일

여기에 하나가 더 붙습니다. 실제로 연결되는 값이라는 점입니다. 테스트 코드가 실수로 메일이나 문자를 발송하면, 받는 쪽은 실제 고객입니다.

개인정보를 어디까지 다뤄도 되는지는 국가·업종·계약에 따라 다릅니다. 이 글은 그 판단을 대신하지 않고, 실제 값이 섞였는지 확인하는 방법섞이지 않는 값을 만드는 방법만 다룹니다.

지금 쓰는 테스트 데이터에 실제 값이 섞였는지 확인하는 법

이미 굴러다니는 시드 파일부터 점검하는 편이 빠릅니다. 파일 하나를 열지 않고도 확인할 수 있는 항목이 있습니다.

1) 이메일 도메인을 전부 모아 봅니다. CSV·JSON 어느 쪽이든 터미널에서 한 줄이면 됩니다.

grep -oE '@[A-Za-z0-9._-]+' seed.csv | sort -u

여기서 회사 도메인이나 실제 메일 서비스 도메인이 나오면, 그 값들은 누군가에게 도달할 수 있는 주소입니다. 예약 도메인만 남아 있어야 안전합니다.

2) 전화번호가 실제 형식인지 봅니다. 무작위로 만든 번호라도 통신사에 개통된 번호와 겹칠 수 있습니다. 발송 테스트를 한다면 번호가 아니라 발송 경로 자체를 차단해 두는 편이 확실합니다.

3) 조합이 한 사람을 가리키는지 봅니다. 이름을 가려도 생년월일·주소·직장이 함께 있으면 특정 개인이 좁혀질 수 있습니다. 마스킹은 열 단위로 지우는 작업이지, 조합까지 지워 주지 않습니다.

4) 출처를 답할 수 있는지 봅니다. "이 파일 어디서 왔나요"에 즉답이 안 되면 운영 덤프에서 왔을 가능성이 큽니다.

실재하지 않는 값을 만드는 규칙

여기부터는 만드는 쪽입니다. 도구 없이 손으로도 충분히 가능합니다.

이메일·도메인은 예약된 이름을 씁니다

RFC 2606은 문서·예시용으로 example.com, example.net, example.org 세 개의 2차 도메인을 예약해 두었습니다. 별도 협의 없이 예시로 써도 되는 이름입니다.

최상위 도메인도 네 개가 예약돼 있습니다. .test는 DNS 관련 코드 시험용, .example은 문서·예시용, .invalid반드시 유효하지 않아야 하는 이름용, .localhost는 루프백용입니다.

그래서 테스트 계정의 이메일은 user001@example.com 처럼 만들면 됩니다. 실수로 발송돼도 실제 수신자가 없습니다.

이름·전화·주소는 후보 목록에서 조합합니다

여기엔 표준이 없습니다. 성·이름·시군구·도로명 후보를 배열로 두고 무작위로 뽑아 붙이면 그만입니다. 브라우저 개발자 도구(대개 F12) 콘솔에 아래를 붙여 넣으면 바로 나옵니다.

const SUR = ["김", "이", "박", "최", "정"];
const GIV = ["민준", "서연", "도윤", "하은", "지우"];
const pick = (a) => a[Math.floor(Math.random() * a.length)];
const p4 = () => String(Math.floor(Math.random() * 10000)).padStart(4, "0");
const rows = Array.from({ length: 10 }, (_, i) => ({
  id: i + 1,
  name: pick(SUR) + pick(GIV),
  email: "user" + String(i + 1).padStart(3, "0") + "@example.com",
  phone: "010-" + p4() + "-" + p4(),
}));
console.log(JSON.stringify(rows, null, 2));

한 가지 만들지 말아야 할 것이 있습니다. 주민등록번호·카드번호처럼 검증 규칙이 공개된 식별번호입니다. 형식을 맞춰 만들면 실제 발급된 번호와 겹칠 수 있고, 겹치는 순간 그건 더 이상 가짜 데이터가 아닙니다.

UUID는 브라우저가 만들어 줍니다

식별자가 필요하면 UUID가 편합니다. 콘솔에서 crypto.randomUUID() 를 실행하면 버전 4 UUID가 하나씩 나옵니다.

이 API는 보안 컨텍스트에서만 제공됩니다. https 페이지나 localhost 에서는 동작하고, 사내 IP로 띄운 http 주소에서는 함수가 없다고 나올 수 있습니다.

UUID는 전체 128비트이고, 버전 4는 그중 122비트가 난수입니다. 나머지 6비트는 버전 필드와 변형 필드로 고정됩니다(RFC 9562). 세 번째 덩어리가 항상 4로 시작하는 이유가 이 버전 필드입니다.

문제는 이 방법들을 매번 이어 붙여야 한다는 점입니다. 필드를 하나 더하거나 CSV로 바꾸려면 코드를 다시 손봐야 합니다.

저희 도구로 확인하기. 생성 개수(1~500)를 정하고 포함할 필드를 체크하면 JSON·CSV 두 형식으로 바로 나오고, 복사와 파일 다운로드 버튼이 함께 붙어 있습니다.

더미 데이터 생성기

설치·회원가입 없이 브라우저 안에서 바로 생성되며, 만들어진 데이터는 서버로 전송되지 않습니다.

도구가 만드는 필드는 12종입니다. 순번(id)·이름·성별·생년월일·나이·이메일·전화번호·주소·회사·직업·아이디·UUID이고, 처음에는 순번·이름·이메일·전화번호·주소 다섯 개가 켜져 있습니다.

"🎲 새로 생성" 버튼을 누를 때마다 완전히 다른 묶음이 만들어집니다. 목록에 주민등록번호·카드번호가 없는 건 앞에서 말한 이유 때문입니다.

만들 때 자주 어긋나는 지점

상황어떻게 하나
실제 발송(메일·문자) 테스트이메일 도메인을 example.com이나 .invalid로 바꾸고, 발송 경로 자체를 막습니다
실데이터 마스킹으로 대체조합으로 재식별될 수 있어, 처음부터 없는 값을 만드는 편이 단순합니다
보안용 난수가 필요할 때더미 데이터용 UUID는 표시용입니다. 토큰·비밀키에는 crypto.randomUUID() 같은 암호학적 난수 API를 씁니다
저장소에 커밋할 시드 파일사람 손으로 만든 파일인지, 운영 덤프인지 출처를 파일 주석에 남깁니다
스크린샷·발표 자료화면에 뜬 값이 생성된 값인지 눈으로 한 번 더 확인합니다

도구가 만드는 이메일 주소는 gmail.com·naver.com 같은 실제 서비스 도메인을 씁니다. 화면 목업처럼 "그럴듯해 보여야 하는" 용도에는 이쪽이 맞습니다.

다만 실제 발송이 일어날 수 있는 테스트라면 도메인 부분만 예약 도메인으로 치환한 뒤 쓰는 편이 안전합니다. CSV로 내려받은 뒤 이메일 열의 @ 뒷부분을 일괄 치환하면 됩니다.

정리

  • 운영 데이터를 테스트로 옮기면 DB 덤프·로그·리포트·아티팩트를 타고 계속 복제되고, 실제 수신자에게 도달할 수 있습니다.
  • 기존 시드 파일은 이메일 도메인 목록·전화번호 형식·필드 조합·출처 네 가지로 점검합니다.
  • 이메일은 RFC 2606이 예약한 example.com·example.net·example.org, 도메인은 .test·.example·.invalid·.localhost를 씁니다.
  • 이름·주소는 후보 목록 무작위 조합으로 충분하고, 식별자는 버전 4 UUID를 씁니다.
  • 주민등록번호·카드번호처럼 검증 규칙이 공개된 번호는 형식을 맞춰 만들지 않습니다.
더미 데이터 생성기

설치·회원가입 없이 브라우저 안에서 바로 생성되며, 만들어진 데이터는 서버로 전송되지 않습니다.

자주 묻는 질문

실제 데이터를 마스킹해서 쓰면 되지 않나요?

마스킹은 열 단위로 가리는 작업이라, 남은 열들의 조합까지 지워 주지는 않습니다. 이름을 가려도 생년월일·주소·직장·가입일이 함께 남아 있으면 특정 인물이 좁혀질 수 있습니다. 처음부터 실재하지 않는 값으로 만들면 이 판단 자체가 필요 없어져서, 결과적으로 손이 덜 갑니다.

생성된 전화번호로 실제 문자를 보내도 되나요?

권하지 않습니다. 010-으로 시작하는 무작위 번호는 형식이 실제 번호와 같아서 개통된 번호와 겹칠 수 있습니다. 발송 로직을 시험할 때는 번호를 바꾸는 대신 발송 어댑터를 테스트용 구현으로 교체하거나, 스테이징에서 외부 발송 자체를 차단해 두는 방식이 확실합니다.

이메일 도메인은 왜 굳이 example.com을 쓰나요?

RFC 2606이 example.com·example.net·example.org를 문서·예시용으로 예약해 두었기 때문입니다. 누구에게도 배정되지 않는 이름이라, 실수로 메일이 나가도 실제 사용자에게 닿지 않습니다. 절대 유효하지 않아야 하는 값이 필요하면 .invalid 최상위 도메인을 쓰면 됩니다.

생성한 데이터가 서버로 전송되나요?

아니요. 이 도구의 데이터 생성은 전부 브라우저 안에서 처리되며, 만들어진 레코드는 서버로 전송되거나 저장되지 않습니다. 복사·다운로드도 브라우저가 화면에 이미 만들어 둔 값을 그대로 내보내는 방식입니다.

가격 보기카톡 무료 상담