Lint, Test, Build #35
Replies: 2 comments
1. Lint, Test, Build가 각각 무엇인지와 각 역할과 목적을 설명해주세요.Lint, Test, Build는 코드의 서로 다른 측면을 확인하는 과정이다. [ Lint ] : 코드를 실행하지 않고 정해진 규칙에 맞는지 검사한다.
[ Test ] : 코드를 실행해 실제 결과가 기대한 결과가 기대한 결과와 같은지 확인한다.
[ Build ] : 소스 코드와 필요한 파일을 실행하거나 배포할 수 있는 형태로 반환한다.
예를 들어 쇼핑몰의 할인 금액 계산 기능을 개발한다면 다음처럼 구분할 수 있다.
보통 Lint → Test → Build 순서로 확인하지만, 프로젝트에 따라 순서가 달라지거나 병렬로 실행되기도 한다. 어느 하나가 성공했다고 나머지까지 보장되지는 않는다. 빌드가 성공해도 계산 결과가 틀릴 수 있고, 테스트가 통과해도 테스트하지 않은 부분에는 문제가 있을 수 있다. 2. Linting 단계에서 미리 잡을 수 있는 오류와, Test 과정을 통해서만 발견할 수 있는 오류의 차이점은 무엇인가요?핵심 차이는 코드의 형태만 보고 판단할 수 있는 문제인지, 실제 동작 결과를 확인해야 하는 문제인지이다. Linting은 코드를 실행하지 않고 규칙이나 패턴을 검사한다. 설정과 도구에 따라 다음과 같은 문제를 미리 잡을 수 있다.
Test는 특정 입력이나 상황에서 코드가 의도대로 동작하는지 검증한다. 문법과 코드 규칙이 올바르더라도 다음 문제는 동작을 확인해야 드러난다.
예를 들어 다음 코드는 문법적으로는 올바르다.
다만 "Test를 통해서만 발견된다"는 표현은 엄밀하게는 아니다. 이런 오류는 코드 리뷰나 수동 실행으로도 발견할 수 있다. Test의 가치는 기대하는 동작을 명시하고, 수정할 때마다 자동으로 반복 검증할 수 있다는 점이다. 3. CI/CD 파이프라인에서 Lint, Test, Build의 수행 순서를 어떻게 구성해야 하며, 그 이유는 무엇인가요?일반적으로 Lint → Test → Build → Deploy 순서로 구성한다. 빠르고 비용이 적은 검사부터 수행해, 문제가 있는 변경을 일찍 걸러내기 위해서이다.
다만 테스트가 빌드 결과물을 필요로 한다면 순서가 달라진다. 예를 들어 컴파일된 프로그램을 테스트하거나, 완성된 웹 앱을 브라우저로 검증하는 E2E 테스트는 빌드 이후에 실행해야 한다. 코드 변경 Lint와 단위 테스트가 서로 의존하지 않으면 병렬 실행해 전체 대기 시간을 줄일 수 있다. 반대로 실행 자원을 아끼는 것이 중요하다면 Lint가 통과한 뒤 테스트를 시작하도록 구성할 수 있다. 따라서 순서는 작업 간 의존성을 먼저 지키고, 가능한 범위에서 빠른 검사를 앞에 배치하는 방식으로 결정하면 된다. 배포할 때는 검증한 빌드 결과물을 그대로 사용해야, 테스트한 대상과 실제 배포 대상이 같아진다. |
1. Lint, Test, Build가 각각 무엇인지와 각 역할과 목적을 설명해주세요.Lint는 소스를 실행하지 않고 텍스트/AST 수준에서 분석하는 정적 분석이다. ESLint,Ruff,clippy 같은 도구가 여기 속한다. 팀 전체가 같은 모양의 코드를 쓰게 만들어 리뷰에서 취향 논쟁을 없애 스타일을 통일 시켜준다. 또한 알려진 버그 패턴을 조기 차단한다. Test는 코드를 실제로 실행해서 입력에 대한 출력이 기대와 맞는지 검증한다. 단위→통합→E2E로 갈수록 현실에 가깝지만 느리고 깨지기 쉽다. 역할은 정확성 검증 자체 보다 리팩토링 안전망과 회귀 방지에 있다. 테스트가 없으면 코드를 고칠 때마다 신뢰가 없다. Build는 소스를 실행 가능한 산출물로 변환한다. 컴파일,타입 체크,트랜스파일,번들링, 최적화, 그리고 아티팩트 생성. 역할은 배포 가능성 보증이다. 빌드가 깨지면 그 커밋은 존재하지 않는 것과 같다. 또한 빌드는 은근히 강력한 검증 단계이기도 하다. 타입 체커가 붙어 있다면 여기서 상당수 계약 위반이 걸린다. 2. Linting 단계에서 미리 잡을 수 있는 오류와, Test 과정을 통해서만 발견할 수 있는 오류의 차이점은 무엇인가요?Lint는 코드의 형태를 보고, Test는 코드의 의미를 본다. Lint는 실행해 보지 않아도 코드 모양 만으로 판단 가능한 것을 잡는다. 선언만 하고 쓰지 않는 변수, 어디서도 도달 불가한 코드 블록, 오타 때문에 존재하지 않는 이름을 참조하는 경우가 대표적이다. 이런 것들은 값이 무엇이든 상관없이 코드의 생김새만으로 실수다!라고 판단할 수 있기 때문에 정적분석의 관할이다. Test로만 잡을 수 있는 건 실제 값을 봐야만 아는 것이다. 짜잘한 예를 들어보자면, 반복문의 범위가 하나씩 어긋나 마지막 원소를 빠뜨리는 경우, 빈 배열이나 null이 들어왔을 때 무너지는 경우 , 호출 순서에 따라 결과가 달라지는 상태 의존성, 외부 api의 응답 스키마가 바꼈거나 db쿼리가 예상과 다른 결과를 돌려주는 불일치도 실제로 호출하기 전에는 알 방법이 없다. 이렇게 정적분석이 원리적으로 접근할 수 없는 영역에서 test를 통해서 버그를 발견할 수 있다. 3. CI/CD 파이프라인에서 Lint, Test, Build의 수행 순서를 어떻게 구성해야 하며, 그 이유는 무엇인가요?기본 원칙은 실패 확률이 높으면서 검증 비용이 싼 것을 먼저 수행한다. 오랫동안 빌드를 다 돌린 후에 오류라고 듣는 건 최악이기 때문이다. 일단 시간은 lint→test→build순으로 오래 걸린다고 한다. 의존성이 순서를 강제하고 그 제약 안에서 비용이 순서를 결정한다. 즉 한 과정을 안 거치면 테스트를 아예 못 돌리는 경우를 의존성이 있다고 말하는데, 이 경우에 비용과 무관하게 순서가 못 박힌다. 인터프리터 계열의 언어는 Lint→Type check→test→build→deploy 이 순서를 따른다. 소스 자체가 실행 단위여서 컴파일 없이 바로 돌아가니까 테스트를 돌리기 위해 사전에 해야 할 일이 없다. 의존성 제약이 없으므로 순수하게 비용 순서를 따를 수 있다. 컴파일 계열(Go,Rust,Java,C++)은 테스트를 실행하기 전에 기계어나 바이트코드로 변환해야 비로소 돌아간다. 테스트 코드도 코드이므로 실행하려면 컴파일이 필요하다. 그래서 이런 순서를 따르고, Lint→Complie→test→package→deploy이렇게 빌드가 아닌, 배포용 아티팩트를 생성하는 것이 마지막이라고 한다. build라는 단어는 컴파일과 패키징을 뭉뚱그리는 단어라는 걸 알 수 있다. 인터프리터 언어에서는 이 두 작업이 뒤에 붙어 있어서 구분할 필요가 없었고, 컴파일 언어에서는 앞에 컴파일, 뒤에 패키징 이렇게 쪼개져 있어 배포용아티팩트 생성이 마지막이라고 이해하는 것이 정확하다. 그리고 컴파일 언어에서 Lint도 어차피 코드를 검증하고 파싱하는 부분인데 컴파일이 더 정확하니까 컴파일 먼저 하면 안되는지 의문이 들 수 있는데 Lint는 컴파일러보다 훨씬 얇게 훑기 때문에 Lint를 먼저 해주거나 병렬로 돌리는 경우도 있다. 그리고 애초에 CI파이프라인은 의존성이 필요한 경우가 아니면 동시에 돌려도 된다. 그러나 전체 소요 시간이 줄어드는 대신, 인프라 비용은 늘어날 수 있다. 순서와는 별개로 반드시 지켜야 할 원칙이 하나 더 있는데 검증을 통과한 커밋에서 아티팩트를 딱 한번만 만들고, 그 동일한 산출물을 staging과 production에 배포해야 한다. 환경마다 매번 다시 빌드하면 그 사이에 빌드 환경이 달라져 다른 결과물이 나올 수 있으니 빌드는 딱 한번만! 그리고 배포를 스테이징과 프로덕션에 해주면 된다. 결국 순서를 통째로 외우는 게 아니라 무엇이 무엇을 필요로 하는지 뼈대를 잡고 그 안에서 자주 꺠지는 것을 앞으로 보내면 된다. 그러면 어떤 언어나 프레임워크를 만나도 스스로 순서를 유도해낼 수 있을 것이다. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
🗓️ 2026년 9월 7일 월요일
💡오늘의 질문?
1. Lint, Test, Build가 각각 무엇인지와 각 역할과 목적을 설명해주세요.
2. Linting 단계에서 미리 잡을 수 있는 오류와, Test 과정을 통해서만 발견할 수 있는 오류의 차이점은 무엇인가요?
3. CI/CD 파이프라인에서 Lint, Test, Build의 수행 순서를 어떻게 구성해야 하며, 그 이유는 무엇인가요?
All reactions