Lint, Test, Build #35
Replies: 6 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에 배포해야 한다. 환경마다 매번 다시 빌드하면 그 사이에 빌드 환경이 달라져 다른 결과물이 나올 수 있으니 빌드는 딱 한번만! 그리고 배포를 스테이징과 프로덕션에 해주면 된다. 결국 순서를 통째로 외우는 게 아니라 무엇이 무엇을 필요로 하는지 뼈대를 잡고 그 안에서 자주 꺠지는 것을 앞으로 보내면 된다. 그러면 어떤 언어나 프레임워크를 만나도 스스로 순서를 유도해낼 수 있을 것이다. |
1. Lint, Test, Build가 각각 무엇인지와 각 역할과 목적을 설명해주세요.셋 모두 코드를 검사하는 기능이지만 다른 관점으로 검사합니다.
Test는 코드를 실제로 실행한 결과를 보고 점검합니다. 예를 들어 더하기 함수가 있는데 내부에서는 뺄셈이 수행되어 기대값과 결과값이 다른지 점검합니다. Test는 함수 하나 정도를 검사하는 작은 단위의 Unit Test와, 여러 기능이 연결되었을 때의 문제를 발견하는 Integration Test와, 실제 사용자가 하는 행동하듯이 사용자의 전체 행동을 테스트하는 E2E Test로 구성되어있습니다. Build란 개발자가 작성한 소스 코드를 실제 실행하거나 배포할 수 있는 결과물로 만드는 과정입니다. 우리가 작성한 코드가 그대로 서버에 올라가거나 사용자에게 전달되는 것은 아닌 경우가 많습니다. 예를 들어 TypeScript로 작성했지만 브라우저나 실행 환경에 맞게 JavaScript로 변환해야하는 과정이 발생할 수도 있는데, 그때에 컴파일, 트랜스파일, 번들링, 최적화 등이 일어나지만, 타입이 맞지 않거나, 호출한 파일명이 없으면 빌드가 실패합니다. 2. Linting 단계에서 미리 잡을 수 있는 오류와, Test 과정을 통해서만 발견할 수 있는 오류의 차이점은 무엇인가요?Lint는 정적 분석으로 실행 전 코드 자체만 보고 의문을 제기하는 단계이고, Test는 실제 실행 후에 기대한 결과와 달랐을 때 발생하는 오류이다. expect(discount(10000)).toBe(7000); //할인 정책의 결과를 예측하는 Test단계를 위한 코드Lint단계에서 잡을 수 없는 오류도 실행 후 Test 단계에서 잡힐 수도 있다는 의미입니다. 3. CI/CD 파이프라인에서 Lint, Test, Build의 수행 순서를 어떻게 구성해야 하며, 그 이유는 무엇인가요?CI/CD에서는 일반적으로 Lint->Test->Build 순서로 검사가 수행되며, 앞 단계에서 실패하면 다음 단계를 굳이 수행하지 않습니다. 이걸 Fail Fast, 즉 가능한 빨리 실패를 발견한다고 표현합니다. 예를 들어 깃허브에 코드를 push했을 때 서버가 자동으로 검사하는 CI가 있을 때, Lint에서 에러가 난다면 다음 단계인 많은 테스트를 굳이 돌릴 필요없기 때문에 효율적이라고 볼 수 있습니다. 마찬가지로 Test단계에서 실패했을 때, 실패할 가능성이 크고 오래 걸리는 Build는 굳이 안 해도 된다는 점이 효율적입니다. 따라서 보통 빠르고 저렴한 검사를 먼저 수행해서 실패를 최대한 빨리 발견하는 것입니다. 이렇게 하면 불필요한 빌드 시간이나 CI 자원을 줄일 수 있습니다. 다만, 프로젝트에 따라 Test보다 Build를 먼저 해야하는 경우도 있습니다. 예를 들어 테스트 자체가 빌드된 결과물을 필요로 하는 구조라면 Build가 먼저 수행될 수 있습니다. 그래서 절대적인 순서라기보다는 각 프로젝트의 구조를 고려하되, 기본 원칙은 빠르게 실패할 수 있는 단계를 앞에 두는 것이라고 생각합니다. 요약)
|
1. Lint, Test, Build가 각각 무엇인지와 각 역할과 목적을 설명해주세요.
2. Linting 단계에서 미리 잡을 수 있는 오류와, Test 과정을 통해서만 발견할 수 있는 오류의 차이점은 무엇인가요?
3. CI/CD 파이프라인에서 Lint, Test, Build의 수행 순서를 어떻게 구성해야 하며, 그 이유는 무엇인가요?Lint → Test → Build 순서라고 생각합니다
|
|
1. Lint, Test, Build가 각각 무엇인지와 각 역할과 목적을 설명해주세요. Lint코드를 실행하지 않고 소스를 정적으로 분석하는 단계
린트의 원리는 코드를 글자 그대로 읽는 게 아니라 문장 구조로 분해해서 트리로 만든 다음 그 트리에서 패턴을 찾는 것이다. 속도가 빠르고 수정이 쉬운 단계라 코드 실행 전, 가장 먼저 실행한다. 코드 작성을 사람이 하는 일이 줄어들면서 스타일 룰에 대한 부분은 불필요해졌지만 ai도 코드 수정이 잦기 때문에 그 부분에서 오는 리팩터링의 잔해를 lint 를 통해 잡아낼 수 있다. 여러 곳에서 실행할 수 있다. vscode extension ESLint 를 설치한다거나 Git hook 을 통해 돌릴 수도 있고, 에이전트가 할 수도 있고, ci 과정에서 할 수도 있다. 이건 재량껏 하면 될 것 같다. 최종 강제용으로 ci 에서 진행하는 게 좋아보인다. Testlint 가 모든 코드를 얕게 보는 체크방식이었다면 test는 적은 코드를 깊게 본다. 테스트에는 크게 3개의 종류가 있다.
세가지 테스트 방식의 차이를 만드는 기준은 “얼마나 실제처럼 테스트 하느냐” 이다. Unit 테스트의 경우 클래스, 메서드 단위에서 mock 데이터로 테스1한다. 하지만 모든 동작을 이렇게 테스트할 수는 없을 것이다. 현실에서는 mock 데이터가 아닌 실제로 존재하는 데이터로 테스트가 필요할 때가 있는데 이때 Integration 테스트 방식을 사용한다. ( Buildbuild 는 개발자가 작성한 코드를 실제 실행, 배포에 사용할 수 있도록 결과물로 만드는 과정이다. 보통 아래의 과정을 거친다.
2. Linting 단계에서 미리 잡을 수 있는 오류와, Test 과정을 통해서만 발견할 수 있는 오류의 차이점은 무엇인가요 lint 단계에서는 코드를 정적으로 분석한다. 따라서 문법에 오류가 없어도 비즈니스 로직의 실제 논리적 오류가 있는 코드를 잡을 수 없다. 예시로 lint 과정에서는 미사용 변수, 라이브러리, 타입 오류를 잡을 수는 있어도 실제 데이터의 조작에 있어서 개발자가 저지른 논리적 실수를 잡을 수는 없다. 따라서 test 와 lint 를 필요에 따라 잘 써야 한다. ?3. CI/CD 파이프라인에서 Lint, Test, Build의 수행 순서를 어떻게 구성해야 하며, 그 이유는 무엇인가요? 실행 속도 순서대로 lint, test, build 가 맞다. 또한 실행하는 데 드는 비용도 lint, test, build 순서이다. 따라서 lint 단계를 먼저 수행하고(test 를 포함해도 됨. lint 가 빨라서 보통 먼저 끝남) 그리고 build 를 하는 방식을 채택해도 되고 lint, test 를 묶어도 되고, 여러 방법이 있다. 프로젝트 by 프로젝트라 솔직히 알잘딱 하면 된다. |
기본 질문1. Lint, Test, Build가 각각 무엇인지와 각 역할과 목적을 설명해주세요.Lint는 코드를 실행하지 않고, 텍스트 상태로 읽어 문법 오류, 스타일 위반, 잠재적 위험을 찾아내는 과정으로 코드의 가독성을 높이고, 팀의 컨벤션을 통일하여 단순한 오타 등으로 생길 수 있는 잠재적 버그를 사전에 방지해줍니다. 주요 역할은 띄어쓰기 규칙, 줄바꿈 등 스타일을 교정하고 선언만 하고 사용하지 않는 변수, 닫히지 않은 괄호 탐지, 안전하지 않은 코드 경고를 해줍니다. Test는 작성한 코드를 실행하여 원하는 대로 작동하는지 검증하는 과정입니다. 기능상의 버그를 찾고 코드를 추가, 수정하더라도 기존의 기능이 깨지지 않는지 보장합니다. 주요 역할은 기능 정상 작동 검증, 회귀 방지, 예외 처리 검증이 있습니다. Build는 소스 파일을 컴퓨터 혹은 웹 브라우저가 실행할 수 있는 하나의 결과물로 변환하는 과정입니다. 실제 사용자가 사용할 수 있는 형태로 바꾸고, 파일 크기를 줄여 로딩 속도를 최적화합니다. 주요 역할은 흩어진 소스 파일을 하나로 묶어주고, 컴파일, 트랜스파일, 최적화 및 경량화를 합니다. 2. Linting 단계에서 미리 잡을 수 있는 오류와, Test 과정을 통해서만 발견할 수 있는 오류의 차이점은 무엇인가요?Linting 단계에서 잡을 수 있는 오류는 문법 및 텍스트 오타, 미사용 코드, 잘못된 접근 및 잠재적 버그, 스타일 및 컨벤션 위반 등을 잡을 수 있습니다. 이는 모두 실제 코드를 실행해서 찾는 것이 아닌 정적 분석으로 찾아내는 정적인 오류들입니다. Test는 실제로 실행해서 찾는 동적 분석으로 비즈니스 로직의 논리적 모순, 예외 처리 실패, 모듈 연동 실패 등의 오류를 찾아냅니다. 이는 동적으로 실행 중에 생기는 실재의 버그를 찾아냅니다. 3. CI/CD 파이프라인에서 Lint, Test, Build의 수행 순서를 어떻게 구성해야 하며, 그 이유는 무엇인가요?CI/CD 파이프라인에서 Lint, Test, Build는 수행시간 짧고 실패할 확률이 높은 순서로 구성하는 것이 핵심입니다. 그래서 Lint → Test → Build 순으로 하는 것이 좋습니다. 여기서 만약 앞 단계에서 실패가 뜨면 그 즉시 CI를 중단하여 실패 지점을 알리고 수정을 요구합니다. 그러나 프로젝트 규모가 커질 수록 각 단계의 소요시간이 늘어나기도 하기에 그때엔 Lint와 Test를 분리하여 병렬로 처리하기도 하며 의존설치를 미리 캐싱해두어 의존 설치에 소요되는 시간을 절약하기도 합니다. |
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