회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
AWS 이용 중이라면 최대 700만 원 지원받으세요
자바스크립트를 활용하는 웹 개발자부터 SQL을 활용하는 데이터 분석가까지, IT 조직에서 코드를 다루는 업무를 하다 보면 누구나 에러를 겪게 됩니다. 이러한 에러를 해결하기 위한 과정을 ‘디버그’라고 하며, 아래 그림처럼 여러 가지 방법이 있습니다.
회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!
확인
자바스크립트를 활용하는 웹 개발자부터 SQL을 활용하는 데이터 분석가까지, IT 조직에서 코드를 다루는 업무를 하다 보면 누구나 에러를 겪게 됩니다. 이러한 에러를 해결하기 위한 과정을 ‘디버그’라고 하며, 아래 그림처럼 여러 가지 방법이 있습니다.
코드 상황이나 에러의 난이도에 따라 조금 바뀔 수도 있지만, 전체적인 맥락에서 보면 디버그는 다음과 같은 순서로 진행됩니다.
운이 좋다면 위 단계에서 에러를 모두 해결할 수 있습니다. 하지만 아래 그림처럼 나와 비슷한 에러 메시지나 현상을 찾을 수 없거나, 아무리 검색해도 단 하나의 답변도 없는 상황이라면 여러분은 험난한 여정을 거쳐야 합니다.
에러 해결을 위한 가장 확실한 방법은 코드 전체를 확인하는 것입니다. 하지만 모든 코드를 확인하는 것은 현실적으로 어렵습니다. 따라서 에러 해결을 위한 가장 효율적인 방법은 현재 겪고 있는 상황을 잘 정리하여 질문하는 것입니다. 이때 재현 가능한 예제(또는 reprex)를 활용할 수 있는데요. 이 방법은 질문자의 현 상황을 답변자가 쉽고 정확하게 이해하고, 문제를 해결하는 데 도움을 줄 수 있도록 현상을 구현하는 것을 말합니다. 이번 글에서 개발자가 알아두면 좋은 재현 가능한 예제와 reprex 활용법에 대해 살펴보겠습니다.
먼저 재현 가능한 예제의 의미에 대해 살펴보겠습니다. 재현은 [다시 나타남]이라는 의미를 가지고 있고, 예시는 [독자가 이해하기 쉽도록 도와주는 역할로 예를 들어 보인다]는 뜻을 가지고 있습니다. 즉, 재현 가능한 예제는 ‘질문한 문제를 다시 나타내어 이해하기 쉽도록 예를 든 것’이라고 할 수 있습니다.
이때 재현 가능한 예제는 상황에 따라 다르지만, 최소한의 코드(Minimal), 완전한 코드(Complete), 재현 가능한 코드(Reproducible)라는 3가지 조건을 만족해야 합니다.
코드가 길수록 어느 부분에서 문제가 발생하는지 확인하려면 더 많은 노력이 필요합니다. 예를 들어, 프로그램이 A, B, C, D, E와 같이 다섯 가지 기능으로 구성되어 있을 때, D 기능에서 발생한 에러를 해결하기 위한 질문을 할 경우, A부터 E까지 모든 코드를 질문하는 것보다는 D 기능과 관련된 최소한의 코드에만 초점을 맞추는 것이 좋습니다. 다른 사람들은 A부터 E까지의 코드 중에서 에러가 발생한 부분을 알 수 없기 때문에 모든 부분을 확인해야 할 가능성이 있습니다. 이러한 기능 분리를 위해서는 커밋을 분리하거나 함수를 모듈화하거나, MSA와 같은 아키텍처를 적용하는 등의 방법을 사용할 수 있습니다.
에러가 발생한 부분을 정확히 모르거나 분리가 되어 있지 않은 경우, 어떻게 해야 최소한의 코드를 찾을 수 있을까요? 이런 상황에서는 모든 부분을 주석 처리하여 없앤 다음 에러가 발생할 때까지 하나씩 코드를 추가해가며 확인하는 방법이 있습니다. 또는 에러가 발생하지 않을 때까지 코드를 역으로 하나씩 제거해가는 방법도 있습니다. 저의 경우 코드의 내용이 많은 경우, 코드를 제거하는 방법을 활용하고, 에러 발생 부분을 확인하려면 코드를 추가해가는 방법을 주로 사용합니다.
최소한의 코드를 분리한 후에는 코드를 정리하는 작업이 필요합니다. 예를 들어 변수 이름을 A, B, C와 같이 단순하게 만들거나, 데이터 값을 3.141592...에서 1로 변경하거나, 탭과 공백을 사용한 들여 쓰기나 주석을 추가하는 등의 작업이 포함됩니다.
완전한 코드란 에러를 재현하는데 필요한 모든 정보가 완전하게 포함되어 있는 것을 의미합니다. 그리고 독립적이고 분리된 코드(standalone/independent)를 뜻합니다. 다시 말해, 완전한 코드는 실행을 위해 다른 코드나 프로그램과의 상호작용이 필요하지 않으며, 하드웨어나 운영체제와 같은 외부 환경에 영향을 받지 않습니다. 또한, 특정 기능이나 목적을 수행하는 데 필요한 모든 기능을 포함하고 있는 코드입니다. 만약 코드가 라이브러리를 활용하거나 스타일 시트와 같이 다른 별도의 파일을 사용한다면, 그 내용도 함께 공유하여 완전한 코드를 만들 수 있습니다.
재현 가능한 코드란 환경에 관계없이 누가 언제 어디서 실행하더라도 동일한 입력이 주어진다면 동일한 결과가 만들어지는 코드를 말합니다. 재현 가능한 코드를 활용해 질문할 때, 코드의 맥락과 구조, 과정 등과 함께 왜 이런 결과가 나오는지를 설명하는 것이 좋습니다. 즉, 단순하게 “이 코드를 실행했는데 이런 에러가 났어요"와 같은 짧은 문장보단, “이 문제를 풀기 위해 이 코드를 사용했고, 이러한 결과를 예상했지만 아래 에러 메시지처럼 다른 결과가 나왔어요.” 와 같이 조금 더 자세하게 공유하는 것이 좋습니다.
특히 코드의 실행환경이나 실행 결과가 동일하게 재현되도록 아래와 같은 방법들을 사용하는 것도 중요합니다.
그리고 다른 사람이 더 쉽게 재현 가능하도록 코드와 에러 메시지는 스크린샷이 아닌 텍스트의 형태로 공유하는 것이 좋습니다. 때때로 실행 결과는 png 또는 gif, 동영상이 도움이 될 수도 있습니다.
반면, 아래와 같은 이유로 스크린샷을 공유하면 안 되는 경우도 있습니다.
이제 간단한 사례를 통해 재현 가능한 예제에 대해 알아보겠습니다. 아래 그림처럼 자바스크립트 환경에서 버튼을 클릭했을 때 기능이 작동하지 않는 간단한 에러 상황을 가정해 보겠습니다.
이 상황에서의 최소한의 코드, 완전한 코드, 재현 가능한 코드는 아래 단계를 거쳐 만들어 볼 수 있습니다.
1. H1, H2… 등 불필요한 태그를 담고 있는 코드를 제거합니다. (최소한의 코드)
2. 코드를 설명하는 적절한 주석을 달아줍니다.
3. 다른 사람이 이미지를 보고 따라 입력하는 것이 아닌, 복사/붙여넣기로 쉽게 작업할 수 있도록 텍스트 형태로 바꿔줍니다. (재현 가능한 코드)
<!DOCTYPE html>
<html>
<body>
<button onclick="myfunction()">Click me</button>
<!-- button with onclick -->
<p id="demo"></p>
<!-- area to show "Hello World" -->
<script>
// script
function myFunction() {
document.getElementById("demo").innerHTML = "Hello World";
}
</script>
</body>
</html>
4. 위 JSFiddle 이미지처럼 HTML / CSS / Javascript 등의 웹 개발 프로그래밍 언어는 JSFiddle이라는 서비스를 사용하여 코드만 입력하면 그 결과를 공유하고 온라인에서 바로 실행할 수도 있습니다. 3번의 코드는 독립적으로 실행 가능한 코드 (완전한 코드)이기 때문에 JSFiddle에서 바로 실행할 수 있습니다.
지금까지 재현 가능한 예제를 위한 3가지 조건을 통해 자바스크립트에서 재현 가능한 예제를 작성해 봤습니다. 다음으로 reprex에 대해 알아보겠습니다.
다음으로 reprex에 대해 살펴보겠습니다. reprex는 R에서 주로 사용하는 코드 재현 패키지를 말합니다. reprex를 사용해 코드와 결과를 다른 사람에게 공유하는 방법에 대해 알아보겠습니다. 아래는 reprex를 사용하지 않은 경우와 사용한 경우에 대한 비교 예시입니다.
reprex 사용법을 설명하기 위해 “starwars라는 데이터에서 skin color가 ‘light’, eye color 가 ‘brown’인 데이터만 추출하기 위해, R을 사용하여 코드를 작성 중이며 코드 결과에서 에러가 났다”라는 상황을 가정해 보겠습니다. 참조한 코드는 아래와 같습니다.
그리고 작성한 코드와 실행 결과는 다음과 같습니다.
앞서 말한 것처럼 이미지 파일을 그대로 깃허브나 슬랙, 이메일 등으로 공유하는 것은 바람직하지 않습니다. 이미지에 포함된 코드를 통해 이를 재현하는 것은 번거롭기 때문입니다. 이를 해결하기 위해 reprex를 사용하여 텍스트로 변경하는 방법을 소개합니다.
R에서 간단한 패키지 설치를 통해 쉽게 재현 가능한 예제로 변경할 수 있습니다. R에서 reprex 패키지를 설치한 이후, 에러가 나는 부분의 코드를 드래그로 선택합니다. 그다음 reprex_selection()이라는 함수를 실행하거나, R studio의 addin(VS Code의 extension과 유사한 기능)을 활용하여, 아래 이미지처럼 공유하려는 형태에 맞게 reprex를 만들 수 있습니다.
starwars %>%
filter(skin_color == "light", eye_color == "brown")
실행한 결과를 뷰어를 통해 확인하거나, 클립보드에 저장된 결과를 github이나 슬랙 등에서 바로 사용할 수 있습니다.
이처럼 reprex는 코드의 실행 환경과 실행 결과를 포함한 완전한(Complete) 예제를 만들 수 있기 때문에, 질문에 활용하는 것 말고도 다른 곳에 다양하게 활용될 수 있습니다.
API 정의서나 SaaS 등의 가이드 문서에는 코드를 어떻게 사용하고 작성해야 하는지 적혀있습니다. 즉, 최소한의 재현 가능한 예제를 포함해야 하고 reprex를 활용하여 작성할 수 있습니다.
다른 누군가에게 코드를 설명하거나 교육할 때, “이 코드는 이렇게 작성하면 에러 없이 사용할 수 있다. 이 코드는 이렇게 사용하는 것을 권장한다.” 등의 의미로 reprex를 활용하여 코드를 전달할 수 있습니다.
코드 작업을 하다 보면 에러나 버그를 발견할 때가 많습니다. 자주 쓰는 기능은 코드를 작성하고 활용하는 데 익숙해서 에러가 많이 발생하지 않고, 발생하더라도 쉽게 해결할 수 있습니다. 하지만 익숙하지 않은 코드는 사용할 때마다 비슷한 에러나 버그를 발견하고 이를 해결하는 과정을 반복합니다. 이러한 코드들을 reprex를 활용해 재현 가능한 예제로 기록해둔다면 해결하는 시간을 줄여 생산성을 높일 수 있습니다.
오늘 살펴본 것과 같이 재현 가능한 예제를 활용하면 코드의 맥락과 상황을 정확하고 자세하게 질문할 수 있습니다. 특히 쉽게 이해하기 어려운 질문이거나, 해결하기 귀찮은 종류의 질문이라면 시간 내어 도와주는 사람이 많지 않을 것입니다. 이럴 때 상대방이 잘 이해할 수 있는 좋은 질문은 개발자가 코드 에러를 해결할 때 뿐만 아니라, UX 리서치, 인공지능을 활용한 검색, 팀원들과의 1on1 등의 다양한 상황에서도 필요합니다. 앞으로 본인의 코드를 여러 사람에게 공유하고 문제를 해결함에 있어 도움이 되길 바랍니다.
글 애옹킴
편집 오신엽 객원 에디터
요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.