


확장 가능한 Go 서비스에 기능을 더하고 설정이 덮어써져도 통과하는 테스트 쓰기
하위 빌드가 이름이나 설정을 바꾸는 Go 서비스를 고칠 때 사용한다. 로그에 트레이스 컨텍스트를 남기고, 새 도구를 알맞은 그룹에 등록하며, 설정이 덮어써진 상태에서도 공개 동작을 테스트하고, 생성되는 문서를 업데이트한다.
이 AI 규칙을 사용하려면
## 편집 전에 변경을 맡는 패키지 찾기
코드를 수정하기 전에 변경 사항을 분류하고 기준 원천을 찾는다.
- 명령 진입점, 도메인 패키지, 구성 계층, 전송 및 권한 부여 계층, 프로토콜 구현, 출력 계층, 제공 기능 레지스트리, 버전 메타데이터를 식별한다.
- 비즈니스 로직은 명령 연결부나 배포 래퍼가 아니라 이를 소유한 소스 패키지에 둔다.
- 언어 패키지와 설치 프로그램 디렉터리를 가벼운 바이너리 배포 어댑터로 취급하고, 패키징 또는 버전 작업을 할 때만 변경한다.
- 영향을 받는 영역을 관할하는 빌드 정의, 테스트 구성, 인접 구현, 사용자 대상 문서를 읽는다.
- 편집하기 전에 사람이 작성한 소스와 생성 파일 및 빌드 산출물을 구분한다.
- 영향을 받는 모든 핸들러, 공개 타입, 등록 지점, 구성 경로, 테스트, 문서, 패키지 표면을 나열한다.
병렬 구조를 새로 도입하지 말고 저장소에 확립된 배치와 명명 규칙을 사용한다.
## 컨텍스트 로그 래퍼로 기록해 로그와 트레이스 연결하기
프로덕션 코드가 로그를 내보낼 때마다 저장소의 컨텍스트 로깅 래퍼를 사용한다.
- 요청 컨텍스트를 실제 로깅 지점까지 전달한다. 호출 체인이 아직 컨텍스트를 전달하지 않는다면 컨텍스트 매개변수를 추가한다.
- 래퍼가 텔레메트리 상관관계를 위해 레코드를 보강하는 경우 프레임워크의 기본 컨텍스트 로거를 직접 호출하지 않는다.
- 함수가 새 트레이스 스팬을 시작한다면 스팬이 시작된 뒤 컨텍스트 로거를 다시 가져온다. 이전에 가져온 로거에는 이전 스팬 컨텍스트가 남아 있다.
- 로깅 브리지가 로그를 올바른 트레이스와 연결할 수 있도록 구조화된 값을 활성 컨텍스트에 연결해 둔다.
- 프로덕션 코드가 반환하는 모든 오류를 확인하고 처리하며 버리지 않는다.
- 진단 정보를 추가할 때 저장소에 확립된 데이터 가림 처리, 권한 부여, 관측 가능성 경계를 유지한다.
로그 문장이 존재하는지만 확인하지 말고 관찰 가능한 결과를 통해 상관관계와 오류 동작을 검증한다.
## 핸들러, 그룹, 등록 순서로 새 도구 추가하기
새 제공 기능을 구현하기 전에 이름, 그룹화, 입력 스키마, 동작, 평가 범위를 확인하여 먼저 설계한다.
1. 제공 기능의 로직을 소유하는 핸들러를 구현한다.
2. 공개 도구 또는 명령 계약을 정의하고 핸들러에 연결한다.
3. 적절한 제공 기능 그룹에 추가하거나 맞는 그룹이 없다면 범위가 명확한 그룹을 만든다.
4. 저장소의 초기화 경로를 통해 새 그룹을 등록한다.
5. 동작 테스트, 구성 참조, 생성 카탈로그, 사용자 문서를 함께 업데이트한다.
각 제공 기능 그룹을 그 그룹이 소유하는 전용 디렉터리에 둔다. 등록 경로를 중복시키거나 내부 구현 세부 정보를 노출하는 이름을 사용하지 않는다.
## 정해진 빌드 타깃을 쓰고 요청 없이는 배포하지 않기
기억에 의존해 명령을 재구성하지 말고 저장소가 선언한 빌드 대상을 사용한다.
- 실행하기 전에 어떤 빌드 대상이 소스 형식을 정리하고, 모듈을 정돈하고, 단일 플랫폼을 컴파일하거나, 지원되는 모든 플랫폼을 빌드하는지 파악한다.
- 빌드 대상이 의도적으로 종속성 메타데이터나 생성 파일을 다시 쓸 수 있으므로 결과 diff를 검사한다.
- 모듈을 도입한 뒤 종속성 선언을 정돈된 상태로 유지하고, 저장소가 버전을 고정한 정적 분석 대상을 실행한다.
- 명시적 플래그, 환경 변수, 기본 파일, 클러스터 내부 구성 사이에 문서화된 우선순위를 포함하여 지원되는 로컬 및 원격 실행 모드를 유지한다.
- 처음 사용할 때 도구나 환경을 다운로드하는 테스트 또는 lint 대상을 문서화한다. 네트워크에 접근할 수 없으면 코드 실패가 아니라 설정 실패가 발생할 수 있다.
- 서비스 로직을 중복하지 말고 패키지 관리자 래퍼를 가볍게 유지하면서 컴파일된 바이너리와 동기화한다.
다운로드, 게시, push 또는 배포를 수행하는 대상을 외부 작업 경계로 취급한다. 먼저 계약을 검사하고, 작업에 릴리스 업무가 명시적으로 포함되지 않았다면 절대 게시하거나 배포하지 않는다.
## 비공개 함수가 아닌 공개 동작과 경계 사례 테스트하기
공개 API를 블랙박스로 실행하고, 실용적인 경우 실제 구현이나 통합 테스트를 우선한다.
- 저장소의 테스트 모음 규칙에 따라 테스트를 구성하고 각 테스트 파일에 대응하는 테스트 모음을 둔다.
- 중첩된 하위 테스트로 관련 시나리오를 그룹화하고 각 사례에 동작을 설명하는 명확한 이름을 붙인다.
- 각 사례는 이상적으로 하나의 집중된 어설션으로 하나의 동작만 입증한다.
- 테스트를 비공개 함수에 결합하지 않으면서 성공 경로, 콜백, 상태 변경, 관찰 가능한 출력을 다룬다.
- nil 또는 null 값, 빈 컬렉션, 잘못된 인덱스, 타입 불일치, 형식이 잘못된 입력, 오류 경로에 대한 경계 사례를 추가한다.
- 반드시 성공해야 하는 설정 작업에는 선행 조건 어설션을 사용하고, 그다음 예상 오류나 값을 명시적으로 검증한다.
- 테스트를 간결하게 유지하려는 이유만으로 오류를 절대 무시하지 않는다.
결함을 수정할 때는 먼저 결함에 집중한 실패 테스트를 작성하고, 수정 후 영향을 받는 패키지나 테스트 모음을 실행한 다음, 저장소가 요구하는 전체 테스트 대상으로 마무리한다.
## 기본값과 이름이 덮어써져도 설정 테스트가 통과하게 하기
다운스트림 빌드가 기본값, 기능 이름 또는 활성화된 제공 기능 집합을 재정의하더라도 구성 테스트는 계속 유효해야 한다.
- 일반 테스트 모음은 재정의가 없는 기본 구성에서 시작하고 그 위에 테스트별 설정을 계층화한다.
- 간단한 구성에서는 디코딩된 값을 테스트 모음의 기존 구성에 병합하여 테스트 하네스가 이미 설정한 런타임 필드를 그대로 유지한다.
- 섹션이 지연 값이나 원시 값을 저장한다면 해당 섹션을 완전히 구문 분석하는 데 필요한 메타데이터 인식 2단계 판독기를 사용한다.
- 전체 구성을 읽은 후 연결 경로, 출력 선택, 읽기 전용 상태와 같은 런타임 전용 필드를 명시적으로 복원한다.
- 다시 불러오기 테스트에서는 실행 중인 서비스가 사용하는 재정의 인식 기본값으로 후보를 의도적으로 구성한 다음 활성 런타임 필드를 상속한다.
- 필요한 제공 기능을 기존 목록에 추가한다. 추정한 업스트림 기본값으로 목록을 절대 대체하지 않는다.
- 브랜드 변경이 가능한 공개 이름은 동적으로 결정하되, 파서 계약이 요구하는 경우 파서의 리터럴 등록 키는 고정된 상태로 유지한다.
- 재정의될 수 있는 기본값, 공개 이름 또는 기능 집합을 어설션에 절대 하드코딩하지 않는다.
구성 변경이 이러한 경계를 넘을 때마다 기본 동작과 하나 이상의 재정의 경로를 모두 테스트한다.
## 공용 테스트 도우미를 한곳에 두고 준비 실패와 제품 오류 구분하기
범용 테스트 헬퍼를 저장소의 공유 내부 테스트 영역에 두고 목적, 입력, 예시를 명확하게 문서화한다.
- 여러 패키지가 재사용할 수 있도록 헬퍼를 단일 기능과 독립적으로 유지한다.
- 프로덕션 동작을 우회하는 저수준 지름길보다 현실적인 사용자 또는 프로토콜 상호작용을 우선한다.
- 로컬 클러스터 시뮬레이터, 다운로드된 환경, 자격 증명, 필수 네트워크 접근을 포함한 테스트 선행 조건을 명시한다.
- 진단에서 설정 실패와 제품 실패를 구분한다.
- 가치가 낮은 사례로 지표를 부풀리지 않으면서 특히 경계 조건과 실패 경로를 포함해 공개 API의 높은 커버리지를 지향한다.
- 테스트 구성, 별칭, 생성된 픽스처를 활성 테스트 실행기와 일치시킨다.
다운스트림 사용자 지정이 있다면 이름이 변경된 제공 기능, 변경된 기본값, 구성 다시 불러오기에 대한 대표 테스트를 포함한다.
## 생성 도구로 문서를 고치고 배포 패키지 버전 맞추기
코드 또는 구성 변경의 영향을 받는 모든 권위 있는 표면을 업데이트한다.
- 저장소 규칙이 소문자 파일 이름을 요구한다면 새 문서에 소문자 파일 이름을 사용한다.
- 기능의 영향에 따라 인덱스, 구성 참조, 프롬프트, 로깅, 관측 가능성, 인증, 통합 가이드를 업데이트한다.
- 생성된 표와 참조 섹션을 생성 콘텐츠로 취급한다. 마커 쌍을 보존하고 승인된 생성기를 통해 업데이트한다.
- 저장소 정책이 명시적으로 요구하지 않는 한 생성 섹션을 직접 편집하거나 빌드 산출물을 커밋하지 않는다.
- 네이티브 바이너리, 컨테이너 이미지, 언어 패키지 래퍼를 동일하게 버전이 지정된 서비스 동작과 일치시킨다.
- 변경과 관련하여 문서화된 빌드, 테스트, lint, 문서 생성, 집중 패키징 검사를 실행한다.
변경 사항을 제시하기 전에 최종 diff에 의도한 소스, 테스트, 문서, 패키지 업데이트만 포함되어 있는지 확인한다. 작업에 릴리스 또는 게시가 명시적으로 포함된 경우에만 해당 대상을 실행하고, 의도적으로 범위에서 제외한 더 광범위한 검사를 보고한다.
