우리는 코드를 작성하고 테스트해 보며 하나의 프로덕트를 개발하고 있습니다.
하지만, 이런 과정은 위에 말한 내용과 같이 한 줄로 표현할 수 없을 만큼 긴 시간과 노력이 필요합니다.
만약, 위 과정을 자동화시킬 수 있다면, 혹은 누군가가 대신 빠르게 분석해 준다면 정말 편하지 않을까요?
이를 해결 해줄 방법으로 SonarQube가 있습니다.
오늘은 SonarQube를 간단한 실습으로 알아보는 시간을 가져보려 합니다.
개발한 소스 코드를 정적 분석을 통해 버그, 취약점, 스타일 등을 탐지하고 이를 시각화시켜
최종적으로 품질 높은 코드를 만들 수 있도록 도와주는 도구입니다.
시작하기에 앞서 우리는 정적 분석과 동적 분석에 대해 알아야 합니다.
소스 코드의 실행 없이 정적으로 프로그램의 문제를 찾는 과정을 의미합니다. 동적 분석과 가장 큰 차이점은 분석 시점으로, 정적 분석은 비 실행시간 환경에서 진행됩니다.
동적 분석은 위에 설명한 정적 분석과 달리 우리가 개발한 코드에 임의의 테스트 코드를 추가하여
프로그램을 직접 실행 및 테스트해 보는 방법을 의미하는 것입니다.

그러면 우리는 왜 직접 실행해서 테스트하지 않는 정적 분석 기법도 사용하는 걸까요?
아래 간단한 예시를 들어보겠습니다.
Public void printLog() {
Log.d("TAG", "hello, World");
}
위 코드를 사용하기 위해서는 어떠한 import 정보가 필요할까요?
바로 android.util.Log가 필요합니다.
만약, 개발자가 임의로 아래와 같이 Log를 지웠다면 앱이 실행시간 동안 어떤 일이 발생할까요?
아마 강제로 종료되거나 하는 큰 일은 일어나지 않을 것입니다. 또한, 개발자가 임의로 지운 내용이니 로그가 안 찍히는 것도 인지하고 있을 것이고요.
Public void printLog() {
}
하지만, 여기에는 숨은 진실이 있습니다.
- 내용이 빈 함수가 남아있음.
- 앞에 import 한 android.util.Log가 남아있음.
위와 같은 내용을 코드 스멜(Code Smell)이라고 하며, 앱을 실행 시켜본다고 확인할 수 있는 내용이 아닙니다.
그럼 우리는 위 내용을 놓치고 Master branch에 Merge를 하면 이후에 누군가가 찾을 때 까기 기다려야 할까요?
다행히 SonarQube의 정적 분석을 통해 위와 같은 부분을 개선할 수 있습니다.

전체 화면은 위와 같이 구성되어 있습니다.
그럼, 하나씩 살펴볼까요?
프로그램에서 발생하고 있는 또는, 발생할 수 있는 결함을 찾아 알려줍니다.
예를 들어 아래와 같은 코드입니다.
class A {
@NonNull
String name;
public A() {
/**TODO**/
}
}
코드에서는 name이 Non Null 어노테이션으로 정의 되어 있지만,
A a = new A();
위와 같이 코드를 생성하면 name은 Null이 됩니다.
이런 결함을 SonarQube에서는 Bug로 잡아줍니다.
소프트웨어를 공격할 수 있는 취약점을 다루는 내용입니다.
위 이미지에서는 취약점과 Security Hotspots이 분리되어 있는데요.
취약점은 지금 당장 공격이 들어올 수 있는 부분으로 반드시 수정해야 하는 부분입니다.
Security Hotspots은 개발자가 취약점 존재 여부를 직접 평가하고, 수정 할지 말지를 결정하는 민감한 코드입니다.
예를 들어 아래 이슈는 broadcasting에서 발생할 수 있는 취약점 및 이전 사례, 해결 방안 등을 제시해 주고 있습니다.

코드 스멜은 아래와 같이 개발자가 작성한 코드가 어떤 이유로 코드 스멜에 감지 되었는지 알려줍니다.

만약, 아래와 같이 Log를 선언하고 사용하지 않는다면 사용하지 않는 import는 제거해 달라는 코드 스멜로 감지됩니다.

또한, 아래와 같이 중복된 코드는 중복되었다고 Duplicated Lines로 감지됩니다.


해당 내용은 유지 보수성에 관련된 내용으로 코드 악취에서 발견된 내용을 전부 수정하는데 얼마 정도의 시간이 걸릴지를 예측해서 알려주는 탭입니다.
위 이미지에서는 111개의 코드 악취를 해결하는데 1일 4시간의 공수가 산출되었습니다.

SonarQube를 확인해 보면 규칙 - 결과 와 같은 내용을 확인 할 수 있습니다.
그럼 이런 규칙을 모두 개발자가 정의 해야 할까요?
다행히 SonarQube는 기본적인 각 언어에 대한 규칙 템플릿을 제공하고 있습니다.
커스텀 프로파일 추가는 해당 링크를 참고해 보는 게 좋을 것 같습니다.

그럼 우리는 SonarQube를 어떻게 하면 적극적으로 활용해 볼 수 있을까요?
첫 번째는 품질 게이트입니다.
품질 게이트는 개발자가 작성한 코드의 최종 점수 와 같은 역할을 합니다.
해당 코드가 이미지에 포함된 규칙을 얼마큼 달성 했느냐에 따라 A ~ E까지 점수를 주며
이를 종합해 아래와 같이 Success / Failed와 같은 결과를 받을 수 있습니다.

이는 해당 앱이 배포할 수 있는 수준인지, 차후 개발에 용이한 깨끗한 Code인지를 판별할 수 있는 지표가 됩니다.
두번째는 이슈 할당 및 관리입니다.

위 이미지와 같이 SonarQube를 활용하면 해당 이슈의 담당자를 지정할 수 있고, 해당 이슈의 담당자는 아래와 같이 이슈를 처리할 수 있습니다.

해당 이슈는 확인/해결/False Positive/Reslove as won't fix 등 4가지 상태로 구성되어 있습니다.
확인 : 이 이슈에 대해 리뷰하였으며, 최종적으로 이후 해결을 위한 활동이 필요합니다.
해결 : 이 이슈는 이미 코드상에서 조치되었으며, 다음번 분석 이후 종료될 예정.
* 실제로 수정되지 않은 경우 재오픈됩니다.False Positive : 분석 엔진의 한계로 인해 오검출된 이슈입니다.
* 이 이슈는 기술 부채에 영향을 주지 않습니다.Reslove as won't fix : 코딩 규칙이 컨텍스트에 맞지 않기 때문에 이 이슈는 무시할 수 있습니다.
* 이 이슈는 기술 부채에 영향을 주지 않습니다.
위와 같은 방법으로 코드 리뷰 및 대응에 보다 적극적인 참여 유도가 가능합니다.

실제로 이슈를 할당 받게 된다면 위와 같이 My Issues로 확인이 가능합니다.
부채라는 단어는 일종의 '빚'으로 다가오는 단어입니다.
그럼, 기술 부채는 기술 빚일까요?
위 내용을 풀어보자면 "나중에 처리하도록 미루어진 기술적인 문제"을 뜻합니다.
즉 코드 스멜 또는 여러 이유로 기술 부채가 증가하게 된다면 차후 개발자는 부채를 처리하기 위해 많은 공수가 발생할 것이고, SonarQube는 해당 내용을 사전에 알려주어 부채의 증가를 예방해 줍니다.

SonarQube에 로그인하여, 프로필 > 보안 > Generate Tokens 를 통해 발급해주세요.
* 한번 발급 받은 토근은 페이지를 벗어나면 확인할 수 없으니 따로 보관해주세요.

복사 붙여넣기도 좋지만 직접 입력해보아요!



SonarQube를 GitHub과 연동하고 이후에 코드 리뷰를 병행하면 좋은 시너지가 발생할 수 있을 것이라 생각됩니다.
긴 글 읽어주셔서 감사합니다.
틀린 내용 or 개선하고 싶은 내용이 있으시다면 편히 글 남겨주세요!