JiwonDev

JVM์˜ ์›๋ฆฌ์™€ ๋ฐ”์ดํŠธ์ฝ”๋“œ

by JiwonDev

ํ•ด๋‹น ๊ธ€์€ https://www.inflearn.com/course/the-java-code-manipulation/ ๋ฅผ ๊ณต๋ถ€ํ•˜๊ณ  ์ •๋ฆฌํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.

 

#1 JVM ์šฉ์–ด ์ •๋ฆฌ

2021.06.30 - [๊ธฐ๋ณธ ์ง€์‹/Java ๊ธฐ๋ณธ์ง€์‹] - JVM(์ž๋ฐ”๊ฐ€์ƒ๋จธ์‹ )๊ณผ JRE, JDK

์ž๋ฐ” ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋Š” JRE(์ž๋ฐ” ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ)์—์„œ ๋™์ž‘ํ•œ๋‹ค. JRE์—๋Š” [JVM]๊ณผ [์ž๋ฐ” API] ์˜์—ญ์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค.

์ตœ๊ทผ ์ž๋ฐ” ์ŠคํŽ™์—์„œ๋Š” JRE๋ฅผ ๋ณ„๋„๋กœ ์ œ๊ณตํ•˜์ง€ ์•Š๊ณ , ๊ฐœ๋ฐœ๋„๊ตฌ์™€ ํ•จ๊ป˜ JDK๋กœ ํฌ์žฅํ•˜์—ฌ ์ œ๊ณตํ•œ๋‹ค.

  • JVM (Java Virtual Machine)
    - ๋ฐ”์ดํŠธ์ฝ”๋“œ(.class)๋ฅผ ํ•ด๋‹น OS์— ํŠนํ™”๋œ ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค. ์ธํ„ฐํ”„๋ฆฌํ„ฐ์™€ JIT์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
    - JVM์€ API ์ŠคํŽ™๋งŒ ์ œ๊ณตํ•  ๋ฟ, ํŠน์ • ํšŒ์‚ฌ๊ฐ€ ๋งŒ๋“  ์›ํ•˜๋Š” ๊ตฌํ˜„์ฒด(๋ฒค๋”)๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋‹ค.
    - JVM ํ”„๋กœ๊ทธ๋žจ์€ ํŠน์ • ํ”Œ๋žซํผ์— ์ข…์†์ ์ด๋‹ค. ์ž๋ฐ”๋Š” ๊ฐ ํ”Œ๋žซํผ์— ๋งž๋Š” JVM์„ ์ œ๊ณตํ•œ๋‹ค.
     
  • JIT ์ปดํŒŒ์ผ๋Ÿฌ (Just In Time)
    - ์ž๋ฐ”์˜ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋Š” ์ธํ„ฐํ”„๋ฆฌํ„ฐ ๋ฐฉ์‹์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ฆ‰์‹œ ์ฝ์–ด๋“ค์—ฌ ๋™์ž‘ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.
    - ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์˜ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด, ์ดˆ๊ธฐ ์‹คํ–‰์‹œ์ ์— ์ž์ฃผ ์‚ฌ์šฉ๋ ๋งŒํ•œ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ๋ฏธ๋ฆฌ ๊ธฐ๊ณ„์–ด๋กœ ํ•ด์„ํ•˜์—ฌ ์ €์žฅ(์บ์‹ฑ)ํ•ด๋†จ๋‹ค ์žฌ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์ด๋ฅผ JIT ์ปดํŒŒ์ผ ๋ฐฉ์‹์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

  • JRE (Java Runtime Environment): JVM + ์ž๋ฐ” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ API
    - ์ž๋ฐ” ์•ฑ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌ์„ฑ๋œ ๋ฐฐํฌ์šฉ ํ”„๋กœ๊ทธ๋žจ์ด๋‹ค.
    - JVM๊ณผ ํ•ต์‹ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฐ ์ž๋ฐ” ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ์— ์‚ฌ์šฉ๋˜๋Š” ์„ค์ •๊ฐ’๊ณผ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
    - ๊ฐœ๋ฐœ๊ณผ ๊ด€๋ จ๋œ ๋„๊ตฌ๋Š” ํฌํ•จํ•˜์ง€ ์•Š๋Š”๋‹ค. (* ์˜ค๋ผํด11๋ถ€ํ„ฐ JRE๋Š” ๋”ฐ๋กœ ์ œ๊ณตํ•ด์ฃผ๊ณ  ์žˆ์ง€์•Š๋‹ค. JDK๋กœ ์ œ๊ณต)

  • JDK (Java Development Kit)
    - JRE + ์ž๋ฐ” ์ปดํŒŒ์ผ๋Ÿฌ, ์ž๋ฐ” ๊ฐœ๋ฐœ ๋„๊ตฌ
    - Java ์ฝ”๋“œ๋Š” JDK์— ์žˆ๋Š” ์ปดํŒŒ์ผ๋Ÿฌ(javac)๋ฅผ ํ†ตํ•ด ๋Ÿฐํƒ€์ž„์— ์‚ฌ์šฉ๋˜๋Š” ๋ฐ”์ดํŠธ์ฝ”๋“œ(.class)๋กœ ์ปดํŒŒ์ผ ๋œ๋‹ค.
    - OpenJDK ๋ฒค๋”๋Š” ์˜คํ”ˆ์†Œ์Šค์ด์ง€๋งŒ [์˜ค๋ผํด SE]๋Š” ํŒจํ‚ค์ง€๋กœ ํŒ๋งคํ•ด์™”๋‹ค. 2019๋…„ ๋ถ€ํ„ฐ ๊ตฌ๋…ํ˜• ๊ฒฐ์ œ๋กœ ๋ณ€๊ฒฝ๋จ.
  • JVM์˜ ์œ ์—ฐํ•œ ์–ธ์–ด์ง€์›, Java์™€ Kotlin
    - ์œ„์—์„œ ๋งํ–ˆ๋“ฏ์ด, ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ์–ธ์–ด๋Š” ์ž๋ฐ”๋งŒ ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค.
    - ๋Œ€ํ‘œ์ ์œผ๋กœ Kotlin๊ณผ Scala. ๊ทธ๋ฆฌ๊ณ  ํด๋กœ์ €, ๊ทธ๋ฃจ๋น„, JRuby, Jython(๋‹ค๋ฅธ ์–ธ์–ด๋ฅผ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋กœ ์ „ํ™˜)์ด ์žˆ๋‹ค.

 


#2. JVM ๊ตฌ์กฐ

  • ํด๋ž˜์Šค ๋กœ๋”
    - ๋ฐ”์ดํŠธ์ฝ”๋“œ(.class)๋ฅผ ์ฝ๊ณ  ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ. ๋ฉ”๋ชจ๋ฆฌ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์—ฐ๊ฒฐํ•˜๊ณ  static ๊ฐ’๋“ค์„ ์ดˆ๊ธฐํ™”, ๋ณ€์ˆ˜์— ํ• ๋‹นํ•จ.

  • ๋ฉ”๋ชจ๋ฆฌ (์Šคํƒ, PC, ๋„ค์ดํ‹ฐ๋ธŒ, ํž™, ๋ฉ”์†Œ๋“œ)
    - ๋ฉ”์†Œ๋“œ : ํด๋ž˜์Šค ์ˆ˜์ค€์˜ ์ •๋ณด๊ฐ€ ์ €์žฅ๋จ. ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์—์„œ ๊ณต์œ ํ•ด์„œ ์ž์šฉํ•˜๋Š” ์ž์› (ํด๋ž˜์Šค ์ด๋ฆ„, ๋ฉ”์†Œ๋“œ, ๋ณ€์ˆ˜ ์ •์˜)
    - ํž™ : ๊ฐ์ฒด๋ฅผ ์ €์žฅ, ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์—์„œ ๋ ˆํผ๋Ÿฐ์Šค ์‹ฌ๋ณผ(* ํฌ์ธํ„ฐ ์ฃผ์†Œ๊ฐ’์ด ์•„๋‹˜)๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ณต์œ  ์ž์›
    - ์Šคํƒ : ์“ฐ๋ ˆ๋“œ๋งˆ๋‹ค ๋Ÿฐํƒ€์ž„ ์Šคํƒ์„ ๋งŒ๋“ฆ. ๊ทธ ์•ˆ์— ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ, ์ง€์—ญ ๋ณ€์ˆ˜๋“ฑ์„ ์Šคํƒ์— ์Œ“์•„์„œ ์‚ฌ์šฉ
    - PC : ํ”„๋กœ๊ทธ๋žจ ์นด์šดํ„ฐ ๋ ˆ์ง€์Šคํ„ฐ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ๋ฉ”๋ชจ๋ฆฌ. ์Šค๋ ˆ๋“œ๋งˆ๋‹ค ํ˜„์žฌ ์‹คํ–‰ํ•  ์Šคํƒ ํ”„๋ ˆ์ž„์„ ๊ฐ€๋ฅดํ‚ค๋Š” ํฌ์ธํ„ฐ
    - ๋„ค์ดํ‹ฐ๋ธŒ ๋ฉ”์†Œ๋“œ ์Šคํƒ : ๋ฐ”์ดํŠธ์ฝ”๋“œ๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ์–ธ์–ด(C,C++) ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ €์žฅํ•˜๋Š” ๊ณต๊ฐ„. (JNI ๊ธฐ์ˆ )

  • JNI (Java Native Interface)
    - ์ž๋ฐ” ์•ฑ์—์„œ ๋‹ค๋ฅธ ์–ธ์–ด๋กœ ์ž‘์„ฑ๋œ ํ•จ์ˆ˜ (C, C++, ์–ด์…ˆ๋ธ”๋ฆฌ๋“ฑ)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ‘œ์ค€ API.
    - ์ž๋ฐ” ์ฝ”๋“œ์—์„œ native ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜์žˆ์Œ.
  • ์‹คํ–‰์—”์ง„
    - ์ธํ„ฐํ”„๋ฆฌํ„ฐ : ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ํ•œ์ค„ ์”ฉ ์ฝ์–ด๋“ค์—ฌ ๊ธฐ๊ณ„์–ด๋กœ ๋ฒˆ์—ญ, ์‹คํ–‰ํ•จ.
    - JIT ์ปดํŒŒ์ผ๋Ÿฌ : ์ธํ„ฐํ”„๋ฆฌํ„ฐ์˜ ํšจ์œจ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ์ž์ฃผ์‚ฌ์šฉ๋˜๋Š” ์ฝ”๋“œ๋ฅผ ๋„ค์ดํ‹ฐ๋ธŒ(๊ธฐ๊ณ„์–ด)๋กœ ๋ณ€ํ™˜ํ•ด์„œ ์‚ฌ์šฉ
    - Garbage Collector : ๋” ์ด์ƒ ์ฐธ์กฐ๋˜์ง€ ์•Š๋Š” ๊ฐ์ฒด๋ฅผ ๋ชจ์•„์„œ ์†Œ๋ฉธ์‹œํ‚จ ํ›„ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ™•๋ณดํ•จ. 

 


# JVM์˜ ํด๋ž˜์Šค๋กœ๋”์˜ ๋™์ž‘๊ณผ์ •

JVM์€ ์—ฌ๋Ÿฌ๊ฐœ์˜ ํด๋ž˜์Šค๋กœ๋”๋ฅผ ๊ณ„์ธต ๊ตฌ์กฐ๋กœ ์‚ฌ์šฉํ•˜๋ฉฐ ๊ธฐ๋ณธ์ ์œผ๋กœ 3๊ฐ€์ง€ ํด๋ž˜์Šค ๋กœ๋”๊ฐ€ ์ œ๊ณต๋œ๋‹ค.

  • Bootstrap ํด๋ž˜์Šค๋กœ๋” : JAVA_HOME/lib์— ์žˆ๋Š” Core Java API๋ฅผ ์ฝ์–ด๋“ค์ž„. ์ตœ์ƒ์œ„ ์šฐ์„ ์ˆœ์œ„
  • Platform ํด๋ž˜์Šค๋กœ๋” : JAVA_HOME/lib/ext ๋˜๋Š” java.ext.dirs ์‹œ์Šคํ…œ ๋ณ€์ˆ˜์— ์žˆ๋Š” ํด๋ž˜์Šค๋ฅผ ์ฝ์–ด๋“ค์ž„
  • App ํด๋ž˜์Šค๋กœ๋” : ๊ฐœ๋ฐœ์ž๊ฐ€ ๋งŒ๋“  ์ž๋ฐ” ์•ฑ์˜ ํด๋ž˜์Šค ๊ฒฝ๋กœ(-classpath ๋˜๋Š” java.class.path ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๊ฐ’์— ํ•ด๋‹นํ•˜๋Š”์œ„์น˜)์˜ ํด๋ž˜์Šค๋“ค์„ ์ฝ์Œ.

์ฐธ๊ณ ๋กœ ๋ชจ๋“  ๊ฐ์ฒด์˜ ์กฐ์ƒ์ธ Object์—๋Š” getClassLoader()๋ผ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋‹ค. ์ด๋Š” ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ์ฝ์€ ํด๋ž˜์Šค ๋กœ๋” ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. ๋‹ค๋งŒ Bootstrap ClassLoader๋Š” C์–ธ์–ด๋กœ ์ž‘์„ฑ๋˜์–ด์žˆ๊ธฐ์— ํ˜ธ์ถœํ•˜๋ฉด null์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

* ์ž‰? ์ž๋ฐ”์ฝ”๋“œ๋ฅผ ์ฝ๋Š” ํด๋ž˜์Šค๋กœ๋”๋Š” ๋ˆ„๊ฐ€ ์ฝ๊ณ  ์–ด๋–ป๊ฒŒ ๊ฐ์ฒด๋กœ ๋ฐ›์ฃ ?? ํ•˜๋ฉด์„œ ํ—ท๊ฐˆ๋ฆด์ˆ˜๋„ ์žˆ๋Š”๋ฐ, ๊ฒฐ๊ตญ ์ปดํŒŒ์ผ๋Ÿฌ๋„ ๊ธฐ๊ณ„์–ด๋กœ ํ•œ๋•€ํ•œ๋•€ ์ฐ์–ด์„œ ๋งŒ๋“ ๊ฒŒ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์ด์šฉํ•ด์„œ ๊ธฐ๊ณ„์–ด๋กœ ์ปดํŒŒ์ผ ๋œ ํ”„๋กœ๊ทธ๋žจ์ž„์„ ๊ธฐ์–ตํ•˜์ž.

ํด๋ž˜์Šค ๋กœ๋”๋Š” Static ๊ฐ’์„ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ์ •์  ๋ณ€์ˆ˜์— ํ• ๋‹นํ•จ.

  • ๋กœ๋”ฉ
    - ํด๋ž˜์Šค ๋กœ๋”๊ฐ€ ๋ฐ”์ดํŠธ์ฝ”๋“œ(.class)๋ฅผ ์ฝ๊ณ  ์ ์ ˆํ•œ ์ด์ง„ ๋ฐ์ดํ„ฐ๋ฅผ [๋ฉ”์†Œ๋“œ ์˜์—ญ]์— ์ €์žฅํ•จ.
    - FQCN(Fully Qualified Class Name), ํด๋ž˜์Šค, ์ธํ„ฐํŽ˜์ด์Šค, Enum, ๋ฉ”์†Œ๋“œ, ๋ณ€์ˆ˜ ์ •๋ณด๋ฅผ ์ €์žฅํ•จ
    - ์ด๋ ‡๊ฒŒ [๋ฉ”์†Œ๋“œ ์˜์—ญ]์— ์ €์žฅํ•˜๊ณ  ๋กœ๋”ฉ์ด ์™„๋ฃŒ๋˜๋ฉด ์ดํ›„ [ํž™ ์˜์—ญ]์— ํ•ด๋‹น Class ๊ฐ์ฒด ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ƒ์„ฑ.

  • ๋งํฌ
    - Verify(๊ฒ€์ฆ) : ๋ฐ”์ดํŠธ์ฝ”๋“œ(.class)๊ฐ€ ๋ณ€ํ˜•๋˜์ง€ ์•Š๊ณ  ์œ ํšจํ•œ์ง€ ํ™•์ธํ•จ.
    - Prepare(์ค€๋น„) : ํด๋ž˜์Šค ๋ณ€์ˆ˜(static)์™€ ๊ธฐ๋ณธ๊ฐ’์— ํ•„์š”ํ•œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹น๋ฐ›์Œ.
    - Resolve(์™„๋ฃŒ) : ์‹ฌ๋ณผ๋ฆญ ๋ ˆํผ๋Ÿฐ์Šค(myClass)๋ฅผ ๋ฉ”์†Œ๋“œ ์˜์—ญ์— ์žˆ๋Š” ์‹ค์ œ ๋ ˆํผ๋Ÿฐ์Šค(ํž™ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ)๋กœ ๊ต์ฒดํ•จ. 
    * ์‹ฌ๋ณผ๋ฆญ -> ์‹ค์ œ ๋ ˆํผ๋Ÿฐ์Šค ๊ต์ฒด๋Š” ๋งํฌ๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ์‹œ์ ์— ์ผ์–ด๋‚  ์ˆ˜๋„ ์žˆ์Œ.

  • ์ดˆ๊ธฐํ™”
    - Static ๋ณ€์ˆ˜์˜ ๊ฐ’์„ ํ• ๋‹นํ•จ. (static block์ด ์žˆ๋‹ค๋ฉด ์ด ์‹œ๊ธฐ์— ์‹คํ–‰๋จ)

 


# ์ด๋ ‡๊ฒŒ ์ž์„ธํ•˜๊ฒŒ ์„ค๋ช…ํ•˜๋Š” ์ด์œ ๊ฐ€ ๋ญ์ฃ ?

=> JVM์€ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ์œ ์—ฐํ•˜๊ฒŒ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œ๊ณตํ•ด์ค€๋‹ค. ์ฆ‰ ์ปดํŒŒ์ผ๋œ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ์กฐ์ž‘ํ•˜์—ฌ ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๋™์ž‘์„ ํ•˜๋„๋ก ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

 

์‹ค์ œ๋กœ ์•„๋ž˜์™€ ๊ฐ™์ด ๋‹ค์–‘ํ•œ ๋ฐ”์ดํŠธ์ฝ”๋“œ ์กฐ์ž‘ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์ด ์กด์žฌํ•œ๋‹ค.

  • CGLib (Code Generator Library)
  • ASM
  • Javassist
  • ByteBuddy

 


# JaCoCo๋Š” ์–ด๋–ป๊ฒŒ ๋งŒ๋“ค์—ˆ์„๊นŒ?

์šฐ์•„ํ•œํ…Œํฌ์ฝ”์Šค - ์ •์ ๋ถ„์„๋„๊ตฌ์— ๋Œ€ํ•œ ์„ค๋ช…

์•„๋ž˜์™€ ๊ฐ™์€ ๊ฐ„๋‹จํ•œ ์„ค์ •ํŒŒ์ผ๋กœ ์ฝ”๋“œ ์ปค๋ฒ„๋ฆฌ์ง€ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฉ”์ด๋ธ์˜ pom.xml์— ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ถ”๊ฐ€ํ•˜๊ณ , ์ปค๋ฒ„๋ฆฌ์ง€ ๋งŒ์กฑ ๋ชปํ•˜๋ฉด ๋นŒ๋“œ๋ฅผ ์‹คํŒจํ•˜๋„๋ก ์„ค์ •.
<execution>
    <id>jacoco-check</id>
    <goals>
        <goal>check</goal>
    </goals>
    <configuration>
        <rules>
            <rule>
                <element>PACKAGE</element>
                <limits>
                    <limit>
                        <counter>LINE</counter>
                        <value>COVEREDRATIO</value>
                        <minimum>0.50</minimum>
                    </limit>
                </limits>
            </rule>
        </rules>
    </configuration>
</execution>

 

์ž๋ฐ”์ฝ”๋“œ๋ฅผ ํ•˜๋‚˜๋„ ๊ฑด๋“œ๋ฆฌ์ง€์•Š๊ณ , jacoco๋Š” ์–ด๋–ป๊ฒŒ ์ฝ”๋“œ ์ปค๋ฒ„๋ฆฌ์ง€๋ฅผ ํ™•์ธํ•˜๊ณ  ๋™์ž‘ํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„๊นŒ?

=> ๋ฐ”์ดํŠธ์ฝ”๋“œ ์กฐ์ž‘ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ตฌํ˜„ํ–ˆ๊ธฐ ๋•Œ๋ฌธ!

 

JaCoCo์™€ ์ฝ”๋“œ ์ปค๋ฒ„๋ฆฌ์ง€๊ฐ€ ๋ญ์ฃ ?

๋”๋ณด๊ธฐ

# ์ฝ”๋“œ ์ปค๋ฒ„๋ฆฌ์ง€(Code Coverage)๋ž€?

์ฝ”๋“œ ์ปค๋ฒ„๋ฆฌ์ง€๋Š” ์†Œํ”„ํŠธ์›จ์–ด์˜ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๊ฐ€ ์–ผ๋งˆ๋‚˜ ์ถฉ์กฑ๋˜์—ˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์ง€ํ‘œ ์ค‘ ํ•˜๋‚˜.

ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•˜์˜€์„ ๋•Œ '์ฝ”๋“œ ์ž์ฒด๊ฐ€ ์–ผ๋งˆ๋‚˜ ์‹คํ–‰๋˜์—ˆ๋Š”๊ฐ€' ์— ๋Œ€ํ•œ ์ˆ˜์น˜.

 


@ ์ฝ”๋“œ ์ปค๋ฒ„๋ฆฌ์ง€๋Š” ์–ด๋–ป๊ฒŒ ์ธก์ •ํ• ๊นŒ?

  • ๋ธ”๋ž™๋ฐ•์Šค ํ…Œ์ŠคํŠธ
    - ์†Œํ”„ํŠธ์›จ์–ด์˜ ๋‚ด๋ถ€ ๊ตฌ์กฐ, ์›๋ฆฌ๋ฅผ ๋ชจ๋ฅด๋Š” ์ƒํƒœ์—์„œ ๋™์ž‘์„ ๊ฒ€์‚ฌํ•˜๋Š” ๋ฐฉ์‹
    - ์‚ฌ์šฉ์ž ๊ด€์ ์˜ ํ…Œ์ŠคํŠธ. ์ด์ƒํ•œ ๊ฐ’์„ ์ž…๋ ฅํ–ˆ์„ ๋•Œ ์˜ฌ๋ฐ”๋ฅธ ์ถœ๋ ฅ์ด ๋‚˜์˜ค๋Š”๊ฐ€?

  • ํ™”์ดํŠธ๋ฐ•์Šค ํ…Œ์ŠคํŠธ
    - ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์˜ ๋‚ด๋ถ€ ๊ตฌ์กฐ์™€ ๋™์ž‘์„ ๊ฒ€์‚ฌํ•˜๋Š” ํ…Œ์ŠคํŠธ ๋ฐฉ์‹.
    - ๊ฐœ๋ฐœ์ž์˜ ๊ด€์ ์—์„œ ์†Œํ”„ํŠธ์›จ์–ด ๋‚ด๋ถ€์˜ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ํ…Œ์ŠคํŠธ

 


@ ์ฝ”๋“œ ์ปค๋ฒ„๋ฆฌ์ง€๋ฅผ ์ธก์ •ํ•˜๋Š” ๊ธฐ์ค€๊ฐ’์€ ์–ด๋–ค๊ฒƒ์ด ์žˆ์„๊นŒ?

  • ๊ตฌ๋ฌธ(Statement) ๋˜๋Š” ๋ผ์ธ(Line) ์ปค๋ฒ„๋ฆฌ์ง€
    - ์กฐ๊ฑด์— ๋”ฐ๋ฅธ ๋กœ์ง(์‹œ๋‚˜๋ฆฌ์˜ค)๋ฅผ ํ™•์ธํ•  ์ˆ˜๋Š” ์—†์ง€๋งŒ, ๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๋Š”์ง€๋Š” ํ™•์ธ ๊ฐ€๋Šฅํ•œ ์ง€ํ‘œ
// ํ…Œ์ŠคํŠธ์—์„œ ์ „์ฒด(100%) ์ฝ”๋“œ ์ค‘, ๋ช‡ ๋ผ์ธ์ด ์‹คํ–‰๋˜๋Š”๊ฐ€?
// 4๊ฐœ์˜ ๋ผ์ธ์ค‘ 3๊ฐœ๊ฐ€ ์‹คํ–‰๋ฌ๋‹ค๋ฉด ๊ตฌ๋ฌธ ์ปค๋ฒ„๋ฆฌ์ง€๋Š” 75% (3/4)
void foo (int x) {
    system.out("start line"); // ํ…Œ์ŠคํŠธ 1๋ฒˆ
    if (x > 0) { // ํ…Œ์ŠคํŠธ 2๋ฒˆ
        system.out("middle line"); // ํ…Œ์ŠคํŠธ 3๋ฒˆ
    }
    system.out("last line"); // ํ…Œ์ŠคํŠธ 4๋ฒˆ
}

 

  • ์กฐ๊ฑด(Condition) ์ปค๋ฒ„๋ฆฌ์ง€
    - ์กฐ๊ฑด๋ฌธ์˜ ๋‚ด๋ถ€์กฐ๊ฑด(if)๊ฐ€ ์ด์ƒํ•œ ๊ฐ’์ด ์•„๋‹Œ true, false๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ์ง€ํ‘œ
// ๋ชจ๋“  ์กฐ๊ฑด์‹์˜ ๋‚ด๋ถ€์กฐ๊ฑด(if)์•  ๋Œ€ํ•ด ์ปจ๋””์…˜ ๊ฐ’์ด true ๋˜๋Š” false๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š”์ง€ ํ…Œ์ŠคํŠธ
// ๋‹จ, ์กฐ๊ฑด์ด ์˜๋ฏธ์—†๋Š” ๊ฒฝ์šฐ(๋ฌด์กฐ๊ฑด true)๋„ ํ…Œ์ŠคํŠธ ์„ฑ๊ณต์œผ๋กœ ํ‘œ๊ธฐํ•œ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Œ.
void foo (int x, int y) {
    system.out("start line");
    if (x > 0 && y < 0) { // ํ…Œ์ŠคํŠธ. x,y ์—ฌ๋Ÿฌ๊ฐ’์„ ๋Œ€์ž…ํ•˜๋ฉฐ true or false๊ฐ€ ๋‚˜์˜ค๋Š”์ง€ ํ™•์ธ
        system.out("middle line");
    }
    system.out("last line");
}

 

  • ๊ฒฐ์ •(Decision) ์ปค๋ฒ„๋ฆฌ์ง€ ๋˜๋Š” ๋ธŒ๋ Œ์น˜(Branch) ์ปค๋ฒ„๋ฆฌ์ง€
    - ํ…Œ์ŠคํŠธ์— ๋Œ€ํ•ด์„œ ๋ชจ๋“  ์กฐ๊ฑด์‹์ด true, false๋ฅผ ๋‘˜ ๋‹ค ๊ฐ€์ ธ์•ผํ•จ. ์ฆ‰ ๋กœ์ง์— ๋”ฐ๋ผ ์‹คํ–‰ํ๋ฆ„์ด ๋ณ€ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ์ง€ํ‘œ
    - ๋‹จ ์กฐ๊ฑด๋ฌธ์ด ์—†์œผ๋ฉด ์•„์˜ˆ ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Œ. => ๊ทธ๋ž˜์„œ ๋ผ์ธ ์ปค๋ฒ„๋ฆฌ์ง€๋ฅผ ์ฃผ๋กœ ์‚ฌ์šฉ.

 

@ ์ด๊ฒŒ ์™œ ์ค‘์š”ํ•˜์ฃ ?

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ์‹œ๋‚˜๋ฆฌ์˜ค์— ๋Œ€ํ•ด ์ž‘์„ฑ๋˜์–ด์•ผํ•œ๋‹ค. ์ฝ”๋“œ ์ปค๋ฒ„๋ฆฌ์ง€๋ฅผ ํ†ตํ•œ ํ…Œ์ŠคํŠธ์˜ ์ˆ˜์น˜ํ™”๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋†“์นœ ๋กœ์ง์˜ ํ๋ฆ„์ด๋‚˜ ์ฝ”๋“œ๋ฅผ ๋ณด์™„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์–ด์ค€๋‹ค.

 

์‹ค์ œ ํ˜„์—…์—์„œ๋„ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์˜ ์ค‘์š”์„ฑ์„ ์ธ์ง€ํ•˜๊ณ , ์ฝ”๋“œ ์ปค๋ฒ„๋ฆฌ์ง€ ๋„๊ตฌ๋ฅผ ์ ๊ทน์ ์œผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค. ๋Œ€ํ‘œ์ ์œผ๋กœ ์†Œ๋‚˜ํ๋ธŒ(SonarQube)์™€ ๊ฐ™์€ ์ •์  ์ฝ”๋“œ ๋ถ„์„๋„๊ตฌ๋Š” ์ฝ”๋“œ ์ปค๋ฒ„๋ฆฌ์ง€๊ฐ’์ด ๊ธฐ์กด๋ณด๋‹ค ๋–จ์–ด์ง€๋Š” ๊ฒฝ์šฐ ์ปค๋ฐ‹์ž์ฒด๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฒŒ ์ œํ•œํ•  ์ˆ˜ ์žˆ๋‹ค.

์šฐ์•„ํ•œํ…Œํฌ์ฝ”์Šค - ์ •์ ๋ถ„์„๋„๊ตฌ์— ๋Œ€ํ•œ ์„ค๋ช…

 

 

 

 

 

 

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

JiwonDev

JiwonDev

ํ™œ๋™ํ•˜๊ธฐ