본문 바로가기
Android/이것저것

[Android] 코드 스캔하기 with Lint

by 일상 속 둔치 2023. 4. 9.

높은 코드 퀄리티, 안정성 있는 코드를 작성하기 위해서 다양한 테스트를 진행한다.

Unit Test를 작성함으로 코드가 요구 사항을 만족하는지 동작을 확인할 수도 있고, 필자가 이전에 작성한 Monkey Test등 UI Test 툴을 사용하여 실사용에서의 문제를 체크해볼 수도 있다.

동적 테스트를 수행 했었다면 이번에는 정적 분석을 할 수 있는 툴을 알아보자.

 

1. Lint란?

쉽게 요약하자면 Android Studio에서 제공하는 코드 정적 분석 툴이다.

Lint를 사용하면 소스 파일을 검사하여 잠재적 버그를 찾아내고 정확성, 보안, 성능, 사용성, 접근성, 국제화를 체크 해볼 수 있다.

 

2. Lint 실행 방법

Android 프로젝트에 Lint를 구성하게 되면 프로젝트 빌드시 매번 Lint가 수행되게 되고, 수동으로도 실행할 수 있다.

Lint Report는 termial 마지막에 출력되게 된다. (<Project>/app/build/reports/lint-results.xml)

Lint를 실행 시킬 때 Gradle Wrapper를 사용하거나 독립적인 tool을 사용할 수도 있다.

* 독립적인 tool은 SDK Manager > SDK Tools > Android Studio Commend-line tools로 설치할 수 있다.

./gradlew lint // 기본형
./gradlew lintRelease // 빌드 변형이 된 경우 릴리즈 빌드 검사
./gradlew :<modlue>:lint <modlue> // 특정 모듈만 lint 검사

 

Lint Report

3. Android Studio에서 Lint 확인하기

Analyze > Inspect Code 에서 코드 분석을 통해서 확인할 수 있다.

코드 변집기에서도 경고/위험 표시로 노란색 혹은 빨간색으로 표기해주기도 한다.


4. Lint 설정해보기

기본적으로 Lint를 실행하면 프로젝트의 모든 소스를 검사한다.

그런데 Lint를 적용하고 싶지 않은 케이스가 있을 수 있다.

이런 경우 Lint에서 예외처리를 할 수 있다.

 

1) Lint 항목 확인하기

lint에서 검사하는 항목(id)의 리스트는 아래로 커맨드로 확인할 수 있다.

* lint의 위치는 Android/sdk/cmdline-tools/latest/bin 이다.

lint --list

Lint issue 카테고리와

lint issue id(lint에서 사용할 id)가 무진장 많이 나온다.

 

2) lint.xml로 처리하기

lint.xml은 프로젝트 root에 생성하면 된다.

issue에 id로 검사할 항목을 정하고 severity로 얼마나 엄격하게 검사할 것인가 (경고/무시/에러 등)를 작성해준다.

무시하고 싶은 파일은 issue 항목의 하위 항목으로 ignore 지정해준다.

<?xml version="1.0" encoding="UTF-8"?>
<lint>
    <!-- Disable the given check in this project -->
    <issue id="IconMissingDensityFolder" severity="ignore" />

    <!-- Ignore the ObsoleteLayoutParam issue in the specified files -->
    <issue id="ObsoleteLayoutParam">
        <ignore path="res/layout/activation.xml" />
        <ignore path="res/layout-xlarge/activation.xml" />
    </issue>

    <!-- Ignore the UselessLeaf issue in the specified file -->
    <issue id="UselessLeaf">
        <ignore path="res/layout/main.xml" />
    </issue>

    <!-- Change the severity of hardcoded strings to "error" -->
    <issue id="HardcodedText" severity="error" />
</lint>

 

3) code 내에서 처리하기

java/kotlin 내에서 처리하는 방법은 어노테이션을 사용하는 것이다.

@SuppressLint를 사용하면 해당하는 lint 검사에서 제외된다.

만약 모든 lint 검사를 무시하고 싶으면 @SuppressLint("all")를 사용하자.

@SuppressLint("NewApi")
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main)

xml 내에서 처리하는 방법은 tools:ignore를 사용하는 것이다.

* lint에서 xml 속성을 이해할 수 있게 lint.xml에 tools name space를 선언해주자

namespace xmlns:tools="http://schemas.android.com/tools"
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:ignore="UnusedResources" >

    <TextView
        android:text="@string/auto_update_prompt" />
</LinearLayout>

두 가지 이상 무시하고 싶다면 ","로 구분된 문자열을 사용하면 되고, 전부 무시하고 싶으면 tools:ignore="all" 을 사용하자.

 

4) Gradle에서 처리하기

모듈 build.gradle에서 lint 옵션을 설정할 수 있다.

android {
    ...
    lint {
        // 아래 검사는 무시
        disable 'TypographyFractions','TypographyQuotes'
        // 아래 검사는 수행
        enable 'RtlHardcoded','RtlCompat', 'RtlEnabled'
        // 아래에서 나열한 검사 및 하위 검사들만 실행
        checkOnly 'NewApi', 'InlinedApi'
        // lint 분석 진행률 안보이게 설정
        quiet true
        // 에러 발견 시 빌드 중지 (기본은 true)
        abortOnError false
        // true면 에러만 report
        ignoreWarnings true
        // true면 모든 종속성을 검사, 라이브러리 종속성이 있는 앱에 권장
        checkDependencies true
    }
}
...

 

6) Lint 설정 Snapshot

현재 프로젝트에 설정된 lint를 Snapshot으로 만들어 관리할 수 있다.

gradle에 lintOptions{} 에 baselint flie("lint-baseline.xml")을 선언해주면 된다.

이후에 lint-baselint.xml 파일이 생성되는데, 생성 이후에는 검사 시 해당 파일의 사양대로 검사를 수행한다.

만약 조건을 추가하고 싶다면 아래처럼 baseline 외에 속성으로 추가해주자.

* 파일을 변경하고 싶으면 아예 삭제하고 다시 생성하면 되고, 다른 사람과 공유도 가능하다.

android {
    lintOptions {
        checkOnly 'NewApi', 'HandlerLeak'
        baseline file("lint-baseline.xml")
    }
}

댓글