์ฐ๋ฆฌ๋ ์ ๋ฌด์ ํ๋ซํผ์ ์ ๊ทน์ ์ผ๋ก ์ฌ์ฉํฉ๋๋ค. ์๋ํ๋ธ ์ฝ๋ ํ์ง์ ๋์ ์์ค์ผ๋ก ์ ์งํฉ๋๋ค. ์์ฑ๋ ํ๋ก์ ํธ ์ค ํ๋๋ฅผ ํตํฉํ๋ ๊ฒฝ์ฐ VueJs+ํ์ ์คํฌ๋ฆฝํธ, ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. ๋ฐ๋ผ์ ์ฐ๋ฆฌ๊ฐ ์ด๋ป๊ฒ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋์ง ๋ ์์ธํ ๋ง์ ๋๋ฆฌ๊ณ ์ถ์ต๋๋ค.
์ด ๊ธ์์๋ ์์์ ์ด ๊ฒ์ฒ๋ผ SonarQube ํ๋ซํผ์ ๋ํด ์ด์ผ๊ธฐํ๊ฒ ์ต๋๋ค. ์ฝ๊ฐ์ ์ด๋ก - ์ฒ์์ผ๋ก ๋ฃ๋ ์ฌ๋๋ค์ ์ํ ์ผ๋ฐ์ ์ธ ๋ด์ฉ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์๋ํ๋ธ (์ด์ ์ ์๋)๋ ์ง์์ ์ธ ๊ฒ์ฌ ๋ฐ ์ฝ๋ ํ์ง ์ธก์ ์ ์ํ ์คํ ์์ค ํ๋ซํผ์ ๋๋ค.
MISRA C, MISRA C++, MITRE/CWE ๋ฐ CERT ๋ณด์ ์ฝ๋ฉ ํ์ค์ ๊ท์น์ ๋ฐ๋ผ ์ฝ๋ ๋ถ์ ๋ฐ ์ค๋ฅ ๊ฐ์ง๋ฅผ ์ง์ํฉ๋๋ค. ๋ํ OWASP ์์ 10๊ฐ ๋ฐ CWE/SANS ์์ 25๊ฐ ํ๋ก๊ทธ๋๋ฐ ์ค๋ฅ ๋ชฉ๋ก์์ ์ค๋ฅ๋ฅผ ์ธ์ํ ์๋ ์์ต๋๋ค.
ํ๋ซํผ์ด ๋ค์ํ ๊ธฐ์ฑ ๋๊ตฌ๋ฅผ ์ฌ์ฉํจ์๋ ๋ถ๊ตฌํ๊ณ SonarQube๋ ๊ฒฐ๊ณผ๋ฅผ ๋จ์ผ ๋์๋ณด๋๋ก ์ถ์ํ์ฌ ์คํ ๊ธฐ๋ก์ ์ ์งํจ์ผ๋ก์จ ๊ฐ๋ฐ ์ค ์ํํธ์จ์ด ํ์ง ๋ณํ์ ์ผ๋ฐ์ ์ธ ์ถ์ธ๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
์์ธํ ๋ด์ฉ์ ๋ค์์์ ํ์ธํ ์ ์์ต๋๋ค.
๋ค์ํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๊ฐ ์ง์๋ฉ๋๋ค. ์ ๋งํฌ์ ์ ๋ณด๋ก ํ๋จํ๋ฉด 25๊ฐ ์ด์์ ์ธ์ด๊ฐ ์์ต๋๋ค. ํน์ ์ธ์ด๋ฅผ ์ง์ํ๋ ค๋ฉด ์ ์ ํ ํ๋ฌ๊ทธ์ธ์ ์ค์นํด์ผ ํฉ๋๋ค. ์ปค๋ฎค๋ํฐ ๋ฒ์ ์๋ ์์ ์ ์ํ ํ๋ฌ๊ทธ์ธ์ด ํฌํจ๋์ด ์์ต๋๋ค. ์๋ฐ ์คํฌ๋ฆฝํธ (typesัript ํฌํจ), Wiki์์๋ ๊ทธ ๋ฐ๋๋ผ๊ณ ๋งํฉ๋๋ค. ๋ค์ ์๋ฐ ์คํฌ๋ฆฝํธ ํ๋ฌ๊ทธ์ธ ๋ต๋ณ SonarJS, Typescript์ ๊ฒฝ์ฐ ์๋TS ๊ฐ๊ฐ.
๊ณต์ ํด๋ผ์ด์ธํธ๋ ์ ์ฉ ๋ฒ์ ์ ๋ณด๋ฅผ ๋ณด๋ด๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ์๋ํ๋ธ ์ค์บ๋, ๋ค์์ ์ค์ ์ ์ฌ์ฉํ์ฌ ์ค์ -file, ์ด ๋ฐ์ดํฐ๋ฅผ ์๋ฒ๋ก ๋ณด๋ ๋๋ค. ์๋ํ๋ธ ์ถ๊ฐ ํตํฉ ๋ฐ ์ง๊ณ๋ฅผ ์ํด.
์ ์๋ฐ ์คํฌ๋ฆฝํธ ์ด
์๋ฒ๋ฅผ ๋ฐฐํฌํ๋ ค๋ฉด ์๋ํ๋ธ ์ด์ ์ ํ์ฉํ์ ๋์ปค ์์ฑ.
sonar.yaml:
version: '1'
services:
simplesample-sonar:
image: sonarqube:lts
ports:
- 9001:9000
- 9092:9092
network_mode: bridge
์์ํ๋ค:
docker-compose -f sonar.yml up
๊ทธํ์ ์๋ํ๋ธ ๋ค์์์ ์ด์ฉ ๊ฐ๋ฅํฉ๋๋ค:
์์ง ํ๋ก์ ํธ๊ฐ ์์ผ๋ฉฐ ๊ณตํํฉ๋๋ค. ์ด ์ํฉ์ ๋ฐ๋ก์ก๊ฒ ์ต๋๋ค. ๋๋ ๊ณต์ ์์ ํ๋ก์ ํธ๋ฅผ ๋งก์์ต๋๋ค. VueJS+TS+Jest. ์ฐ๋ฆฌ ์์ ์ ํฅํด ๊ตฌ๋ถ๋ฆฌ์:
git clone https://github.com/vuejs/vue-test-utils-typescript-example.git
๋จผ์ ํด๋ผ์ด์ธํธ๋ฅผ ์ค์นํด์ผ ํฉ๋๋ค ์๋ํ๋ธ๋ผ๋ ์๋ ์ค์บ๋~์ ์ํด npm ๋ํผ๊ฐ ์์ต๋๋ค.
yarn add sonarqube-scanner
๊ทธ๋ฆฌ๊ณ ์ฆ์ ๋ช ๋ น์ ์ถ๊ฐํ์ญ์์ค. ์คํฌ๋ฆฝํธ ๊ทธ๊ฒ์ผ๋ก ์์ ํฉ๋๋ค.
ํจํค์ง.json:
{
โฆ
scripts: {
...
"sonar": "sonar-scanner"
...
},
โฆ
}
๋ค์์ผ๋ก, ์ค์บ๋๊ฐ ์๋ํ๋ ค๋ฉด ํน์ ํ์ผ์์ ํ๋ก์ ํธ ์ค์ ์ ์ง์ ํด์ผ ํฉ๋๋ค. ๊ธฐ๋ณธ๋ถํฐ ์์ํด ๋ณด๊ฒ ์ต๋๋ค.
์๋ ํ๋ก์ ํธ.์์ฑ:
sonar.host.url=http://localhost:9001
sonar.projectKey=test-project-vuejs-ts
sonar.projectName=Test Application (VueJS+TS)
sonar.sources=src
# sonar.tests=
sonar.test.inclusions=src/**/*tests*/**
sonar.sourceEncoding=UTF-8
- ์๋.ํธ์คํธ.url - ์ฃผ์ ์๋'ใ ;
- sonar.projectKey โ ์๋ฒ์ ๊ณ ์ ํ ํ๋ก์ ํธ ์๋ณ์ ์๋'ใ ;
- sonar.ํ๋ก์ ํธ ์ด๋ฆ โ ์ด๋ฆ์ ํ๋ก์ ํธ๊ฐ ๋ค์์ผ๋ก ์๋ณ๋๋ฏ๋ก ์ธ์ ๋ ์ง ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค. ํ๋ก์ ํธํค;
- ์๋ ์์ค โ ์์ค๊ฐ ์๋ ํด๋, ์ผ๋ฐ์ ์ผ๋ก ์ด ํด๋ SRC, ๊ทธ๋ฌ๋ ๋ฌด์์ด๋ ๋ ์ ์์ต๋๋ค. ์ด ํด๋๋ ์ค์บ๋๊ฐ ์คํ๋๋ ํด๋์ธ ๋ฃจํธ ํด๋๋ฅผ ๊ธฐ์ค์ผ๋ก ์ค์ ๋ฉ๋๋ค.
- ์๋.ํ ์คํธ โ ์ด์ ๋งค๊ฐ๋ณ์์ ํจ๊ป ์ฌ์ฉ๋๋ ๋งค๊ฐ๋ณ์์ ๋๋ค. ํ ์คํธ๊ฐ ์์นํ ํด๋์ ๋๋ค. ์ด ํ๋ก์ ํธ์๋ ํด๋น ํด๋๊ฐ ์์ผ๋ฉฐ ํ ์คํธ๋ 'ํด๋์์ ํ ์คํธ์ค์ธ ๊ตฌ์ฑ ์์ ์์ ์์ต๋๋ค.test'์ด๋ฏ๋ก ์ง๊ธ์ ์ด๋ฅผ ๋ฌด์ํ๊ณ ๋ค์ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ๊ฒ ์ต๋๋ค.
- ์๋.ํ ์คํธ.ํฌํจ โ ๋ง์คํฌ๋ฅผ ์ฌ์ฉํ๋ ํ ์คํธ ๊ฒฝ๋ก์๋ ์ฌ๋ฌ ์์๊ฐ ์ผํ๋ก ๊ตฌ๋ถ๋์ด ๋์ด๋ ์ ์์ต๋๋ค.
- sonar.source์ธ์ฝ๋ฉ โ ์์ค ํ์ผ ์ธ์ฝ๋ฉ.
์ค์บ๋๋ฅผ ์ฒ์ ์คํํ๋ ๊ฒฝ์ฐ ์ฃผ์ ์ด์ ์์ ์ ์ ์ธํ ๋ชจ๋ ๊ฒ์ด ์ค๋น๋ฉ๋๋ค. ํ ์คํธ ์์ง ์์ฒด๋ฅผ ์คํํ์ฌ ์ค์บ๋๊ฐ ์ดํ์ ์ฌ์ฉํ ์ ์ฉ ๋ฒ์์ ๋ํ ์ ๋ณด๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
ํ์ง๋ง ์ด๋ ๊ฒ ํ๋ ค๋ฉด ์ด ์ ๋ณด๋ฅผ ์์ฑํ๋๋ก ํ ์คํธ ์์ง์ ๊ตฌ์ฑํด์ผ ํฉ๋๋ค. ์ด ํ๋ก์ ํธ์์ ํ ์คํธ ์์ง์ ๋๋ด. ํด๋น ์ค์ ์ ํ์ผ์ ํด๋น ์น์ ์ ์์ต๋๋ค. package.json.
๋ค์ ์ค์ ์ ์ถ๊ฐํด ๋ณด๊ฒ ์ต๋๋ค.
"collectCoverage": true,
"collectCoverageFrom": [
"src/**/*",
"!src/main.ts",
"!src/App.vue",
"!src/**/*.d.*",
"!src/**/*__tests__*"
],
์ฆ, ์ ์ฉ ๋ฒ์๋ฅผ ๊ณ์ฐํด์ผ ํ๋ ํ์์ฑ๊ณผ ๊ทธ๊ฒ์ด ํ์ฑ๋ ์์ค(์์ธ ํฌํจ)์ ๋ํ ํ๋๊ทธ ์์ฒด๋ฅผ ์ค์ ํฉ๋๋ค.
์ด์ ํ ์คํธ๋ฅผ ์คํํด ๋ณด๊ฒ ์ต๋๋ค.
yarn test
์ฐ๋ฆฌ๋ ๋ค์์ ๋ณผ ๊ฒ์ ๋๋ค:
์ด์ ๋ ์ปดํฌ๋ํธ ์์ฒด์ ์ฝ๋๊ฐ ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด ๋ณด๊ฒ ์ต๋๋ค.
HelloWorld.vue:
...
methods: {
calc(n) {
return n + 1;
}
},
mounted() {
this.msg1 = this.msg + this.calc(1);
},
...
์ด๋ ์ ์ฉ ๋ฒ์๋ฅผ ๊ณ์ฐํ๋ ๋ฐ ์ถฉ๋ถํฉ๋๋ค.
ํ ์คํธ๋ฅผ ๋ค์ ์์ํ ํ ๋ค์ ์ฌํญ์ ํ์ธํฉ๋๋ค.
ํ๋ฉด์ ์ ์ฉ ๋ฒ์์ ๋ํ ์ ๋ณด๊ฐ ํ์๋๊ณ ํ๋ก์ ํธ ํด๋์ ํด๋๊ฐ ์์ฑ๋ฉ๋๋ค. ์ ์ฉ ๋ฒ์ ๋ฒ์ฉ ํ์์ ํ ์คํธ ์ปค๋ฒ๋ฆฌ์ง ์ ๋ณด ํฌํจ LCOV(LTP GCOV ํ์ฅ).
Gcov ์ฝ๋ ์ ์ฉ ๋ฒ์๋ฅผ ๊ฒ์ฌํ๊ธฐ ์ํด ๋ฌด๋ฃ๋ก ๋ฐฐํฌ๋๋ ์ ํธ๋ฆฌํฐ์ ๋๋ค. Gcov๋ ํ๋ก๊ทธ๋จ์ ๊ฐ ๋ช ๋ น๋ฌธ์ ๋ํ ์ ํํ ์คํ ํ์๋ฅผ ์์ฑํ๊ณ ์์ค ์ฝ๋์ ์ฃผ์์ ์ถ๊ฐํ ์ ์๋๋ก ํฉ๋๋ค. Gcov๋ GCC ํจํค์ง์ ์ผ๋ถ๋ก ํ์ค ์ ํธ๋ฆฌํฐ๋ก ์ ๊ณต๋ฉ๋๋ค.
๋ฆฌ์ฝ๋ธ - gcov์ฉ ๊ทธ๋ํฝ ์ธํฐํ์ด์ค. ์ฌ๋ฌ ์์ค ํ์ผ์ ๋ํ gcov ํ์ผ์ ์กฐํฉํ๊ณ ์ฝ๋ ๋ฐ ์ ์ฉ ๋ฒ์ ์ ๋ณด๊ฐ ํฌํจ๋ HTML ํ์ด์ง ์ธํธ๋ฅผ ์์ฑํฉ๋๋ค. ํ์์ ๋ ์ฝ๊ฒ ํ๊ธฐ ์ํด ํ์ด์ง๋ ์์ฑ๋ฉ๋๋ค. Lcov๋ ๋ฌธ์์ด, ํจ์ ๋ฐ ๋ถ๊ธฐ์ ์ ์ฉ ๋ฒ์๋ฅผ ์ง์ํฉ๋๋ค.
ํ
์คํธ๊ฐ ์๋ฃ๋ ํ ์ ์ฉ ๋ฒ์ ์ ๋ณด๋ ๋ค์์์ ํ์ธํ ์ ์์ต๋๋ค. ์ ์ฉ ๋ฒ์/lcov.info.
์ฐ๋ฆฌ๋ ๋งํ ํ์๊ฐ ์๋'์ด๋์ ๊ตฌํ ์ ์๋์? ๋ฐ๋ผ์ ๊ตฌ์ฑ ํ์ผ์ ๋ค์ ์ค์ ์ถ๊ฐํด ๋ณด๊ฒ ์ต๋๋ค. ๊ทธ๋ฌ๋ ํ ๊ฐ์ง ์ ์ด ์์ต๋๋ค. ํ๋ก์ ํธ๋ ๋ค๊ตญ์ด, ์ฆ ํด๋์ ์์ ์ ์์ต๋๋ค. SRC ์ฌ๋ฌ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ๋ํ ์์ค ์ฝ๋์ ํ๋ ๋๋ ๋ค๋ฅธ ์ธ์ด์์ ์ ํด๊ฐ ์์ผ๋ฉฐ, ํ๋ ๋๋ ๋ค๋ฅธ ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉ์ ํ์ฅ์ ๋ฐ๋ผ ๊ฒฐ์ ๋ฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ ์ฉ ๋ฒ์ ์ ๋ณด๋ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ง๋ค ๋ค๋ฅธ ์์น์ ์ ์ฅ๋ ์ ์์ผ๋ฏ๋ก ๊ฐ ์ธ์ด์๋ ์ด๋ฅผ ์ค์ ํ๊ธฐ ์ํ ์์ฒด ์น์
์ด ์์ต๋๋ค. ์ฐ๋ฆฌ ํ๋ก์ ํธ์์๋ ํ์ดํ ์คํฌ๋ฆฝํธ, ๋ฐ๋ผ์ ์ด์ ๋ํ ์ค์ ์น์
์ด ํ์ํฉ๋๋ค.
์๋ ํ๋ก์ ํธ.์์ฑ:
sonar.typescript.coveragePlugin=lcov
sonar.typescript.lcov.reportPaths=coverage/lcov.info
์ค์บ๋์ ์ฒซ ๋ฒ์งธ ์คํ์ ์ํ ๋ชจ๋ ์ค๋น๊ฐ ์๋ฃ๋์์ต๋๋ค. ์ด ํ๋ก์ ํธ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ์๋'e๋ ํน์ ํ๋ก์ ํธ์ ๋ํด ์ค์บ๋๋ฅผ ์ฒ์ ์คํํ ๋ ์๋์ผ๋ก ์์ฑ๋ฉ๋๋ค. ์ดํ์๋ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ํ๋ก์ ํธ ๋งค๊ฐ๋ณ์์ ์ญํ์ ๋ณํ๋ฅผ ํ์ธํ๊ธฐ ์ํด ์ ๋ณด๊ฐ ์ถ์ ๋ ๊ฒ์ ๋๋ค.
๊ทธ๋ผ ์์์ ๋ง๋ ๋ช ๋ น์ ์ฌ์ฉํด ๋ณด๊ฒ ์ต๋๋ค. package.json:
yarn run sonar
์ฐธ๊ณ : ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ ์๋ ์์ต๋๋ค. -X ๋ ์์ธํ ๋ก๊น ์ ์ํ์๋ฉด
์ค์บ๋๊ฐ ์ฒ์์ผ๋ก ์์๋ ๊ฒฝ์ฐ ์ค์บ๋ ์์ฒด์ ๋ฐ์ด๋๋ฆฌ๊ฐ ๋จผ์ ๋ค์ด๋ก๋๋ฉ๋๋ค. ๊ทธ ํ ์๋ฒ ๊ฒ์์ด ์์๋๊ณ ์์๋ฉ๋๋ค. ์๋'a ์ค์น๋ ํ๋ฌ๊ทธ์ธ์ ๋ํด ์ง์๋๋ ์ธ์ด๋ฅผ ๊ณ์ฐํฉ๋๋ค. ํด๋น ์์ ์ ์ํ ๋ค์ํ ๊ธฐํ ๋งค๊ฐ๋ณ์๋ ๋ก๋๋ฉ๋๋ค. ํ์ง ํ๋กํ, ํ์ฑ ๊ท์น, ์งํ ์ ์ฅ์, ์๋ฒ ๊ท์น.
์ฐธ๊ณ : ์ด ๊ธฐ์ฌ์ ํ ๋ด์์ ์ด์ ๋ํด ์์ธํ ์ค๋ช ํ์ง๋ ์์ง๋ง ์ธ์ ๋ ์ง ๊ณต์ ์์ค์ ๋ฌธ์ํ ์ ์์ต๋๋ค.
๋ค์์ผ๋ก ํด๋ ๋ถ์์ด ์์๋ฉ๋๋ค SRC ํ์ ์ธ๋ฑ์ฑ์ ํตํด ์ง์๋๋ ๋ชจ๋ ์ธ์ด(ํน์ ์ธ์ด๊ฐ ๋ช ์์ ์ผ๋ก ์ง์ ๋์ง ์์ ๊ฒฝ์ฐ)์ ๋ํ ์์ค ํ์ผ์ ๊ฐ์ฉ์ฑ์ ํ์ธํฉ๋๋ค.
๋ค์์๋ ์ด ๊ธฐ์ฌ์์ ๋ค๋ฃจ์ง ์๋ ๋ค์ํ ๋ค๋ฅธ ๋ถ์(์: ๋ฆฐํ , ์ฝ๋ ์ค๋ณต ๊ฐ์ง ๋ฑ)์ด ๋์ต๋๋ค.
์ค์บ๋ ์์ ์ด ๋๋๋ฉด ์์ง๋ ๋ชจ๋ ์ ๋ณด๊ฐ ์ง๊ณ, ๋ณด๊ด๋์ด ์๋ฒ๋ก ์ ์ก๋ฉ๋๋ค.
๊ทธ ํ์ ์น ์ธํฐํ์ด์ค์์ ๋ฌด์จ ์ผ์ด ์ผ์ด๋ฌ๋์ง ์ด๋ฏธ ๋ณผ ์ ์์ต๋๋ค.
๋ณด์๋ค์ํผ ๋ญ๊ฐ ํจ๊ณผ๊ฐ ์์๊ณ ์ฌ์ง์ด ์ด๋ค ์ข ๋ฅ์ ๋ณด๋๋ ๋ณด์ฌ ์ฃผ์์ง๋ง ์ฐ๋ฆฌ์ ๊ฒ๊ณผ ์ผ์นํ์ง ์์ต๋๋ค. ๋๋ด-๋ณด๊ณ ์.
๊ทธ๊ฒ์ ์์ ๋ด ์๋ค. ํ๋ก์ ํธ๋ฅผ ๋ ์์ธํ ์ดํด๋ณด๊ณ ์ ์ฉ ๋ฒ์ ๊ฐ์ ํด๋ฆญํ ๋ค์ ์์ธํ ํ์ผ ๋ณด๊ณ ์๋ฅผ "์ ์ฒด" ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ฌ๊ธฐ์๋ ๊ฒ์ฌ๋ ๊ธฐ๋ณธ ํ์ผ ์ธ์๋ HelloWorld.vue, ํ์ผ๋ ์์ต๋๋ค main.ts, ์ด๋ ๋ณด๋์ ์ ์ฒด ๊ทธ๋ฆผ์ ๋ง์นฉ๋๋ค. ๊ทธ๋ฐ๋ฐ ์ ๋ณด์ฅ ๋ฒ์ ๊ณ์ฐ์์ ์ ์ธํ๋์ง์. ์, ๋ชจ๋ ๊ฒ์ด ์ ํํฉ๋๋ค. ํ์ง๋ง ์์ค์ ์์์ต๋๋ค. ๋๋ด, ๊ทธ๋ฌ๋ ์ค์บ๋๊ฐ ์ด๋ฅผ ์์ธํํ๊ธฐ ๋๋ฌธ์ ๊ฒฐ๊ตญ ๊ณ์ฐ์ ํฌํจ๋์์ต๋๋ค.
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด ๋ณด๊ฒ ์ต๋๋ค.
์๋ ํ๋ก์ ํธ.์์ฑ:
...
sonar.exclusions=src/main.ts
...
๋ช ํํ๊ฒ ์ค๋ช ํ๊ณ ์ถ์ต๋๋ค. ์ด ๋งค๊ฐ๋ณ์์ ์ง์ ๋ ํด๋ ์ธ์๋ ๋งค๊ฐ๋ณ์์ ๋์ด๋ ๋ชจ๋ ํด๋๋ ์ถ๊ฐ๋ฉ๋๋ค. ์๋.ํ ์คํธ.ํฌํจ.
์ค์บ๋๋ฅผ ์คํํ๋ฉด ์ฌ๋ฐ๋ฅธ ์ ๋ณด๊ฐ ํ์๋ฉ๋๋ค.
๋ค์ ์์ ์ ์ดํด ๋ณด๊ฒ ์ต๋๋ค. ํ์ง ํ๋กํ. ์์์ ์ง์์ ๋ํด ์ด์ผ๊ธฐํ์ต๋๋ค. ์๋๋์์ ์ฌ๋ฌ ์ธ์ด๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ด๊ฒ์ด ๋ฐ๋ก ์ฐ๋ฆฌ๊ฐ ๋ณด๊ณ ์๋ ๊ฒ์ ๋๋ค. ํ์ง๋ง ์ฐ๋ฆฌ๋ ์ฐ๋ฆฌ ํ๋ก์ ํธ๊ฐ ๋ค์ ์ธ์ด๋ก ์์ฑ๋์๋ค๋ ๊ฒ์ ์๊ณ ์์ต๋๋ค. TS, ๊ทธ๋ ๋ค๋ฉด ๋ถํ์ํ ์กฐ์๊ณผ ํ์ธ์ผ๋ก ์ค์บ๋์ ๋ถ๋ด์ ์ฃผ๋ ์ด์ ๋ ๋ฌด์์ ๋๊น? ๊ตฌ์ฑ ํ์ผ์ ๋งค๊ฐ๋ณ์๋ฅผ ํ๋ ๋ ์ถ๊ฐํ์ฌ ๋ถ์ํ ์ธ์ด๋ฅผ ์ค์ ํ๊ฒ ์ต๋๋ค. ์๋'ใ :
์๋ ํ๋ก์ ํธ.์์ฑ:
...
sonar.language=ts
...
์ค์บ๋๋ฅผ ๋ค์ ์คํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํด ๋ณด๊ฒ ์ต๋๋ค.
์ปค๋ฒ๋ ฅ์ด ์์ ์์ด์ก์ต๋๋ค.
์ค์บ๋ ๋ก๊ทธ๋ฅผ ๋ณด๋ฉด ๋ค์ ์ค์ ๋ณผ ์ ์์ต๋๋ค.
์ฆ, ํ๋ก์ ํธ ํ์ผ์ด ์์ธํ๋์ง ์์์ต๋๋ค.
์ํฉ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ๊ณต์์ ์ผ๋ก ์ง์๋ฉ๋๋ค. VueJ ํ๋ฌ๊ทธ์ธ์ ์์ต๋๋ค SonarJS, ๋๊ฐ ์ฑ ์์ ์ง๋๊ฐ ์๋ฐ ์คํฌ๋ฆฝํธ.
ํ์ง๋ง ์ด ์ง์์ ํ๋ฌ๊ทธ์ธ์ ์์ต๋๋ค ์๋TS ์ TS, ๋ฒ๊ทธ ์ถ์ ๊ธฐ์์ ๊ณต์ ํฐ์ผ์ด ๊ฐ์ค๋์์ต๋๋ค. ์๋'ใ :
๋ค์์ ์ด ์ฌ์ค์ ํ์ธํ๋ SonarQube ๊ฐ๋ฐ์ ๋ํ ์ค ํ ์ฌ๋์ ๋ต๋ณ์ ๋๋ค.
ํ์ง๋ง ๋ชจ๋ ๊ฒ์ด ์ฐ๋ฆฌ์๊ฒ ๋์์ด ๋์๋ค๊ณ ๋น์ ์ ๋ฐ๋ํฉ๋๋ค. ์, ์ข ํด๋ณด์ "๋ง๊ตฌ ์๋ฅด๊ธฐ".
์ง์์ด ์๋ ๊ฒฝ์ฐ .vue-ํ์ผ ์๋'์, ๊ทธ๋ผ ๊ทธ์๊ฒ ๊ทธ๊ฒ๋ค์ ๋ค์๊ณผ ๊ฐ์ด ์๊ฐํ๋ผ๊ณ ๋งํด๋ณด์ ํ์ดํ ์คํฌ๋ฆฝํธ.
๋งค๊ฐ๋ณ์๋ฅผ ์ถ๊ฐํด ๋ณด๊ฒ ์ต๋๋ค.
์๋ ํ๋ก์ ํธ.์์ฑ:
...
sonar.typescript.file.suffixes=.ts,.tsx,.vue
...
์ค์บ๋๋ฅผ ์คํํด ๋ด ์๋ค:
๊ทธ๋ฆฌ๊ณ ์ง์, ๋ชจ๋ ๊ฒ์ด ์ ์์ผ๋ก ๋์์์ต๋๋ค. ํ์ดํ ์คํฌ๋ฆฝํธ. ์ฆ, ์ฐ๋ฆฌ๋ ์ง์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ต๋๋ค. VueJs+TS ์ ์๋ํ๋ธ.
๋ ๋์๊ฐ ์ปค๋ฒ๋ฆฌ์ง ์ ๋ณด๋ฅผ ์กฐ๊ธ ๋ ๊ฐ์ ํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
์ง๊ธ๊น์ง ์ฐ๋ฆฌ๊ฐ ํ ์ผ:
- ํ๋ก์ ํธ์ ์ถ๊ฐ๋จ ์๋-์ค์บ๋;
- ์ค์ ๋๋ด ์ ์ฉ ๋ฒ์ ์ ๋ณด๋ฅผ ์์ฑํ๊ธฐ ์ํด;
- ๊ตฌ์ฑ๋ ์๋-์ค์บ๋;
- ์ง์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ต๋๋ค .vue-ํ์ผ + ํ์ดํ ์คํฌ๋ฆฝํธ.
ํ ์คํธ ๋ฒ์ ์ธ์๋ ์ฝ๋ ํ์ง์ ๋ํ ๋ค๋ฅธ ํฅ๋ฏธ๋กญ๊ณ ์ ์ฉํ ๊ธฐ์ค์ด ์์ต๋๋ค. ์๋ฅผ ๋ค์ด ํ๋ก์ ํธ์ ์ฝ๋ ์ค๋ณต ๋ฐ ์ค ์(์ฝ๋ ๋ณต์ก์ฑ๊ณผ ๊ด๋ จ๋ ๊ณ์ ๊ณ์ฐ์ ํฌํจ)๊ฐ ์์ต๋๋ค.
์์ ์ ์ํ ํ๋ฌ๊ทธ์ธ์ ํ์ฌ ๊ตฌํ์์ TS (์๋TS) ์๋ ์ ํ ๊ฒ์ด๋ค CPD(๋ณต์ฌ ๋ถ์ฌ๋ฃ๊ธฐ ๊ฐ์ง๊ธฐ) ์ฝ๋ ์ค์ ์ธ๋ ์ค .vue-ํ์ผ.
์ฝ๋ ์ค๋ณต์ ํฉ์ฑ ์ํฉ์ ๋ง๋ค๋ ค๋ฉด ๊ตฌ์ฑ ์์ ํ์ผ์ ๋ค๋ฅธ ์ด๋ฆ์ผ๋ก ๋ณต์ ํ๊ณ ์ฝ๋์ ์ถ๊ฐํ๋ฉด ๋ฉ๋๋ค. main.ts ๋๋ฏธ ํจ์๋ฅผ ๋ง๋ค๊ณ ๋ค๋ฅธ ์ด๋ฆ์ผ๋ก ๋ณต์ ํฉ๋๋ค. ๋ค์๊ณผ ๊ฐ์ด ์ค๋ณต์ ํ์ธํ๋ ค๋ฉด .vue,์์ .ts -ํ์ผ.
main.ts:
...
function name(params:string): void {
console.log(params);
}
...
์ด๋ ๊ฒ ํ๋ ค๋ฉด ๊ตฌ์ฑ ์ค์ ์ผ์์ ์ผ๋ก ์ฃผ์ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค.
์๋ ํ๋ก์ ํธ.์์ฑ:
...
sonar.exclusions=src/main.ts
...
ํ ์คํธ์ ํจ๊ป ์ค์บ๋๋ฅผ ๋ค์ ์์ํด ๋ณด๊ฒ ์ต๋๋ค.
yarn test && yarn run sonar
๋ฌผ๋ก ์ฐ๋ฆฌ์ ๋ณด์ฅ ๋ฒ์๋ ๋จ์ด์ง๊ฒ ์ง๋ง ์ง๊ธ์ ๊ทธ๊ฒ์ ๊ด์ฌ์ด ์์ต๋๋ค.
์ฝ๋ ์ค์ ๋ณต์ ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํ์๋ฉ๋๋ค.
ํ์ธํ๊ธฐ ์ํด ์ฐ๋ฆฌ๋ ์ฌ์ฉํ ๊ฒ์ ๋๋ค CPD-๊ณต์ต์ฌ์ - jscpd:
npx jscpd src
์ฝ๋ ์ค์ ๊ฒฝ์ฐ:
์๋ง๋ ์ด ๋ฌธ์ ๋ ํฅํ ํ๋ฌ๊ทธ์ธ ๋ฒ์ ์์ ํด๊ฒฐ๋ ๊ฒ์ ๋๋ค. ์๋JS(TS). ๋๋ ๊ทธ๋ค์ด ์ ์ฐจ์ ์ผ๋ก ์ด ๋ ํ๋ฌ๊ทธ์ธ์ ํ๋๋ก ๋ณํฉํ๊ธฐ ์์ํ๋ค๋ ์ ์ ์ฃผ๋ชฉํ๊ณ ์ถ์ต๋๋ค. SonarJS, ๋ด ์๊ฐ์ ๊ทธ๊ฒ ๋ง๋ ๊ฒ ๊ฐ์.
์ด์ ๋ณด์ฅ ์ ๋ณด๋ฅผ ๊ฐ์ ํ๋ ์ต์ ์ ๊ณ ๋ คํ๊ณ ์ถ์์ต๋๋ค.
์ง๊ธ๊น์ง ์ ์ฒด ํ๋ก์ ํธ, ํนํ ํ์ผ์ ๋ํ ํ ์คํธ ์ ์ฉ ๋ฒ์๋ฅผ ๋ฐฑ๋ถ์จ๋ก ๋ณผ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ์๋์ ๋ํ ์ ๋ณด๋ก ์ด ์งํ๋ฅผ ํ์ฅํ๋ ๊ฒ์ด ๊ฐ๋ฅํฉ๋๋ค. ๋จ์-ํ์ผ ์ปจํ ์คํธ๋ฟ๋ง ์๋๋ผ ํ๋ก์ ํธ์ ๋ํ ํ ์คํธ๋ ์ํํฉ๋๋ค.
ํ ์ ์๋ ๋์๊ด์ด ์์ด์ ๋๋ด-๋ณด๊ณ ์๋ฅผ ๋ค์ ํ์์ผ๋ก ๋ณํํฉ๋๋ค. ์๋'ใ
:
์ผ๋ฐ ํ
์คํธ ๋ฐ์ดํฐ -
ํ๋ก์ ํธ์ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํด ๋ณด๊ฒ ์ต๋๋ค.
yarn add jest-sonar-reporter
๊ทธ๋ฆฌ๊ณ ๊ทธ๊ฒ์ ๊ตฌ์ฑ์ ์ถ๊ฐํ์ญ์์ค. ๋๋ด:
ํจํค์ง.json:
โฆ
"testResultsProcessor": "jest-sonar-reporter"
โฆ
์ด์ ํ ์คํธ๋ฅผ ์คํํด ๋ณด๊ฒ ์ต๋๋ค.
yarn test
๊ทธ๋ฐ ๋ค์ ํ๋ก์ ํธ ๋ฃจํธ์ ํ์ผ์ด ์์ฑ๋ฉ๋๋ค. ํ ์คํธ ๋ณด๊ณ ์.xml.
๊ตฌ์ฑ์ ์ฌ์ฉํด ๋ณด๊ฒ ์ต๋๋ค. ์๋'ใ :
์๋ ํ๋ก์ ํธ.์์ฑ:
โฆ
sonar.testExecutionReportPaths=test-report.xml
โฆ
๊ทธ๋ฆฌ๊ณ ์ค์บ๋๋ฅผ ๋ค์ ์์ํ์ญ์์ค.
yarn run sonar
์ธํฐํ์ด์ค์์ ๋ฌด์์ด ๋ณ๊ฒฝ๋์๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค. ์๋'ใ :
๊ทธ๋ฆฌ๊ณ ์๋ฌด๊ฒ๋ ๋ณํ์ง ์์์ต๋๋ค. ์ฌ์ค Sonar๋ Jest ๋ณด๊ณ ์์ ์ค๋ช ๋ ํ์ผ์ ํ์ผ๋ก ๊ฐ์ฃผํ์ง ์์ต๋๋ค. ๋จ์-ํ ์คํธ. ์ด ์ํฉ์ ์์ ํ๊ธฐ ์ํด ๊ตฌ์ฑ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์๋ ์๋.ํ ์คํธ, ํ ์คํธ๊ฐ ํฌํจ๋ ํด๋๋ฅผ ๋ช ์์ ์ผ๋ก ํ์ํฉ๋๋ค(ํ์ฌ๋ ํ๋๋ง ์์).
์๋ ํ๋ก์ ํธ.์์ฑ:
โฆ
sonar.tests=src/components/__tests__
โฆ
์ค์บ๋๋ฅผ ๋ค์ ์์ํด ๋ณด๊ฒ ์ต๋๋ค.
yarn run sonar
์ธํฐํ์ด์ค์์ ๋ฌด์์ด ๋ณ๊ฒฝ๋์๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค.
์ด์ ์ฐ๋ฆฌ๋ ์ฐ๋ฆฌ์ ์ซ์๋ฅผ ๋ณด์์ต๋๋ค. ๋จ์-ํ ์คํธ๋ฅผ โโ์ํํ๊ณ ๋ด๋ถ๋ฅผ ํด๋ฆญํ์ฌ ์คํจํ๋ฉด ํ๋ก์ ํธ ํ์ผ ๊ฐ์ ์ด ๋ฒํธ์ ๋ถํฌ๋ฅผ ๋ณผ ์ ์์ต๋๋ค.
๊ฒฐ๋ก
๊ทธ๋์ ์ฐ๋ฆฌ๋ ์ง์์ ์ธ ๋ถ์์ ์ํ ๋๊ตฌ๋ฅผ ์ดํด๋ณด์์ต๋๋ค. ์๋ํ๋ธ. ์ฐ๋ฆฌ๋ ๋ค์์ผ๋ก ์์ฑ๋ ํ๋ก์ ํธ๋ฅผ ์ฑ๊ณต์ ์ผ๋ก ํตํฉํ์ต๋๋ค. VueJs+TS. ์ผ๋ถ ํธํ์ฑ ๋ฌธ์ ๋ฅผ ์์ ํ์ต๋๋ค. ํ ์คํธ ์ปค๋ฒ๋ฆฌ์ง ์งํ์ ์ ๋ณด ๋ด์ฉ์ ๋๋ ธ์ต๋๋ค. ์ด ๊ธฐ์ฌ์์๋ ์ฝ๋ ํ์ง ๊ธฐ์ค ์ค ํ๋๋ง(์๋ง๋ ์ฃผ์ ๊ธฐ์ค ์ค ํ๋) ์กฐ์ฌํ์ง๋ง ์๋ํ๋ธ ์์ ํ ์คํธ๋ฅผ ํฌํจํ ๊ธฐํ ํ์ง ๊ธฐ์ค์ ์ง์ํฉ๋๋ค. ํ์ง๋ง ์ด๋ฌํ ๊ธฐ๋ฅ ์ค ์ผ๋ถ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ์ปค๋ฎค๋ํฐ-๋ฒ์ . ํฅ๋ฏธ๋กญ๊ณ ์ ์ฉํ ๊ธฐ๋ฅ ์ค ํ๋๋ ํตํฉ์ ๋๋ค. ์๋ํ๋ธ GitLab, BitBucket ๋ฑ ๋ค์ํ ์ฝ๋ ์ ์ฅ์ ๊ด๋ฆฌ ์์คํ ์ ๊ฐ์ถ๊ณ ์์ต๋๋ค. ๋ฐฉ์งํ๊ธฐ ์ํด ๋ณํฉ ํ(๋ณํฉ) ์์ฒญ'๋ฒ์๊ฐ ์ ํ๋๋ฉด ์ ์ฅ์์ ์ฃผ์ ๋ถ๊ธฐ๋ก ์ด๋ํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ด๊ฒ์ ์์ ํ ๋ค๋ฅธ ๊ธฐ์ฌ์ ๋ํ ์ด์ผ๊ธฐ์ ๋๋ค.
์ถ์ : ์ฝ๋ ํ์์ผ๋ก ๊ธฐ์ฌ์ ์ค๋ช
๋ ๋ชจ๋ ๋ด์ฉ์ ๋ค์์์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ฑ๋ก๋ ์ฌ์ฉ์๋ง ์ค๋ฌธ ์กฐ์ฌ์ ์ฐธ์ฌํ ์ ์์ต๋๋ค.
SonarQube ํ๋ซํผ์ ์ฌ์ฉํ์๋์?
-
26,3%์5
-
15,8%3
-
15,8%์ด ํ๋ซํผ์ ๋ํด ๋ค์๊ณ ์ฌ์ฉํ๊ณ ์ถ์ต๋๋ค3
-
10,5%์ด ํ๋ซํผ์ ๋ํด ๋ค์์ง๋ง ์ฌ์ฉํ๊ณ ์ถ์ง ์์ต๋๋ค2
-
0,0%๋ค๋ฅธ ํ๋ซํผ์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค0
-
31,6%์ฒ์์ผ๋ก ๊ทธ๋ ์ ๋ํด ๋ค์ด๋ดค์ต๋๋ค6
19๋ช
์ ์ฌ์ฉ์๊ฐ ํฌํํ์ต๋๋ค. 3๋ช
์ ์ฌ์ฉ์๊ฐ ๊ธฐ๊ถํ์ต๋๋ค.
์ถ์ฒ : habr.com