7부 36장. 파일, 터미널, 테스트, 실행을 연결하는 방식
7부 36장. 파일, 터미널, 테스트, 실행을 연결하는 방식
코딩을 처음 배울 때는 흔히 이렇게 생각한다.
"코드는 파일에 쓰여 있으니, 파일만 잘 고치면 되는 것 아닌가?"
반쯤은 맞고, 반쯤은 틀리다. 실제 개발에서는 파일 하나만 보고 문제를 해결하는 일이 생각보다 드물다. 코드는 파일에 적혀 있지만, 그 파일은 혼자 움직이지 않는다. 터미널에서 명령으로 실행되고, 테스트로 검증되고, 실제 런타임 환경에서 비로소 진짜 모습이 드러난다.
그래서 코딩 AI를 잘 쓰려면 단순히 "코드를 써 주는 모델"로 보면 안 된다. 더 중요한 것은 그 AI가 어떤 파일을 읽고, 어떤 명령을 실행하고, 어떤 테스트를 확인하며, 어디에서 실제로 돌아가는지를 이해하는 일이다.
겉보기에는 모두 코드 작업 같지만, 실전에서는 네 가지 층이 늘 연결되어 있다.
파일: 무엇이 적혀 있는가
터미널: 무엇을 시키고 있는가
테스트: 무엇이 맞고 틀린가
실행 환경: 실제로 무엇이 벌어지는가
이 연결을 이해하지 못하면 AI에게 일을 맡길 때도 자꾸 이상한 일이 생긴다. 코드는 그럴듯한데 실행이 안 되고, 테스트는 통과했는데 서비스는 깨지고, 로컬에서는 되는데 배포 환경에서는 실패한다.
이번 장에서는 이 네 가지가 어떻게 이어지는지, 그리고 왜 실행 환경 이해가 코딩 AI 시대의 필수 기초가 되었는지 차근차근 살펴보자.

코드는 파일 안에 있지만, 일은 파일 밖에서 일어난다
개발자가 실제로 하는 일을 떠올려 보면 금방 감이 온다. 에디터에서 파일을 열어 코드를 바꾸고 끝나는 경우는 거의 없다. 바꾼 뒤에는 보통 뭔가를 확인해야 한다. 앱을 실행해 보고, 테스트를 돌리고, 로그를 보고, 빌드를 해 보고, 에러가 나면 다시 원인을 찾는다.
즉, 파일 수정은 시작일 뿐이다. 진짜 작업은 그 다음부터다.
요리로 비유하면 더 쉽다. 레시피를 종이에 다시 썼다고 음식이 완성되는 것은 아니다. 재료를 준비하고, 불을 켜고, 익혀 보고, 간을 보고, 다시 조절해야 한다. 코드도 비슷하다. 파일은 레시피에 가깝고, 터미널은 조리 도구에 가깝고, 테스트는 맛보기이며, 실행은 손님 앞에 실제로 내는 순간에 가깝다.
그래서 AI가 파일만 잘 고쳐도 충분하다고 생각하면 금방 벽에 부딪힌다. 개발은 문장 생성이 아니라 상태를 바꾸고 결과를 확인하는 활동이기 때문이다.
파일은 설계도이자 현재 상태다
파일은 가장 눈에 잘 보이는 층이다. 소스 코드, 설정 파일, 테스트 파일, 환경 설정 파일, 문서 파일이 모두 여기에 있다. AI도 보통 여기서부터 일을 시작한다. 관련 파일을 찾고, 읽고, 수정하고, 변경 범위를 요약한다.
하지만 중요한 점이 하나 있다. 파일은 단순한 텍스트 묶음이 아니다. 그 프로젝트의 현재 상태가 파일에 녹아 있다.
예를 들어 같은 로그인 기능이라도 프로젝트마다 구조가 다르다. 어떤 곳은 src/auth에 모아 두고, 어떤 곳은 services와 controllers로 나누고, 어떤 곳은 프론트엔드와 백엔드가 분리되어 있다. 타입 정의는 다른 파일에 있고, 테스트는 또 다른 디렉터리에 있으며, 환경 변수 이름은 .env 파일에 적혀 있을 수 있다.
이 말은 곧, 파일 하나만 봐서는 전체를 모른다는 뜻이다. 함수 한 줄을 고치려 해도 이런 주변 맥락을 함께 봐야 한다.
이 함수는 어디서 호출되는가
어떤 설정 값에 의존하는가
관련 테스트는 어디에 있는가
같은 역할의 다른 함수는 어떤 스타일로 작성되었는가
배포 환경에서 필요한 값은 따로 있는가
AI가 파일 시스템에 접근할 수 있을수록 더 나은 이유가 여기에 있다. 코드는 늘 관계 속에 있기 때문이다. 겉으로는 한 줄 수정처럼 보여도, 실제로는 여러 파일의 균형을 맞추는 일인 경우가 많다.
터미널은 명령 창이 아니라 관찰 창이다
초보자에게 터미널은 종종 "명령어를 입력하는 까만 화면"처럼 느껴진다. 하지만 개발에서 터미널은 그보다 훨씬 중요하다. 터미널은 단순히 시키는 곳이 아니라, 현재 시스템이 어떻게 반응하는지 직접 보는 곳이다.
터미널에서는 보통 이런 일이 벌어진다.
개발 서버를 켠다
테스트를 돌린다
패키지를 설치한다
빌드를 한다
로그를 확인한다
프로세스를 죽이거나 다시 실행한다
Git 상태를 본다
즉, 터미널은 코드의 현실 반응이 드러나는 무대다.
예를 들어 AI가 파일을 잘 고쳤다고 해 보자. 그런데 npm test를 돌리니 실패한다. 혹은 서버는 켜지지만 런타임 에러가 난다. 또는 타입 체크는 통과하는데 번들링 단계에서 깨진다. 이 차이는 파일만 보고는 보이지 않는다. 명령을 실행해 봐야 드러난다.
그래서 코딩 AI가 터미널과 연결된다는 것은 아주 큰 의미를 가진다. 단지 글을 잘 쓰는 조수가 아니라, 가설을 세우고 실제로 확인할 수 있는 조수가 되는 것이다.
여기서 중요한 감각이 하나 생긴다. 개발에서 "안다"는 것은 설명을 읽는 것만이 아니라, 명령을 실행해 반응을 확인하는 것이다. 터미널을 모르면 AI가 뭔가를 해도 그 결과를 해석하기 어려워진다.
테스트는 심판이지만, 모든 것을 대변하지는 않는다
많은 사람이 테스트를 마치 절대적인 판정처럼 생각한다. 물론 테스트는 매우 중요하다. 자동화된 확인 장치가 있다는 것은 엄청난 장점이다. AI가 코드를 수정한 뒤 테스트를 돌려 바로 결과를 볼 수 있기 때문이다.
하지만 테스트에도 함정이 있다.
테스트 통과는 좋은 신호이지만, 그것만으로 충분하지는 않다. 왜냐하면 테스트는 작성된 범위 안에서만 검사하기 때문이다. 테스트가 없는 구멍은 그냥 지나간다. 잘못된 가정을 담은 테스트는 오히려 안심을 주기도 한다.
예를 들어 보자. AI가 로그인 토큰 만료 처리를 수정했고 관련 단위 테스트는 전부 통과했다. 그런데 실제 브라우저에서는 만료 직후 자동 로그아웃 화면 전환이 되지 않는다. 왜 그럴까. 백엔드 로직은 맞았지만 프론트엔드 상태 갱신이나 캐시 처리까지는 테스트하지 않았을 수 있다.
즉, 테스트는 매우 강력한 심판이지만, 경기장 전체를 항상 다 보는 것은 아니다.
그래서 테스트를 볼 때는 두 가지 질문을 함께 해야 한다.
첫째, 무엇이 통과했는가.
둘째, 무엇은 아직 아예 검사되지 않았는가.
AI에게 일을 맡길 때도 이 감각이 중요하다. 테스트를 통과시켰다는 말만 듣고 안심하면 안 된다. 어떤 테스트를 돌렸는지, 빠진 검증은 없는지, 실제 사용자 흐름까지 보았는지 확인해야 한다.
실행은 진짜 현실이다
파일이 바뀌고, 터미널 명령이 돌아가고, 테스트도 통과했다. 그러면 끝일까. 아직 아닐 수 있다. 마지막으로 남는 것은 실행이다.
여기서 말하는 실행은 단순히 명령이 성공했다는 뜻이 아니다. 실제 애플리케이션이 사용될 환경에서 의도한 대로 동작하는지를 보는 것이다.
예를 들어 이런 일들이 있다.
로컬에서는 되는데 컨테이너에서는 안 된다
개발 모드에서는 되는데 프로덕션 빌드에서 깨진다
테스트 데이터에서는 되는데 실제 데이터 규모에서 느려진다
macOS에서는 되는데 Linux 서버에서는 경로 문제로 실패한다
환경 변수가 빠진 배포 환경에서는 시작조차 안 된다
이런 문제는 파일만 읽어서는 놓치기 쉽다. 테스트만 보고도 지나치기 쉽다. 실제 실행 환경에서 돌려 봐야 비로소 드러난다.
개발에서 자주 나오는 말 중 하나가 있다.
"제 컴퓨터에서는 되는데요."
이 말이 농담처럼 들리지만, 사실 아주 중요한 교훈을 담고 있다. 코드는 진공 상태에서 존재하지 않는다. 운영체제, 패키지 버전, 환경 변수, 네트워크 상태, 데이터베이스 연결, 파일 권한, 컨테이너 설정 같은 조건 위에서 돌아간다.
그래서 실행은 늘 마지막 진실에 가깝다. 설명보다 강하고, 추정보다 냉정하다.
왜 AI에게 코딩을 맡길수록 실행 환경 이해가 더 중요해지는가
사람이 직접 코드를 짤 때는, 이상하게도 실행 환경을 몸으로 익히는 경우가 많다. 여러 번 실패하면서 감이 생긴다. "아, 이 프로젝트는 pnpm을 쓰는구나", "여기는 테스트 전에 마이그레이션을 해야 하네", "이 서버는 .env.local이 아니라 시크릿 매니저를 쓰는구나" 같은 감각이 쌓인다.
그런데 AI에게 일을 맡기기 시작하면 오히려 이 감각이 더 중요해진다. 왜냐하면 AI는 코드를 꽤 잘 만들 수 있지만, 실행 환경의 암묵지까지 자동으로 완벽히 이해하지는 못하기 때문이다.
여기서 초보자가 자주 하는 착각이 생긴다.
"AI가 코드를 잘 쓰니까, 나보다 훨씬 잘 알겠지."
아니다. AI는 문법과 패턴, 일반적인 해결책에는 강하다. 하지만 현재 저장소의 특수한 실행 방식, 사내 환경의 규칙, 숨겨진 운영 조건까지는 사람이 경계를 알려 주거나 직접 검증해야 한다.
즉, AI 시대에는 실행 환경 이해가 덜 중요해지는 것이 아니라, 오히려 더 중요해진다. 사람이 코드를 일일이 작성하는 비중은 줄어도, 무엇이 실제로 돌아가는 조건인가를 판단하는 역할은 여전히 사람에게 남기 때문이다.
파일, 터미널, 테스트, 실행은 어떻게 한 줄로 이어지는가
이 네 가지를 따로따로 보면 복잡해 보인다. 하지만 흐름으로 보면 비교적 단순하다.
먼저 파일에서 변경이 일어난다. 그다음 터미널에서 관련 명령을 실행한다. 테스트나 빌드로 기계적인 검증을 한다. 마지막으로 실제 애플리케이션을 실행해 현실 반응을 본다.
이 과정을 한 줄로 쓰면 이렇다.
수정 → 실행 → 검증 → 관찰 → 재수정
코딩 AI가 강력해지는 것도 바로 이 고리 때문이다. 파일만 건드리는 AI는 수정에서 멈춘다. 터미널과 테스트에 연결된 AI는 검증까지 갈 수 있다. 여기에 실행 환경까지 고려하는 AI는 현실에 더 가까워진다.
사람이 잘해야 하는 것도 이 고리를 설계하는 일이다. 무엇을 고칠지, 어떤 명령으로 확인할지, 어떤 테스트를 기준으로 삼을지, 마지막에 어디서 실제 실행을 볼지를 정해 줘야 한다.
이 고리가 빠진 채 "코드 좀 고쳐 줘"만 반복하면, AI는 자꾸 그럴듯한 초안을 만들고 사람은 끝없이 뒷정리하게 된다.
자주 생기는 오해: 코드가 맞는데 앱은 왜 안 돌아갈까
이 질문은 초보자뿐 아니라 숙련자도 자주 만난다. 그리고 이 질문의 답은 대개 코드 바깥에 있다.
앱이 안 도는 이유는 문법 오류만이 아니다. 오히려 실무에서는 이런 이유가 더 흔하다.
필요한 환경 변수가 없다
패키지 버전이 맞지 않는다
데이터베이스가 예상한 상태가 아니다
파일 경로나 권한이 운영체제마다 다르다
개발 서버와 프로덕션 서버의 설정이 다르다
테스트에서는 목 객체를 썼지만 실제 서비스는 외부 API에 연결된다
이런 문제는 "코드가 틀렸다"와는 조금 다르다. 더 정확히 말하면, 코드가 놓인 자리가 다르기 때문에 생긴다.
그래서 코딩 AI에게 버그를 맡길 때도, 에러 메시지와 관련 파일만 던져 주는 것으로 부족할 때가 많다. 어떤 명령으로 실행했는지, 어느 환경에서 실패했는지, 로컬인지 컨테이너인지 CI인지, 환경 변수는 어떻게 주입되는지 같은 정보가 품질을 크게 바꾼다.
AI가 틀린 답을 냈다기보다, 현실을 구성하는 조건이 전달되지 않은 경우가 많은 것이다.
로컬, 컨테이너, CI는 같은 세상이 아니다
요즘 개발에서는 실행 환경이 하나가 아니다. 보통 최소 세 가지가 섞여 있다.
로컬 환경은 내 컴퓨터다. 컨테이너는 격리된 실행 상자라고 생각하면 된다. CI는 GitHub Actions 같은 자동화 검증 환경이다. 겉으로는 모두 같은 프로젝트를 다루지만, 실제로는 꽤 다르게 행동할 수 있다.
로컬에서는 내 컴퓨터에 깔린 도구 버전과 캐시의 영향을 받는다. 컨테이너는 더 깨끗하지만, 대신 로컬과 설정 차이가 날 수 있다. CI는 가장 엄격한 경우가 많다. 처음부터 설치하고 처음부터 실행하기 때문에, 숨겨진 의존성이 있으면 잘 드러난다.
예를 들어 내 컴퓨터에는 이미 어떤 CLI 도구가 설치되어 있어서 빌드가 되는데, CI는 그 도구가 없어서 실패할 수 있다. 혹은 macOS에서는 대소문자 구분이 느슨하게 느껴졌는데 Linux CI에서는 파일 경로 오류가 터질 수 있다.
이런 차이를 모르면 AI가 수정한 코드가 왜 어떤 곳에서는 되고 어떤 곳에서는 안 되는지 설명하기 어렵다.
반대로 이 차이를 이해하면 AI에게도 훨씬 좋은 일을 맡길 수 있다. "로컬에서만 통과하면 되는 수정"인지, "CI와 컨테이너까지 고려해야 하는 수정"인지 범위를 나눌 수 있기 때문이다.
작은 사례로 보는 연결 구조
조금 더 생생하게 보자. 로그인 API 호출이 가끔 401 오류를 내고, 프론트엔드가 사용자 상태를 잘못 유지하는 버그가 있다고 하자.
겉으로만 보면 "로그인 버그 고쳐 줘" 한 문장으로 보인다. 하지만 실제로는 여러 층이 연결되어 있다.
먼저 파일 층에서는 인증 요청 함수, 토큰 저장 로직, 상태 관리 코드, 관련 테스트 파일을 읽어야 한다. 여기서 AI는 어떤 파일들이 함께 움직이는지 파악한다.
그다음 터미널 층에서는 개발 서버를 띄우고, 테스트를 돌리고, 실패 로그를 확인한다. 필요하면 특정 테스트만 골라 돌려 재현 속도를 높일 수 있다.
이후 테스트 층에서는 단위 테스트가 깨지는지, 통합 테스트가 있는지, 인증 만료 케이스가 자동 검증되는지 확인한다. 없다면 테스트를 추가해야 할 수도 있다.
마지막 실행 층에서는 브라우저에서 실제 로그인 후 일정 시간이 지나면 어떤 화면이 나오는지, 새로고침했을 때 상태가 어떻게 바뀌는지, 백엔드 응답과 프론트 상태가 맞물리는지 봐야 한다.
이 과정을 보면 알 수 있다. 버그는 하나였지만, 해결은 여러 층을 건너야 한다. 그리고 이때 AI가 강해지려면 단순히 로그인 함수를 멋지게 다시 쓰는 것이 아니라, 재현하고, 수정하고, 검증하고, 실제 흐름을 다시 확인하는 연결 능력이 필요하다.
AI가 잘못 달리기 시작할 때 보이는 신호
코딩 AI를 쓰다 보면, 겉보기에는 열심히 일하는데 사실은 엉뚱한 방향으로 가는 순간이 있다. 그럴 때는 대개 파일, 터미널, 테스트, 실행 중 하나가 끊겨 있다.
예를 들어 이런 신호가 보인다.
파일은 많이 바꾸는데 테스트를 돌리지 않는다
테스트는 통과시키는데 실제 실행 확인이 없다
에러 로그를 보고도 재현 명령을 명확히 잡지 못한다
환경 변수나 설정 파일은 건드리지 않으면서 원인을 코드 안에서만 찾는다
한 환경에서 생긴 문제를 다른 환경 기준으로 해결하려 한다
이런 모습이 보이면 멈춰서 다시 물어봐야 한다. 지금 무엇을 고쳤는지보다, 무엇을 어떤 환경에서 확인했는지를 먼저 따져야 한다.
사람도 디버깅할 때 가장 먼저 확인하는 것이 재현과 관찰이듯, AI에게도 같은 원칙이 필요하다.
사람이 꼭 알아야 할 최소한의 실행 환경 감각
모든 개발자가 인프라 전문가가 될 필요는 없다. 하지만 코딩 AI를 실전에서 잘 쓰려면 최소한의 실행 환경 감각은 갖고 있어야 한다.
적어도 다음 정도는 구분할 줄 알아야 한다.
이 프로젝트를 켜는 명령은 무엇인가
테스트와 빌드 명령은 각각 무엇인가
환경 변수는 어디서 오고 어디에 쓰이는가
로컬, 컨테이너, CI 중 어디에서 실패하는가
성공 기준은 테스트 통과인지, 실제 화면 확인인지, 둘 다인지
이 정도만 알아도 AI에게 일을 맡기는 방식이 완전히 달라진다. 단순히 "이거 고쳐 줘"가 아니라, "로컬에서 이 명령으로 재현되고, 관련 테스트는 이것이며, 최종적으로는 이 화면 흐름이 정상이어야 한다"처럼 훨씬 현실적인 요청을 할 수 있게 된다.
중요한 것은 전문 용어를 많이 아는 것이 아니다. 어디서 무엇을 확인해야 진짜 끝났다고 말할 수 있는지를 아는 것이다.
결국 코딩은 텍스트 편집이 아니라 피드백 루프다
이 장의 핵심을 가장 짧게 말하면 이렇다.
코딩은 파일을 편집하는 일이 아니라, 피드백 루프를 돌리는 일이다.
파일에서 바꾸고, 터미널에서 실행하고, 테스트로 검증하고, 실제 실행에서 확인한 뒤, 다시 고친다. 이 고리가 개발의 기본 리듬이다. AI가 이 리듬 안에 들어오면 강력해지고, 이 리듬 밖에서 문장만 만들어 주면 생각보다 한계가 빨리 온다.
그래서 앞으로 코딩 AI를 잘 쓰는 사람은 단순히 프롬프트를 예쁘게 쓰는 사람이 아니다. 작업이 어떤 파일에 걸쳐 있는지 알고, 어떤 명령으로 재현되는지 알고, 어떤 테스트가 신뢰할 만한지 알고, 실제 실행 환경이 어디인지 구분할 수 있는 사람이다.
AI에게 코딩을 맡긴다는 것은 "대신 타이핑해 줘"가 아니다. 더 정확히 말하면, 내 작업 루프 안으로 들어와 함께 수정하고 검증하라는 뜻이다.
그 루프를 이해할수록 AI는 더 유능한 조수가 된다. 반대로 그 루프를 모르면, 아무리 똑똑한 모델을 써도 자꾸 겉만 맞는 결과에 속게 된다.
이 장의 정리
파일은 코드가 적혀 있는 장소다. 터미널은 명령을 실행하고 반응을 확인하는 장소다. 테스트는 자동화된 검증 장치다. 실행 환경은 코드가 실제로 살아 움직이는 현실이다.
실제 개발은 이 네 가지가 분리되어 있지 않다. 파일 수정은 터미널 실행으로 이어지고, 터미널 실행은 테스트와 로그 확인으로 이어지며, 마지막에는 실제 환경에서 동작을 확인해야 한다. 그래서 코드 작업은 본질적으로 여러 실행 환경의 연결 위에서 돌아간다.
코딩 AI가 강력해지는 이유도 바로 이 연결을 따라갈 수 있기 때문이다. 반대로 사람이 이 연결을 이해하지 못하면, AI가 만든 결과를 제대로 평가할 수 없다.
좋은 코드란 예쁘게 써진 코드만이 아니다. 지금 이 프로젝트의 파일 구조 안에서 자연스럽고, 이 명령 체계 안에서 검증되며, 이 실행 환경에서 실제로 돌아가는 코드다.
그 기준을 붙잡는 순간, AI에게 코딩을 맡기는 방식도 훨씬 현실적이고 강력해진다.
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.