[์—˜๋ฆฌ์Šค SW QA ํŠธ๋ž™ 9~10์ฃผ์ฐจ] 1์ฐจ ํŒ€ ํ”„๋กœ์ ํŠธ ํšŒ๊ณ 

2025. 4. 3. 16:08ยท๐Ÿ“‚ Quality Assurance/๐Ÿ”ฅ ์—˜๋ฆฌ์Šค SW QAํŠธ๋ž™

โ„น๏ธ ํ”„๋กœ์ ํŠธ ๊ฐ€์ด๋“œ


๐Ÿ“Œ 3/21 - 1์ผ์ฐจ ํšŒ๊ณ  (๋Œ€์ƒ ์„œ๋น„์Šค ํŒŒ์•… ๋ฐ ํ”„๋กœ์ ํŠธ ํ™˜๊ฒฝ ์„ธํŒ…)

 
์–ด์ œ ์ˆ˜์—…์ด ๋๋‚œ ํ›„ ์˜คํ›„ 8์‹œ 30๋ถ„ ๊ธฐ์ฐจ๋ฅผ ํƒ€๊ณ  ์„œ์šธ๋กœ ์˜ฌ๋ผ์™”๋‹ค. ์ง์„ ๋Œ€์ถฉ ํ’€๊ณ  ๋‚˜๋‹ˆ ์–ด๋А๋ง ๋ฐค 11์‹œ๊ฐ€ ํ›Œ์ฉ ์ง€๋‚˜ ์žˆ์—ˆ๋‹ค. ๊ธ‰ํ•˜๊ฒŒ ๋ˆˆ์„ ๋ถ™์˜€์ง€๋งŒ, ๋‚ฏ์„  ์ž ์ž๋ฆฌ ๋•Œ๋ฌธ์ธ์ง€ ์ž๊พธ ๋’ค์ฒ™์ด๊ฒŒ ๋๋‹ค.. ์˜ค๋Š˜์€ ์—˜๋ฆฌ์ŠคLab์—์„œ ํŒ€์›๋ถ„๋“ค์„ ์ฒ˜์Œ์œผ๋กœ ์˜คํ”„๋ผ์ธ์—์„œ ๋งŒ๋‚˜๋Š” ๋‚ ์ด์—ˆ๋‹ค. ๋น„๋ชฝ์‚ฌ๋ชฝ ์ผ์–ด๋‚˜์„œ ์„œ์šธ ๊ตฌ๊ฒฝ๋„ ํ•  ๊ฒธ 30๋ถ„ ์ •๋„ ๊ฑธ์–ด์„œ ์—˜๋ฆฌ์ŠคLab์œผ๋กœ ํ–ฅํ–ˆ๋‹ค.
Jenkins๋Š” CI/CD ์ž๋™ํ™”๋ฅผ ์œ„ํ•œ ๋„๊ตฌ์ด์ง€๋งŒ, Windows ํ™˜๊ฒฝ์—์„œ๋Š” Java ํ™˜๊ฒฝ ์„ค์ • ๋ฐ ์„ค์น˜ ๊ณผ์ •์—์„œ ๋‹ค์–‘ํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ๋กœ์ปฌ ์„ค์น˜์— ์–ด๋ ค์›€์ด ์žˆ์—ˆ๋‹ค. ์ด์— Jenkins ๊ณต์‹ ์ด๋ฏธ์ง€๋ฅผ ํ™œ์šฉํ•ด Docker๋กœ Jenkins ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ํ•˜์˜€๊ณ , GitHub ๋ ˆํฌ์ง€ํ† ๋ฆฌ์™€ ์—ฐ๋™ํ•œ ๋’ค, ํ•ด๋‹น ๋ ˆํฌ ๋‚ด ํŒŒ์ผ์„ ์‹คํ–‰ํ•˜๋Š” ๋ช…๋ น์–ด๋ฅผ Jenkins Job์— ์ž…๋ ฅํ•ด ๋นŒ๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•ด๋ณด์•˜๋‹ค. ๋ช…๋ น์–ด๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋˜๋Š”์ง€ ํ™•์ธํ•จ์œผ๋กœ์จ Jenkins์™€ GitHub ๋ ˆํฌ์ง€ํ† ๋ฆฌ ๊ฐ„ ์—ฐ๊ฒฐ์ด ์ž˜ ์ด๋ฃจ์–ด์กŒ๋Š”์ง€๋ฅผ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.


๐Ÿ”ฅ Jenkins ์„ค์ • ๋ฐ GitHub Repo์™€์˜ ์—ฐ๊ฒฐ

๋”๋ณด๊ธฐ

[ Jenkins์™€ ์—ฐ๊ฒฐํ•  GitHub ๋ ˆํฌ ์ƒ์„ฑ ]

https://github.com/kys0529/Jenkins_prac

 

[ ์ƒˆ๋กœ์šด Jenkins ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰ (in cmd) ]

docker run -d -p {์™ธ๋ถ€ ํฌํŠธ}:{์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€ ํฌํŠธ} -p 50000:50000 --name {์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„} jenkins/jenkins

 > Jenkins ๊ณต์‹ ์ด๋ฏธ์ง€๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒˆ๋กœ์šด ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์‹คํ–‰

 > ํฌํŠธ 8080(์›น UI)๊ณผ 50000(์—์ด์ „ํŠธ ํ†ต์‹ ์šฉ)์„ ์˜คํ”ˆ

 

[ ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰ ์—ฌ๋ถ€ ํ™•์ธ (in cmd) ]

docker ps

 > ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ Docker ์ปจํ…Œ์ด๋„ˆ ๋ชฉ๋ก์„ ํ™•์ธํ•˜์—ฌ Jenkins๊ฐ€ ์ž˜ ๋–  ์žˆ๋Š”์ง€ ์ฒดํฌ

 

[ Jenkins ์ดˆ๊ธฐ ๋น„๋ฐ€๋ฒˆํ˜ธ ํ™•์ธ (in cmd) ]

docker exec -it {์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„} cat /var/jenkins_home/secrets/initialAdminPassword

 > Jenkins ์ดˆ๊ธฐ ์„ค์น˜ ์‹œ ํ•„์š”ํ•œ ๊ด€๋ฆฌ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ถœ๋ ฅ

 

[ Jenkins ์›น UI ์ ‘์† ๋ฐ ์ดˆ๊ธฐ ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ ]

http://localhost:8080

 > ๋ธŒ๋ผ์šฐ์ €์—์„œ http://localhost:8080 ์ ‘์† ํ›„, ์œ„์—์„œ ํ™•์ธํ•œ ์ดˆ๊ธฐ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•˜์—ฌ ์ดˆ๊ธฐ ์„ค์ •์„ ์ง„ํ–‰

 

[ Freestyle Job ์ƒ์„ฑ ๋ฐ GitHub Webhook ์—ฐ๊ฒฐ]

Jenkins์—์„œ New Item > Freestyle Project๋ฅผ ์„ ํƒํ•˜์—ฌ ์ƒˆ๋กœ์šด Job ์ƒ์„ฑ

http://{๊ณต์ธ IP}:8080/github-webhook/

 > GitHub์—์„œ Webhook ์„ค์ • ์‹œ Payload URL์€ ์œ„ ๊ฐ™์ด ์ž…๋ ฅ

 > ํ•ด๋‹น Webhook์€ GitHub์—์„œ push ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ Jenkins Job์„ ํŠธ๋ฆฌ๊ฑฐํ•˜๋Š” ์—ญํ• 

 

[ Jenkins ์ปจํ…Œ์ด๋„ˆ ๋‚ด Python ์„ค์น˜ ์—ฌ๋ถ€ ํ™•์ธ (in cmd) ]

docker exec -it {์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„} bash

 > Jenkins ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€๋กœ ์ง„์ž…

python3 --version

 > Python์ด ์„ค์น˜๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธ

 

[ Docker ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์— python3 ์„ค์น˜ ]

docker exec -it --user root {์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„} bash

 > ๋ฃจํŠธ ๊ถŒํ•œ์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ์— ์ง„์ž…

apt update

apt install -y python3 python3-pip

 > Python3 ๋ฐ pip ์„ค์น˜

 

[ Build Steps ์„ค์ • ]

Jenkins Job ์„ค์ • > Build Steps ํ•ญ๋ชฉ์—์„œ "Execute shell" ์„ ํƒ

python3 hello.py

 > ๋ ˆํฌ ๋‚ด hello.py ํŒŒ์ผ์„ ์‹คํ–‰ํ•˜์—ฌ Jenkins์™€ GitHub ๋ ˆํฌ ๊ฐ„์˜ ์—ฐ๊ฒฐ ๋ฐ ์‹คํ–‰ ์—ฌ๋ถ€๋ฅผ ํ™•์ธ

 


 

๊ทธ ํ›„ ํŒ€๋ช…๊ณผ ํŒ€์žฅ์„ ์ •ํ–ˆ๋‹ค. ํŒ€๋ช…์€ GPT์˜ ๋„์›€์„ ๋ฐ›์•„ ๊ฒฐ์ •ํ–ˆ๊ณ , ํŒ€์žฅ์€ ์•„๋ฌด๋„ ํ•˜๋ ค๊ณ  ํ•˜์ง€ ์•Š์•„์„œ ๋‚ด๊ฐ€ ๋งก๊ฒŒ ๋๋‹ค. ๋‚˜์„œ์„œ ๋ฆฌ๋” ์—ญํ• ์„ ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ, ํ•ญ์ƒ ๊ทธ๋ ‡๋“ฏ ํ•  ์‚ฌ๋žŒ์ด ์—†์œผ๋ฉด ๊ฒฐ๊ตญ ๋‚ด๊ฐ€ ํ•˜๊ฒŒ ๋˜๋Š” ํŽธ์ด๋‹ค.
ํŒ€์žฅ์„ ์ •ํ•œ ํ›„์—๋Š” ๋Œ€์ƒ ์„œ๋น„์Šค์˜ Figma, ERD, ๊ธฐํš์„œ ๊ฐ™์€ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด์„œ ๊ธฐ๋Šฅ๋“ค์„ ๋Œ€๋žต์ ์œผ๋กœ ํŒŒ์•…ํ–ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํŒ€์›๋“ค๊ณผ ํ•จ๊ป˜ ์„œ๋น„์Šค๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•ด๋ณด๋ฉด์„œ ํƒ์ƒ‰์  ํ…Œ์ŠคํŠธ์™€ ํฌ๋กœ์Šค ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ–ˆ๋‹ค. ์–ด๋–ค ๊ธฐ๋Šฅ๋“ค์ด ๊ตฌํ˜„๋ผ ์žˆ๋Š”์ง€, ์•„์ง ๊ตฌํ˜„๋˜์ง€ ์•Š์€ ๊ฑด ๋ฌด์—‡์ธ์ง€, ์–ด๋–ค ์˜ค๋ฅ˜๋“ค์ด ์žˆ๋Š”์ง€๋ฅผ ํ•˜๋‚˜ํ•˜๋‚˜ ์ง์ ‘ ํ™•์ธํ•ด๋ณด๋ฉด์„œ ์ „๋ฐ˜์ ์ธ ํ๋ฆ„์„ ์ดํ•ดํ–ˆ๋‹ค.
 
 

๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๊ตฌ๊ธ€ ์Šคํ”„๋ ˆ๋“œ์‹œํŠธ์— ๊ธฐ๋Šฅ ๋ช…์„ธ์„œ๋ฅผ ์ •๋ฆฌํ–ˆ๊ณ , ๊ฐ์ž ํ•˜๋‚˜์”ฉ ๊ธฐ๋Šฅ์„ ์„ ์ •ํ•ด์„œ TC ์ดˆ์•ˆ๋„ ์ž‘์„ฑํ–ˆ๋‹ค. ์†Œํ†ต์„ ๋” ์›ํ™œํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด, Figma์— ์ž์ฃผ ์“ฐ๋Š” URL์ด๋‚˜ ํ”„๋กœ์ ํŠธ ์‚ฐ์ถœ๋ฌผ, ๊ทธ๋ฆฌ๊ณ  ์ง„ํ–‰ ์ƒํ™ฉ ๋“ฑ์„ ํ•œ๋ˆˆ์— ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ์ •๋ฆฌํ•ด๋‘์—ˆ๋‹ค.
 
GitHub๋Š” GitHub Desktop์„ ํ™œ์šฉํ•˜๋ฉด GUI๋กœ ์‰ฝ๊ฒŒ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ์–ด์„œ Git ๊ฒฝํ—˜์ด ์—†์–ด๋„ ๋ˆ„๊ตฌ๋‚˜ ์–ด๋ ต์ง€ ์•Š๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ๋Š”๋ฐ, GitLab์€ ์šฐ๋ฆฌ ๋ชจ๋‘ ์ฒ˜์Œ์ด๋ผ CLI ์กฐ์ž‘์— ๋งŽ์ด ํ—ค๋งธ๋‹ค. ๊ทธ๋ž˜๋„ SSH Key๋ฅผ ๋ฐœ๊ธ‰๋ฐ›๊ณ , Clone๊ณผ Pull๊นŒ์ง€๋Š” ๊ฒฐ๊ตญ ๋‹ค ์„ฑ๊ณตํ–ˆ๋‹ค. ์˜ค๋Š˜์€ ์ผ๋‹จ ํ”„๋กœ์ ํŠธ์˜ ์ดˆ๊ธฐ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ๋งŒ ๋งŒ๋“ค์–ด๋‘” ์ƒํƒœ๋‹ค.
์˜คํ›„ 8์‹œ์—๋Š” ์˜คํ”ผ์Šค ์•„์›Œ๊ฐ€ ์ง„ํ–‰๋๋‹ค. ์ด ์‹œ๊ฐ„์€ QA ์‹ค๋ฌด ๋ฐ ์ž๋™ํ™” ๊ฒฝํ—˜์ด ์žˆ๋Š” ํ’€์Šคํƒ ํ˜„์—…์ž๋ถ„๊ป˜ 1์‹œ๊ฐ„ ๋™์•ˆ ๊ถ๊ธˆํ•œ ์ ์„ ๋ฌผ์–ด๋ณผ ์ˆ˜ ์žˆ๋Š” ์ •๋ง ์†Œ์ค‘ํ•œ ์‹œ๊ฐ„์ด๋‹ค. ์‚ฌ์‹ค ํ”„๋กœ์ ํŠธ ์ฒซ๋‚ ์ด๋ผ ์ด๊ฒƒ์ €๊ฒƒ ์ •์‹ ์ด ๋„ˆ๋ฌด ์—†์—ˆ๊ณ , ์งˆ๋ฌธ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฏธ๋ฆฌ ์ค€๋น„ํ•˜์ง€ ๋ชปํ•œ ๊ฒŒ ๋„ˆ๋ฌด ์•„์‰ฌ์› ๋‹ค. ๋‹ค์Œ๋ถ€ํ„ฐ๋Š” ๊ผญ ๋ฏธ๋ฆฌ ์งˆ๋ฌธ์„ ์ •๋ฆฌํ•ด์„œ ์ด ์‹œ๊ฐ„์„ ๋” ์œ ์šฉํ•˜๊ฒŒ ํ™œ์šฉํ•ด์•ผ๊ฒ ๋‹ค.
 
 
๐Ÿ”ฅ SSH Key ์„ค์ • ๋ฐ GitLab ํ”„๋กœ์ ํŠธ Clone

๋”๋ณด๊ธฐ

[ SSH Key ์ƒ์„ฑ (in cmd) ]

ssh-keygen -t rsa -b 4096 -C "{GitLab์— ๋“ฑ๋ก๋œ ์ด๋ฉ”์ผ}"

 > ์œ„ ๋ช…๋ น์–ด ์ž…๋ ฅ ํ›„ Enter 3๋ฒˆ ์ž…๋ ฅ

 > SSH ํ‚ค๊ฐ€ ์ƒ์„ฑ๋˜๋ฉด ํ‚ค ํŒŒ์ผ ์ €์žฅ ์œ„์น˜๊ฐ€ ์ถœ๋ ฅ

 

[ SSH ํ‚ค ๋ณต์‚ฌ ]

ํŒŒ์ผ ํƒ์ƒ‰๊ธฐ๋กœ ์ƒ์„ฑ๋œ SSH ํ‚ค ์œ„์น˜๋กœ ์ด๋™ (๋ณธ์ธ์€ C:\Users\samsung\.ssh)

๋น„๋ฐ€ ํ‚ค(id_rsa)๊ฐ€ ์•„๋‹Œ ๊ณต๊ฐœ ํ‚ค(id_rsa.pub) ์‚ฌ์šฉ (๊ณต๊ฐœ ํ‚ค ๋‚ด์šฉ ssh-rsa ~~~~ ํ˜•ํƒœ๋กœ ์‹œ์ž‘)

๊ณต๊ฐœ ํ‚ค ๋‚ด์šฉ ๋ณต์‚ฌ

 

[ GitLab์—์„œ SSH Key ๋“ฑ๋ก ]

GitLab ์ ‘์† ํ›„ ํ”„๋กœํ•„ ์„ค์ •์œผ๋กœ ์ด๋™

์ขŒ์ธก ๋ฉ”๋‰ด์—์„œ SSH Keys ํด๋ฆญ ํ›„,  ๋ณต์‚ฌํ•œ SSH ๊ณต๊ฐœ ํ‚ค๋ฅผ Key ์ž…๋ ฅ๋ž€์— ๋ถ™์—ฌ๋„ฃ๊ธฐ

 

[ ํด๋” ์ƒ์„ฑ ๋ฐ ํด๋ก  ]

์›ํ•˜๋Š” ์œ„์น˜์— ํ”„๋กœ์ ํŠธ ํด๋” ์ƒ์„ฑ ํ›„, VS Code์—์„œ ํ•ด๋‹น ํด๋” ์—ด๊ธฐ

git clone {GitLab SSH ํ‚ค}

 


 
๐Ÿ”ฅ Git ๋ช…๋ น์–ด

๋”๋ณด๊ธฐ

[ Clone ๋ช…๋ น์–ด ]
git clone {Gitlab์—์„œ ๋ณต์‚ฌํ•œ SSH}

[ Repo๋ฅผ Cloneํ•œ ํด๋”๋กœ ์ด๋™ ]
cd {ํด๋” ์ด๋ฆ„}

[ branch ์ƒ์„ฑ ๋ฐ ํ•ด๋‹น branch๋กœ ์ด๋™ ]
git checkout -b {branch ์ด๋ฆ„}

[ ํ˜„์žฌ branch ํ™•์ธ (*์ด ํ˜„์žฌ ์œ„์น˜ํ•œ branch) ]
git branch

[ Pull ๋ช…๋ น์–ด ]
git pull origin {branch ์ด๋ฆ„}

[ Push ๊ณผ์ • ]
๋ณ€๊ฒฝ ์‚ฌํ•ญ ํ™•์ธ: git status
๋ณ€๊ฒฝ๋œ ํŒŒ์ผ ์Šคํ…Œ์ด์ง•: git add .
์ปค๋ฐ‹ ๋งŒ๋“ค๊ธฐ: git commit -m "์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€"
Push: git push origin {branch ์ด๋ฆ„}

 



๐Ÿ“š 3/22 - ๊ฐœ์ธ ๊ณต๋ถ€ (Sourcetree)

 
์‚ฌ์‹ค ์ฃผ๋ง์€ ์•”๋ฌต์ ์œผ๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜์ง€ ์•Š๊ธฐ๋กœ ํ–ˆ์—ˆ์ง€๋งŒ, ๋™๊ธฐ ์นœ๊ตฌ๊ฐ€ SW ๋งˆ์—์ŠคํŠธ๋กœ ๋ฉด์ ‘ ๋•Œ๋ฌธ์— ์„œ์šธ์— ์˜ฌ๋ผ์˜จ ๊น€์— ์–ผ๊ตด๋„ ๋ณผ ๊ฒธ ์„ฑ์ˆ˜์—์„œ ๋ฐฅ์„ ๋จน๊ณ , ์นดํŽ˜์— ๋“ค๋Ÿฌ ์ž ๊น ํ”„๋กœ์ ํŠธ ๊ด€๋ จ ๊ณต๋ถ€๋ฅผ ๊ฐœ์ธ์ ์œผ๋กœ ์ง„ํ–‰ํ–ˆ๋‹ค.
๋งˆ์นจ ๊ทธ ์นœ๊ตฌ๊ฐ€ Docker๋ฅผ ๋‹ค๋ค„๋ณธ ์ ์ด ์žˆ์–ด์„œ, ์–ด์ œ ๋‚ด๊ฐ€ Docker๋กœ ์ง„ํ–‰ํ–ˆ๋˜ "Jenkins ์„ค์ • ๋ฐ GitHub Repo์™€์˜ ์—ฐ๊ฒฐ" ๊ณผ์ •์„ ์„ค๋ช…ํ•ด์คฌ๋”๋‹ˆ, ์นœ๊ตฌ๊ฐ€ ์ด๋Ÿฐ ๋ง์„ ํ•ด์คฌ๋‹ค. “๋„ˆ๊ฐ€ ์ง€๊ธˆ์ฒ˜๋Ÿผ ๋ช…๋ น์–ด ํ•˜๋‚˜ํ•˜๋‚˜ ์ณ์„œ Jenkins ์ปจํ…Œ์ด๋„ˆ ๋„์šฐ๊ณ  ์„ค์ •ํ•˜๋Š” ์ด๋Ÿฐ ์ž‘์—…๋“ค์€ Dockerfile์ด๋‚˜ Docker Compose๋กœ ์ •๋ฆฌํ•ด๋‘๋ฉด, ํ•œ ์ค„ ๋ช…๋ น์–ด๋กœ ํ†ตํ•ฉ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์–ด” ์ฆ‰, Dockerfile์„ ๋งŒ๋“ค์–ด์„œ Jenkins์™€ Python๊นŒ์ง€ ๋ฏธ๋ฆฌ ์„ค์น˜ํ•ด๋‘๋ฉด, docker build ํ•œ ๋ฒˆ์œผ๋กœ Jenkins + Python3 ํ™˜๊ฒฝ์ด ๊ตฌ์„ฑ๋œ ์ด๋ฏธ์ง€๋ฅผ ๋ฐ”๋กœ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋œป์ด์—ˆ๋‹ค. ๋ฌผ๋ก  ์ฝ”์น˜๋‹˜๊ป˜์„œ ์ฒ˜์Œ๋ถ€ํ„ฐ Dockerfile๋กœ ์ฃผ์…จ๋‹ค๋ฉด ๊ธˆ๋ฐฉ ๋๋‚ฌ๊ฒ ์ง€๋งŒ, ์ด ์‹ค์Šต์˜ ๋ชฉ์  ์ž์ฒด๊ฐ€ ์ง์ ‘ Jenkins๋ฅผ ์„ธํŒ…ํ•ด๋ณด๋Š” ๋ฐ ์žˆ์œผ๋‹ˆ๊นŒ! ๊ทธ๋ž˜๋„ Docker๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ํ•˜๋‚˜ ๋ฐฐ์›Œ๊ฐ„ ์…ˆ์ด๋‹ค.
๊ทธ๋ฆฌ๊ณ  ๋ง๋ถ™์—ฌ, GitLab ์ด์•ผ๊ธฐ๋ฅผ ํ•˜๋‹ค๊ฐ€ GitLab์—๋Š” GitHub Desktop์ฒ˜๋Ÿผ GUI ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์—†์–ด์„œ, CLI์— ์ต์ˆ™ํ•˜์ง€ ์•Š์€ ๋‚˜์™€ ํŒ€์›๋“ค์ด ๊ฝค๋‚˜ ํž˜๋“ค์–ดํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ํ•˜์†Œ์—ฐํ–ˆ๋”๋‹ˆ ์นœ๊ตฌ๊ฐ€ "Sourcetree"๋ฅผ ์ถ”์ฒœํ•ด์คฌ๋‹ค.
 
๐Ÿ”ฅ Sourcetree ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

๋”๋ณด๊ธฐ

[ Access Token ๋ฐœ๊ธ‰ ๋ฐฉ๋ฒ• - GitHub ]

Settings > Developer Settings 

Personal access token > Tokens (classic) > Generate new token (classic)

 

[ Access Token ๋ฐœ๊ธ‰ ๋ฐฉ๋ฒ• - GitLab ]

User Settings > Access tokens > Add new token

 

[ Access Token ๋ฐœ๊ธ‰ ๋ฐฉ๋ฒ• - GitLab EE ]

User Settings > Access Tokens

 

[ ํ˜ธ์ŠคํŒ… ๊ณ„์ • ์—ฐ๋™ ]

(1) Host

     New tab > Remote > ๊ณ„์ • ์ถ”๊ฐ€ > ํ˜ธ์ŠคํŒ… ์„œ๋น„์Šค ๋ฐ ์„ ํ˜ธ ํ”„๋กœํ† ์ฝœ ์„ ํƒ

     GitLab EE๋Š” ํ˜ธ์ŠคํŠธ URL ์ถ”๊ฐ€์ ์œผ๋กœ ์ž…๋ ฅ (ex: https://kdt-gitlab.elice.io/)

(2) Credentials

     ์ธ์ฆ์€ Personal Access Token ์„ ํƒ

     Personal Access Token ์ƒˆ๋กœ๊ณ ์นจ ๋ฒ„ํŠผ ํด๋ฆญ > ๋ณธ์ธ ์‚ฌ์šฉ์ž ์ด๋ฆ„ ์ž…๋ ฅ ๋ฐ ์•”ํ˜ธ์— ๋ฐœ๊ธ‰๋ฐ›์€ Access Token ์ž…๋ ฅ

 



๐Ÿ“š  3/23 - ๊ฐœ์ธ ๊ณต๋ถ€ (Docker ๋ฐ Jenkins)

 
์˜ค๋Š˜์€ ํŒ€ ํ”„๋กœ์ ํŠธ๋ฅผ ํ•จ๊ป˜ ์ง„ํ–‰ ์ค‘์ธ ํŒ€์›๋ถ„๊ณผ ์ƒ๋ด‰์—ญ ์นดํŽ˜์—์„œ ๋งŒ๋‚˜, Python์˜ ๊ธฐ๋ณธ ๋ฌธ๋ฒ•๋ถ€ํ„ฐ Selenium, pytest, ๊ทธ๋ฆฌ๊ณ  ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด๋“œ๋ ธ๋‹ค. ์„ค๋ช…์„ ํ•˜๋ฉด์„œ ๋‚˜ ์—ญ์‹œ ๊ธฐ๋ณธ ๊ฐœ๋…๋“ค์„ ๋‹ค์‹œ ๋– ์˜ฌ๋ฆด ์ˆ˜ ์žˆ์–ด ์œ ์ตํ•œ ์‹œ๊ฐ„์ด์—ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์˜ค๋Š˜ ์ƒˆ๋กญ๊ฒŒ ์•Œ๊ฒŒ ๋œ ์‚ฌ์‹ค ํ•˜๋‚˜! conftest.py ํŒŒ์ผ์€ pytest๊ฐ€ ์ž๋™์œผ๋กœ ์ธ์‹ํ•ด fixture๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋‹ค๋ฅธ ๋ชจ๋“ˆ์ฒ˜๋Ÿผ importํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ๋‹ค๋งŒ ์ด ํŒŒ์ผ์€ ํ…Œ์ŠคํŠธ ํŒŒ์ผ๊ณผ ๊ฐ™์€ ๋””๋ ‰ํ† ๋ฆฌ ๋˜๋Š” ์ƒ์œ„ ๋””๋ ‰ํ† ๋ฆฌ์— ์žˆ์–ด์•ผ ์ž๋™ ์ธ์‹๋˜๋ฉฐ, ํ•˜์œ„ ๋””๋ ‰ํ† ๋ฆฌ์— ์žˆ๋Š” conftest.py๋Š” ์ž๋™์œผ๋กœ ์ฝํžˆ์ง€ ์•Š๋Š”๋‹ค.
 
Docker
 • Dockerfile
  ~> ๋‚˜๋งŒ์˜ Docker Image๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ์กฐ๋ฆฌ๋ฒ•(๋ ˆ์‹œํ”ผ)
  ~> ์–ด๋–ค OS๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ, ์–ด๋–ค ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ• ์ง€, ์–ด๋–ค ์„ค์ •์„ ์ ์šฉํ• ์ง€ ํ•œ ์ค„์”ฉ ์ž‘์„ฑํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ
  ~> ์‰ฝ๊ฒŒ ๋งํ•ด "๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ๊ทธ๋Œ€๋กœ ์ด๋ฏธ์ง€๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ์„ค๊ณ„๋„"
 • Docker Image
  ~> ์ผ์ข…์˜ ์„ค์น˜ CD๋‚˜ ํ”„๋กœ๊ทธ๋žจ์˜ ์™„์ œํ’ˆ ํ…œํ”Œ๋ฆฟ
  ~> ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜, ์„ค์ •, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋“ฑ ์‹คํ–‰์— ํ•„์š”ํ•œ ๋ชจ๋“  ์š”์†Œ๊ฐ€ ํฌํ•จ๋œ ๋ถˆ๋ณ€ํ•œ ์ƒํƒœ์˜ ํŒจํ‚ค์ง€
 • Docker Container
  ~> ์ด๋ฏธ์ง€๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์‹คํ–‰ ์ค‘์ธ ์ธ์Šคํ„ด์Šค
  ~> ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด, ์ด๋ฏธ์ง€๋ฅผ ์‹คํ–‰ํ•ด์„œ ๋งŒ๋“ค์–ด๋‚ธ ๋…๋ฆฝ์ ์ธ ์šด์˜ ํ™˜๊ฒฝ
  ~> ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๊ฐ™์€ ์ด๋ฏธ์ง€๋กœ๋ถ€ํ„ฐ ์ƒ์„ฑ ๊ฐ€๋Šฅ
 • docker-compose.yml
  ~> ์—ฌ๋Ÿฌ ๊ฐœ์˜ Docker ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํ•œ ๋ฒˆ์— ์‹คํ–‰์‹œํ‚ค๋Š” ์‹คํ–‰ ๋งค๋‹ˆ์ €
  ~> ์–ด๋–ค ์ด๋ฏธ์ง€๋ฅผ ์‹คํ–‰ํ• ์ง€, ํฌํŠธ๋ฅผ ์–ด๋–ป๊ฒŒ ์—ฐ๊ฒฐํ• ์ง€, ๋ณผ๋ฅจ์€ ์–ด๋””์— ๋งˆ์šดํŠธํ• ์ง€ ๋“ฑ์„ ์ •์˜
  ~> ์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด "Docker ํ™˜๊ฒฝ ์ „์ฒด๋ฅผ ์ž๋™์œผ๋กœ ์„ธํŒ…ํ•ด์ฃผ๋Š” ์‹œ๋‚˜๋ฆฌ์˜ค ํŒŒ์ผ"
 
GitHub Webhook์„ ์„ค์ •ํ•  ๋•Œ ๊ณต์ธ IP๋ฅผ ์ด์šฉํ•ด ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •ํ–ˆ์ง€๋งŒ, ์ •์ƒ์ ์œผ๋กœ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์•˜๋‹ค๋Š” ์‚ฌ์‹ค์„ ๋’ค๋Šฆ๊ฒŒ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค.

  • GitHub Webhook: http://{๊ณต์ธ IP}:8080/github-webhook/

์ฆ‰, 21์ผ์— ์ง„ํ–‰ํ–ˆ๋˜ Jenkins ์‹ค์Šต ๋‹น์‹œ์—๋Š” Job์˜ Build Steps์— python3 hello.py๋ฅผ ์ž…๋ ฅํ•œ ๋’ค Jenkins์—์„œ ์ˆ˜๋™์œผ๋กœ Build Now ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ์‹คํ–‰ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, Jenkins์™€ GitHub ๊ฐ„ ์—ฐ๋™์ด ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜๋Š” ์ค„๋กœ๋งŒ ์•Œ๊ณ  ์žˆ์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” Webhook์ด ์ œ๋Œ€๋กœ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ดํ›„ GitHub์—์„œ push ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•ด๋„ Jenkins๊ฐ€ ์ž๋™์œผ๋กœ ๋นŒ๋“œ๋˜์ง€ ์•Š๋Š” ์ƒํƒœ์˜€๋‹ค. ์ด ์‚ฌ์‹ค์€ ์˜ค๋Š˜ GitHub ๋ ˆํฌ ๋‚ด์˜ hello.py ํŒŒ์ผ์„ ์ˆ˜์ •ํ•˜๋ฉด์„œ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค.
GitHub Webhook ์„ค์ •์— ๊ณต์ธ IP๋ฅผ ์‚ฌ์šฉํ–ˆ์Œ์—๋„ ์ž๋™ ๋นŒ๋“œ๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š์•˜๋˜ ์ด์œ ๋Š”, ์™ธ๋ถ€์—์„œ ํ•ด๋‹น ํฌํŠธ(8080)๋กœ ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ํ™˜๊ฒฝ์ด์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋Š” ๊ณต์œ ๊ธฐ ํฌํŠธํฌ์›Œ๋”ฉ ๋ฏธ์„ค์ •, ๋กœ์ปฌ ๋ฐฉํ™”๋ฒฝ ์ฐจ๋‹จ, ๋˜๋Š” ISP์˜ ํฌํŠธ ์ œํ•œ ๋“ฑ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์›์ธ์œผ๋กœ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.
ํ•˜์ง€๋งŒ ์ด ๋ชจ๋“  ์„ค์ •์„ ํ•˜๋‚˜ํ•˜๋‚˜ ํ™•์ธํ•˜๊ณ  ๊ตฌ์„ฑํ•˜๋Š” ๊ณผ์ •์ด ๋ณต์žกํ•˜๊ณ  ๋ฒˆ๊ฑฐ๋กญ๊ธฐ ๋•Œ๋ฌธ์—, GPT์˜ ์ถ”์ฒœ๋Œ€๋กœ ngrok์„ ํ™œ์šฉํ•ด Jenkins๋ฅผ ์™ธ๋ถ€์— ์•ˆ์ „ํ•˜๊ฒŒ ๋…ธ์ถœ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ์ „ํ™˜ํ•ด๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค.
 
๊ณต์ธ IP
 ~> ํ˜„์žฌ ๋‚ด ๊ณต์ธ IP ํ™•์ธ ์‚ฌ์ดํŠธ
 ~> ๊ณต์ธ IP๋Š” ์ธํ„ฐ๋„ท์ƒ์—์„œ ๊ณ ์œ ํ•˜๊ฒŒ ์‹๋ณ„๋˜๋Š” IP ์ฃผ์†Œ๋กœ, ์™ธ๋ถ€์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์ฃผ์†Œ
 ~> ๋ณดํ†ต ๊ฐ€์ •์ด๋‚˜ ํšŒ์‚ฌ์—์„œ๋Š” ํ•˜๋‚˜์˜ ๊ณต์ธ IP๋ฅผ ๊ณต์œ ๊ธฐ(๋ผ์šฐํ„ฐ)๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ๊ทธ ์•„๋ž˜์— ์—ฌ๋Ÿฌ ๋Œ€์˜ ์ปดํ“จํ„ฐ๋“ค์ด ์‚ฌ์„ค IP๋ฅผ ํ†ตํ•ด ์—ฐ๊ฒฐ
 ~> Jenkins๊ฐ€ ๋กœ์ปฌ PC์— ์„ค์น˜๋˜์–ด ์žˆ๊ณ , ์™ธ๋ถ€(GitHub/GitLab)์—์„œ๋Š” ๊ณต์ธ IP๋กœ ์ ‘์†์„ ์‹œ๋„ํ•˜๋”๋ผ๋„ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์œ ๋กœ ์‹คํŒจ ๊ฐ€๋Šฅ
  • ๊ณต์œ ๊ธฐ์—์„œ ํฌํŠธํฌ์›Œ๋”ฉ ์„ค์ •์ด ์•ˆ ๋˜์–ด ์žˆ์Œ
  • ๋กœ์ปฌ ๋ฐฉํ™”๋ฒฝ์—์„œ 8080 ํฌํŠธ๋ฅผ ์ฐจ๋‹จ ์ค‘
  • ์ธํ„ฐ๋„ท ์ œ๊ณต์—…์ฒด(ISP)์—์„œ ํฌํŠธ ์ฐจ๋‹จ ์ •์ฑ…์ด ์žˆ์Œ
 
ngrok
 ~> ๋กœ์ปฌ์—์„œ ์‹คํ–‰ ์ค‘์ธ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(์˜ˆ: Jenkins)์„ ์™ธ๋ถ€์—์„œ ์ ‘์† ๊ฐ€๋Šฅํ•˜๋„๋ก ๋งŒ๋“ค์–ด์ฃผ๋Š” ๋„๊ตฌ
 ~> ์ฆ‰, ngrok์ด ์ œ๊ณตํ•˜๋Š” ์ž„์‹œ ํผ๋ธ”๋ฆญ ์ฃผ์†Œ๋ฅผ ํ†ตํ•ด ๊ณต์ธ IP ์—†์ด๋„ ์™ธ๋ถ€์—์„œ ๋‚ด Jenkins์— ์ ‘๊ทผ ๊ฐ€๋Šฅ
 ~> ngrok์€ ์‹ค์‹œ๊ฐ„ ํ„ฐ๋„๋ง ์ค‘๊ณ„ ํ”„๋กœ๊ทธ๋žจ์ด๋ฏ€๋กœ, ngrok์ด ์‹คํ–‰ ์ค‘์ธ ๋™์•ˆ์—๋งŒ ์ƒ์„ฑ๋œ Forwarding ์ฃผ์†Œ๊ฐ€ ์œ ํšจ
 
๐Ÿ”ฅ ngrok ์„ค์น˜ ๋ฐฉ๋ฒ•

๋”๋ณด๊ธฐ

[ ๊ณต์‹ ์‚ฌ์ดํŠธ์—์„œ ๋‹ค์šด๋กœ๋“œ ๋ฐ ์••์ถ• ํ’€๊ธฐ ]

https://ngrok.com/downloads/windows?tab=download

 

[ ngrok ํšŒ์›๊ฐ€์ž… ๋ฐ ์ธ์ฆ ํ† ํฐ ๋ฐœ๊ธ‰ ]

https://ngrok.com/

Identity & Access > Authtokens > Add Tunnel Authtoken

 

[ ์ธ์ฆ ํ† ํฐ ๋“ฑ๋ก (in ngrok.exe) ]

ngrok config add-authtoken {๋ฐœ๊ธ‰ ๋ฐ›์€ ํ† ํฐ}

 

[ Jenkins์šฉ ํฌํŠธ 8080 ํ„ฐ๋„๋ง ์‹คํ–‰ (in ngrok.exe) ]

ngrok http 8080

 

 > ngrok์ด ์ƒ์„ฑํ•œ Forwarding ์ฃผ์†Œ ์˜ˆ์‹œ

 


 
Jenkins
๐Ÿ”ฅ GitLab ์ €์žฅ์†Œ ์—ฐ๊ฒฐ์„ ์œ„ํ•ด ํ•„์š”ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ

๋”๋ณด๊ธฐ

[ Docker ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์— ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์น˜ (in cmd) ]

docker exec -it {์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„} bash

 > Jenkins ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€๋กœ ์ง„์ž…

 

jenkins-plugin-cli --plugins git:5.7.0

 > Git SCM ์ง€์›: Jenkins๊ฐ€ Git ์ €์žฅ์†Œ์—์„œ ์ฝ”๋“œ๋ฅผ ํด๋ก ํ•˜๊ณ  ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์คŒ

 

jenkins-plugin-cli --plugins gitlab-plugin:1.9.7

 > GitLab ์—ฐ๋™: GitLab Webhook, GitLab credentials, GitLab SCM UI ์—ฐ๋™ ๋“ฑ์„ ๋‹ด๋‹น

 

ํ•ด๋‹น ์ปจํ…Œ์ด๋„ˆ Stop & Start

 > Jenkins ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์„ค์น˜ ํ›„ ๋ฐ˜๋“œ์‹œ ์žฌ์‹œ์ž‘ํ•ด์•ผ ์ ์šฉ

 


๐Ÿ”ฅ ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์— Python3, ๊ฐ€์ƒ ํ™˜๊ฒฝ, Chrome ์„ค์น˜

๋”๋ณด๊ธฐ

[ ๋ฃจํŠธ ๊ถŒํ•œ์œผ๋กœ Docker ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€ ์ง„์ž… (in cmd) ]

docker exec -it --user root {์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„} bash

 > ๋ฃจํŠธ ๊ถŒํ•œ์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ์— ์ง„์ž…

 

[ Python3 ์„ค์น˜ (in cmd) ]

apt update

apt install -y python3 python3-pip

 > Python3 ๋ฐ pip ์„ค์น˜

 

[ ๊ฐ€์ƒ ํ™˜๊ฒฝ ์„ค์น˜ (in cmd) ]

apt-get update
apt-get install -y python3-venv

 > ํ•„์š” ํŒจํ‚ค์ง€ ๋ฐ ๊ฐ€์ƒ ํ™˜๊ฒฝ ์„ค์น˜

 

[ Chrome ์„ค์น˜ (in cmd) ]

apt-get update
apt-get install -y wget gnupg2 curl unzip

 > ํ•„์š” ํŒจํ‚ค์ง€ ์„ค์น˜

 

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
apt-get install -y ./google-chrome-stable_current_amd64.deb

 > Chrome ์„ค์น˜

 


๐Ÿ”ฅ headless ์˜ต์…˜ ์ถ”๊ฐ€

๋”๋ณด๊ธฐ
import pytest
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

@pytest.fixture
def createDriver():
    chromeOption = Options()

    chromeOption.add_argument('--start-maximized') # ์ „์ฒด ํ™”๋ฉด
    chromeOption.add_argument('--incognito') # ์‹œํฌ๋ฆฟ ๋ชจ๋“œ
    chromeOption.add_argument("--headless") # GUI ์—†์ด ํ…Œ์ŠคํŠธ
    chromeOption.add_argument("--no-sandbox") # ๋ธŒ๋ผ์šฐ์ €์˜ ๋ณด์•ˆ ๊ธฐ๋Šฅ ์—†์ด ํ…Œ์ŠคํŠธ
    chromeOption.add_argument('--disable-dev-shm-usage')  # shared memory ๋ฌธ์ œ ๋ฐฉ์ง€
    chromeOption.add_argument('--disable-gpu')  # ๊ฐ€์ƒํ™˜๊ฒฝ์—์„œ GPU ๊ธฐ๋Šฅ ๋น„ํ™œ์„ฑํ™”
    
    driver = webdriver.Chrome(options=chromeOption)

    yield driver

    driver.quit()

.๐Ÿ”ฅ ์˜์กด์„ฑ ํŒŒ์ผ(requirements.txt) ์ถ”๊ฐ€

๋”๋ณด๊ธฐ
pytest
selenium

๐Ÿ”ฅ Jenkinsfile ์ถ”๊ฐ€

๋”๋ณด๊ธฐ
pipeline {
    agent any
    
    stages {
        stage('Run Tests') {
            steps {
                sh '''
                    python3 -m venv venv
                    . venv/bin/activate
                    pip install -r requirements.txt
                    python3 -m pytest
                '''
            }
        }
    }
}

๐Ÿ”ฅ GitLab๊ณผ Jenkins ์—ฐ๋™ ๋ฐฉ๋ฒ•

๋”๋ณด๊ธฐ
 

[Jenkins] Jenkins GitLab ํ”„๋กœ์ ํŠธ ์—ฐ๋™ํ•˜๊ธฐ 01

[Jenkins] Jenkins GitLab ํ”„๋กœ์ ํŠธ ์—ฐ๋™ํ•˜๊ธฐ 01Jenkins์—์„œ GitLab, GitHub๊ณผ ๊ฐ™์€ Git Repository์™€ ์—ฐ๋™ํ•˜์—ฌ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.๊ทธ์ค‘ GitLab ํ”„๋กœ์ ํŠธ์™€ ์—ฐ๋™ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์–ด๋–ค ์„ค์ •์ด ํ•„์š”ํ•œ์ง€ ์•Œ

every-up.tistory.com

 

[Jenkins] Jenkins GitLab ํ”„๋กœ์ ํŠธ ์—ฐ๋™ํ•˜๊ธฐ 02

[Jenkins] Jenkins GitLab ํ”„๋กœ์ ํŠธ ์—ฐ๋™ํ•˜๊ธฐ 02Project Access Tokens ๋ฐœ๊ธ‰ ํ›„ ํ•ด๋‹น Tokens์œผ๋กœ GitLab ์„œ๋ฒ„๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์ž‘์—…์„ ์™„๋ฃŒํ•˜์˜€๊ณ ,์ด์ œ GitLab ํ”„๋กœ์ ํŠธ ์—ฐ๋™๊ณผ ๊ฐ„๋‹จํžˆ Pipeline์„ ๋™์ž‘ํ•˜๋Š” ์„ค์ •์„ ์ง„ํ–‰ํ•ด๋ณด

every-up.tistory.com

 

[Jenkins] Jenkins GitLab ํ”„๋กœ์ ํŠธ ์—ฐ๋™ํ•˜๊ธฐ 03

[Jenkins] Jenkins GitLab ํ”„๋กœ์ ํŠธ ์—ฐ๋™ํ•˜๊ธฐ 03GitLab ํ”„๋กœ์ ํŠธ ์—ฐ๋™๊ณผ ๊ฐ„๋‹จํžˆ Pipeline์„ ๋™์ž‘ํ•˜๋Š” ์„ค์ •์„ ์™„๋ฃŒํ•˜์˜€๊ณ ,์ด์ œ WebHook์„ ์—ฐ๋™ํ•˜์—ฌ Commit ๋“ฑ์˜ Event ์‹œ ์ž๋™์œผ๋กœ Jenkins Pipeline์ด ๋™์ž‘๋˜๋„๋ก ์„ค์ •

every-up.tistory.com

 > Webhook URL์—์„œ http://localhost:8080 ๋ถ€๋ถ„์„ ngrok์ด ์ƒ์„ฑํ•œ Forwarding ์ฃผ์†Œ๋กœ ๋ณ€ํ™˜

 



๐Ÿ“Œ 3/24 - 2์ผ์ฐจ ํšŒ๊ณ  (๋Œ€์ƒ ์„œ๋น„์Šค ๊ธฐ๋Šฅ ๋ช…์„ธ์„œ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ TC ์ž‘์„ฑ)

 

์˜ค๋Š˜์€ ๋ณธ๊ฒฉ์ ์ธ ์ž‘์—…์— ์•ž์„œ ๊ฐ„๋‹จํ•œ ์Šคํฌ๋Ÿผ ํšŒ์˜๋ฅผ ์ง„ํ–‰ํ–ˆ๋‹ค. ํŒ€์›๋ณ„๋กœ ์ž‘์„ฑํ•œ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ํ•จ๊ป˜ ๊ฒ€ํ† ํ•˜๊ณ  ํ”ผ๋“œ๋ฐฑ์„ ์ฃผ๊ณ ๋ฐ›์•˜์œผ๋ฉฐ, AI ๊ธฐ๋ฐ˜ ๊ธฐ๋Šฅ(์ทจํ•ฉ๋ฅ , DB ์ €์žฅ์†Œ ๋“ฑ)์˜ ๊ตฌ์กฐ ๋ฐ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์— ๋Œ€ํ•ด ๋…ผ์˜ํ–ˆ๋‹ค. ์ด์–ด ์‚ฌ์ดํŠธ ์ „๋ฐ˜์„ ๋ถ„์„ํ•˜๋ฉฐ ์—ฃ์ง€ ์ผ€์ด์Šค์™€ ๋ˆ„๋ฝ๋œ ์˜ค๋ฅ˜๋“ค์„ ์ถ”๊ฐ€๋กœ ํ™•์ธํ•˜๊ณ  ๊ณต์œ ํ–ˆ๋‹ค.
ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์˜ ๋ฐฉํ–ฅ์„ฑ๋„ ๋ช…ํ™•ํžˆ ์žฌ์ •์˜ํ–ˆ๋‹ค. QA ๋Œ€์ƒ ํ™ˆํŽ˜์ด์ง€์˜ UI์™€ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉ์ž ๊ด€์ ์—์„œ ๋‹ค์‹œ ์ ๊ฒ€ํ•ด, ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์˜ ํ˜„์‹ค์„ฑ์„ ๋†’์˜€๋‹ค. ์ฒ˜์Œ์—๋Š” ํšŒ์›๊ฐ€์ž…, ํ›„๊ธฐ๊ด€๋ฆฌ, ๋ฐ์ดํ„ฐ ์‹œ๊ฐํ™”์ฒ˜๋Ÿผ ๊ธฐ๋Šฅ ๋‹จ์œ„๋กœ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ๋‚˜๋ˆด๋Š”๋ฐ, ์‹ค์ œ ์‚ฌ์šฉ์ž ๊ด€์ ์—์„œ๋Š” ์ด๋Ÿฐ ๊ธฐ๋Šฅ๋“ค์ด ํƒญ ์•ˆ์—์„œ ํ†ตํ•ฉ์ ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค๋Š” ์ ์„ ๊นจ๋‹ฌ์•˜๋‹ค. ๊ทธ๋ž˜์„œ ์ดํ›„์—๋Š” ์‚ฌ์ดํŠธ ๊ตฌ์กฐ์— ๋งž์ถฐ 'ํ™ˆ', '๊ฐœ์ธ ํ”ผ๋“œ', 'ํŒ€ ํ”ผ๋“œ', 'ํžˆ์Šคํ† ๋ฆฌ' ํƒญ๋ณ„๋กœ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ๋‹ค์‹œ ์ •๋ฆฌํ–ˆ๋‹ค. ์ด ๋ฐฉํ–ฅ ์ „ํ™˜ ๋•๋ถ„์— ํ…Œ์ŠคํŠธ ํ˜„์‹ค์„ฑ์ด ๋†’์•„์กŒ๊ณ , ์ž๋™ํ™” ์ฝ”๋“œ ์ž‘์„ฑ๋„ ํ•œ๊ฒฐ ์ˆ˜์›”ํ•ด์กŒ๋‹ค.
 
์™€ ๊ทธ๋ฆฌ๊ณ  ์˜ค๋Š˜ ์•Œ๊ฒŒ๋œ ์‚ฌ์‹ค.. GitHub Desktop์œผ๋กœ๋„ GitLab์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค..(์‚ฌ์ดํŠธ ๋ฐ”๋กœ๊ฐ€๊ธฐ)


๐Ÿ“Œ 3/25 - 3์ผ์ฐจ ํšŒ๊ณ  (TC ์ž‘์„ฑ ๋งˆ๋ฌด๋ฆฌ)

๊ฒฝ๋ ฅ์ด ์—†์–ด์„œ์ธ์ง€ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ TC์ธ ํšŒ์›๊ฐ€์ž…๊ณผ ๋กœ๊ทธ์ธ ํŒŒํŠธ๋ฅผ ๋งก๊ฒŒ ๋˜์—ˆ๊ณ , ๋•๋ถ„์— ๋‚˜๋Š” TC ์ž‘์„ฑ์„ ๊ฐ€์žฅ ๋จผ์ € ๋งˆ๋ฌด๋ฆฌํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์˜คํ›„ 7์‹œ์— ์˜ˆ์ •๋œ ์˜คํ”ผ์Šค ์•„์›Œ ์‹œ๊ฐ„์— ์ž‘์„ฑํ•œ TC์— ๋Œ€ํ•œ ํ”ผ๋“œ๋ฐฑ์„ ์š”์ฒญํ•˜๊ธฐ๋กœ ํ–ˆ๊ณ , ์•„์ง ๋‹ค๋ฅธ ๋ถ„๋“ค์€ TC ์ž‘์„ฑ์„ ์ง„ํ–‰ ์ค‘์ด์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋‚จ๋Š” ์‹œ๊ฐ„ ๋™์•ˆ GitLab ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ๋ฅผ ํ™œ์šฉํ•ด GitLab๊ณผ Jenkins ์—ฐ๋™์— ๋„์ „ํ•ด๋ณด์•˜๋‹ค.
๋‹คํ–‰ํžˆ ์˜ค๋Š˜์€ ์•ฝ 3์‹œ๊ฐ„ ๋งŒ์— GitLab๊ณผ Jenkins๋ฅผ ์ •์ƒ์ ์œผ๋กœ ์—ฐ๋™ํ–ˆ๊ณ , GitLab ํ”„๋กœ์ ํŠธ ๋‚ด Jenkinsfile์„ ํ†ตํ•ด ํŒŒ์ดํ”„๋ผ์ธ์ด ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ๊นŒ์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์ด ์ž‘์—…์„ 2์ผ ๋„˜๊ฒŒ ๋ถ™์žก๊ณ  ์žˆ์—ˆ๋˜ ํ„ฐ๋ผ, Webhook ์—ฐ๋™๊ณผ ๋นŒ๋“œ ์„ฑ๊ณต ๋ฉ”์‹œ์ง€๋ฅผ ๋ดค์„ ๋• ์ •๋ง ์ง„์‹ฌ์œผ๋กœ ๊ธฐ๋ปค๋‹ค. ๊ทธ๋ž˜๋„ ์ดํ‹€ ๋™์•ˆ ์—ฌ๋Ÿฌ ๊ฐ€์ง€๋ฅผ ์‹œ๋„ํ•ด๋ณธ ๋•๋ถ„์— ๊ฒฐ๊ตญ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ๊ฒƒ ๊ฐ™๋‹ค. ๊ทธ ๊ณผ์ •์—์„œ ngrok์ด๋ผ๋Š” ํˆด๋„ ์ƒˆ๋กญ๊ฒŒ ์•Œ๊ฒŒ ๋˜์–ด ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋‚ด ๋กœ์ปฌ ์„œ๋ฒ„(localhost:8080)๋Š” ์™ธ๋ถ€์—์„œ ์ง์ ‘ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, ngrok์„ ํ†ตํ•ด ์™ธ๋ถ€์—์„œ๋„ ์ ‘์† ๊ฐ€๋Šฅํ•œ ์ฃผ์†Œ๋ฅผ ์ƒ์„ฑํ•ด Webhook ์—ฐ๊ฒฐ์„ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.
 
ํ˜„์žฌ๋Š” Docker ํ™˜๊ฒฝ์—์„œ jenkins/jenkins ๊ณต์‹ ์ด๋ฏธ์ง€๋ฅผ ๋ฐ”๋กœ ์‚ฌ์šฉํ•ด Jenkins ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ํŒŒ์ด์ฌ์ด๋‚˜ ํฌ๋กฌ ๋“ฑ์˜ ๋„๊ตฌ๋Š” ๋งค๋ฒˆ ์ˆ˜๋™์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ ๋‚ด์— ์„ค์น˜ํ•ด ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค. ํ•˜์ง€๋งŒ Dockerfile์„ ํ™œ์šฉํ•ด ์ปค์Šคํ…€ ์ด๋ฏธ์ง€๋ฅผ ๋งŒ๋“ค์–ด๋‘๋ฉด, ์ด๋Ÿฌํ•œ ๋„๊ตฌ๋“ค์ด ๋ฏธ๋ฆฌ ์„ค์น˜๋œ Jenkins ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ž๋™์œผ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์–ด ๋งค๋ฒˆ ์ˆ˜๋™ ์„ค์น˜ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํŒ€์›๋“ค๋„ ๋™์ผํ•œ ํ™˜๊ฒฝ์„ ์†์‰ฝ๊ฒŒ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์–ด ์„ค์ • ๊ณผ์ •์ด ํ›จ์”ฌ ๊ฐ„ํŽธํ•ด์ง„๋‹ค. ๊ทธ๋ž˜์„œ ์ด๋ฒˆ์— ์ง์ ‘ ๋„์ „ํ•ด๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค.
 
๐Ÿ”ฅ Dockerfile ์ƒ์„ฑ (Jenkins + Git Plugin + GitLab Plugin + Python3 + ๊ฐ€์ƒ ํ™˜๊ฒฝ + Chrome)

๋”๋ณด๊ธฐ

[ Dockerfile ์ƒ์„ฑ ]

FROM jenkins/jenkins:lts

USER root

# ํ•„์ˆ˜ ๋„๊ตฌ ์„ค์น˜
RUN apt-get update && apt-get install -y \
    python3 python3-pip python3-venv \
    git \
    curl wget unzip gnupg2 && \
    apt-get clean

# Chrome ์„ค์น˜
RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb && \
    apt-get install -y ./google-chrome-stable_current_amd64.deb && \
    rm google-chrome-stable_current_amd64.deb

# Git, GitLab ํ”Œ๋Ÿฌ๊ทธ์ธ ์ง์ ‘ ์„ค์น˜
RUN jenkins-plugin-cli --plugins \
    git \
    gitlab-plugin \
    workflow-aggregator \
    credentials-binding

USER jenkins

 

[ Dockerfile ๋นŒ๋“œ (in VS Code ํ„ฐ๋ฏธ๋„) ]

์œ„ Dockerfile์ด ๋‹ด๊ธด ํด๋”๋ฅผ VS Code๋กœ ์—ด๊ธฐ

docker build -t {์ด๋ฏธ์ง€ ์ด๋ฆ„} .

 

[ Jenkins ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰ (in VS Code ํ„ฐ๋ฏธ๋„) ]

docker run -d -p {์™ธ๋ถ€ ํฌํŠธ}:{์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€ ํฌํŠธ} -p 50000:50000 --name {์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„} {์ด๋ฏธ์ง€ ์ด๋ฆ„}

 


 

์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค! Plugin๋ถ€ํ„ฐ Python3, ๊ฐ€์ƒ ํ™˜๊ฒฝ, Chrome๊นŒ์ง€ ๋ชจ๋‘ ์„ค์น˜๋œ Jenkins ์ปค์Šคํ…€ Dockerfile์„ ๋นŒ๋“œํ•ด ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์ด ์ด๋ฏธ์ง€๋กœ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ํ•œ ๋’ค GitLab๊ณผ ์—ฐ๋™ํ•˜๋‹ˆ, ํ•ด๋‹น GitLab ํ”„๋กœ์ ํŠธ ๋‚ด์˜ Jenkinsfile๋„ ์ž˜ ์ธ์‹๋œ๋‹ค. ์ด์ œ ์œ„ ๋ชจ๋“  ๊ณผ์ •๋“ค์„ ์ƒ๋žตํ•˜๊ณ  ngrok ์„ค์น˜์™€ Dockerfile๋งŒ ๊ณต์œ ํ•˜๋ฉด, ํŒ€์›๋“ค๋„ ๋น ๋ฅด๊ฒŒ ๋™์ผํ•œ ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.
 

TC ์ž‘์„ฑ์€ ์˜ค๋Š˜์„ ๋งˆ์ง€๋ง‰์œผ๋กœ ์ตœ์ข… ๋งˆ๋ฌด๋ฆฌํ–ˆ๋‹ค. ์†”์งํžˆ ๊ณ„์† ์ˆ˜์ •ํ•˜๋ ค๋ฉด ๋๋„ ์—†๊ณ , ๋ณธ๊ฒฉ์ ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์ „์— ํ™˜๊ฒฝ ์„ค์ •๋ถ€ํ„ฐ ํ•ด์•ผ ํ•  ์ผ๋“ค์ด ๋งŽ๋‹ค ๋ณด๋‹ˆ, ์–ธ์ œ๊นŒ์ง€๋‚˜ TC๋งŒ ๋ถ™์žก๊ณ  ์žˆ์„ ์ˆ˜๋Š” ์—†์—ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ ๋ฐœ๊ฒฌํ•œ ๋ถ€๋ถ„์— ๋”ฐ๋ผ TC๋ฅผ ์ˆ˜์ •ํ•ด๋„ ๊ดœ์ฐฎ์„ ๊ฒƒ ๊ฐ™์•„์„œ, ์˜ค๋Š˜์„ ๊ธฐ์ค€์œผ๋กœ ์ผ๋‹จ๋ฝ ์ง“๊ธฐ๋กœ ํ–ˆ๋‹ค. ์–ด์ฐจํ”ผ ๊ฐœ๋ฐœ์„ ํ•˜๋‹ค ๋ณด๋ฉด ๋ฏธ์ฒ˜ ์ƒ๊ฐํ•˜์ง€ ๋ชปํ–ˆ๋˜ ์˜ˆ์™ธ๋‚˜ ํ๋ฆ„๋„ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋“œ๋Ÿฌ๋‚  ํ…Œ๋‹ˆ๊นŒ..


๐Ÿ“Œ 3/26 - 4์ผ์ฐจ ํšŒ๊ณ  (์ฝ”๋“œ ์ž‘์„ฑ ์ „ ๊ต์œก ์ง„ํ–‰ ๋ฐ ๊ตฌ์กฐ ์„ค๊ณ„)

 
๐Ÿ”ฅ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” import

๋”๋ณด๊ธฐ

import time
import pytest
import selenium

 

from selenium.webdriver.common.by import By

from selenium.webdriver.chrome.webdriver import WebDriver

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

from selenium.webdriver.common.keys import Keys

from selenium.webdriver.support.ui import Select

from selenium.webdriver.common.action_chains import ActionChains
from selenium.common.exceptions import NoSuchElementException, TimeoutException

 


 

ํŒ€์›๋“ค์ด ์•„์ง Python ๋ฌธ๋ฒ•(๋งค๊ฐœ๋ณ€์ˆ˜, ์ธ์ž, ํด๋ž˜์Šค, ๊ฐ์ฒด, ์ƒ์„ฑ์ž ๋“ฑ)์— ์ต์ˆ™ํ•˜์ง€ ์•Š์€ ์ƒํƒœ๋ผ, ์˜ค๋Š˜์€ ๋‚ด๊ฐ€ Live Share ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•ด ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ ๊ฐ•์˜๋ฅผ ์ง„ํ–‰ํ–ˆ๋‹ค. ํ‰์†Œ์—๋Š” ์„œ๋กœ์˜ ํ™”๋ฉด์„ ์ง์ ‘ ๋ณด์—ฌ์ค˜์•ผ ํ•˜๋Š” ๋ถˆํŽธํ•จ์ด ์žˆ์—ˆ์ง€๋งŒ, Live Share๋ฅผ ํ†ตํ•ด ๋™์ผํ•œ ์ฝ”๋“œ์— ํ•จ๊ป˜ ์ ‘์†ํ•˜๋ฉด์„œ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์„œ๋กœ ์งˆ๋ฌธํ•˜๊ณ  ํ”ผ๋“œ๋ฐฑ ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ์–ด ํ›จ์”ฌ ํšจ์œจ์ ์œผ๋กœ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.
 
๐Ÿ”ฅ mainPage.py

๋”๋ณด๊ธฐ
# Page Object ํด๋ž˜์Šค (UI ์š”์†Œ ๋ฐ ๋ฉ”์„œ๋“œ ์ •์˜)

import json
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

from src.utils import mainLocators

class mainPage():
    URL = "https://kdt-pt-1-pj-2-team03.elicecoding.com/signin"

    def __init__(self, driver: WebDriver):
        self.driver = driver
        self.wait = WebDriverWait(self.driver, 10)

        with open("credentials.json", "r", encoding="utf-8") as f:
            self.userInfo = json.load(f)

    def goToPage(self, depth2):
        if (depth2 == "๋ฉ”์ธ ํŽ˜์ด์ง€"):
            self.driver.get(self.URL)
        elif (depth2 == "ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€"):
            self.driver.get(self.URL)
            self.getElement(mainLocators.REGISTER_BTN).click()
            # ์ฒซ๋ฒˆ์งธ ์—ฌ๊ธฐ์„œ url ๊ฒ€์ฆ
        elif (depth2 == "์•ฑ ์ธ์ฆ ๊ถŒํ•œ"):
            pass
        elif (depth2 == "๋กœ๊ทธ์ธ ์˜ค๋ฅ˜ ํŽ˜์ด์ง€"):
            pass
        elif (depth2 == "์ธ์ ์‚ฌํ•ญ ์ž‘์„ฑ ํŽ˜์ด์ง€"):
            pass
        elif (depth2 == "๋กœ๊ทธ์ธ ํŽ˜์ด์ง€"):
            self.driver.get(mainLocators.URL)
            self.getElement(mainLocators.LOGIN_BTN).click()
        elif (depth2 == "๋น„๋ฐ€๋ฒˆํ˜ธ ์žฌ์„ค์ • ํŽ˜์ด์ง€"):
            pass

    def getElement(self, element):
        result = self.wait.until(EC.presence_of_element_located(element))
        return result

๐Ÿ”ฅ test_mainPage.py

๋”๋ณด๊ธฐ
# ์‹ค์ œ ํ…Œ์ŠคํŠธ ์Šคํฌ๋ฆฝํŠธ (test_*.py ํ˜•์‹)

import time
import pytest
import inspect
from src.pages.mainPage import mainPage

# ๊ตฌ๊ธ€ ์Šคํ”„๋ ˆ๋“œ ์‹œํŠธ ์ฐธ๊ณ  (depth2 ๊ธฐ์ค€์œผ๋กœ ํ•˜๊ณ , ์˜†์— test id ์—ด ์ถ”๊ฐ€)
def test_login_001(createDriver):
    try:
        myMainPage = mainPage(createDriver)
        myMainPage.goToPage("๋ฉ”์ธ ํŽ˜์ด์ง€")
        time.sleep(2)

        assert "signin" in myMainPage.driver.current_url
    except Exception as e:
        print(f"[โ—] {e}")

def test_login_002(createDriver):
    myMainPage = mainPage(createDriver)
    myMainPage.goToPage("๋กœ๊ทธ์ธ ํŽ˜์ด์ง€")
    time.sleep(2)

def test_login_003(createDriver):
    myMainPage = mainPage(createDriver)
    myMainPage.goToPage("ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€")
    time.sleep(2)

๐Ÿ”ฅ mainLocators.py

๋”๋ณด๊ธฐ
from selenium.webdriver.common.by import By

# ๋ฉ”์ธ ํŽ˜์ด์ง€ ์š”์†Œ
LOGIN_BTN = (By.XPATH, "//button[text()='๋กœ๊ทธ์ธํ•˜๊ธฐ']")
REGISTER_BTN = (By.XPATH, "//button[text()='ํšŒ์›๊ฐ€์ž…']")

ID_INPUT = (By.ID, "username")
PW_INPUT = (By.ID, "password")

PW_TOGGLE_BTN = (By.XPATH, "//button[@data-action='toggle']") #์†์„ฑ์€ @๋กœ ์ฐพ๊ธฐ
PW_RESET = (By.XPATH, "//button[text()='๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์žŠ์œผ์…จ๋‚˜์š”?']")

GOING_BTN = (By.XPATH, "//button[text()='๊ณ„์†ํ•˜๊ธฐ']") #ํ…์ŠคํŠธ๋Š” @์ƒ๋žต

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

์˜คํ”ผ์Šค์•„์›Œ ์‹œ๊ฐ„์—๋Š” ์ค‘๋ณต๋˜๋Š” ํŽ˜์ด์ง€ ์ด๋™ ๊ณผ์ •์„ ํ•จ์ˆ˜๋กœ ๋ถ„๋ฆฌํ•œ ๋ฐฉ์‹์— ๋Œ€ํ•ด ์ฝ”์น˜๋‹˜๊ป˜ ํ”ผ๋“œ๋ฐฑ์„ ์š”์ฒญ๋“œ๋ ธ๋‹ค. ์›๋ž˜ ์‹ค๋ฌด์—์„œ๋„ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค(TC) ํ•˜๋‚˜๋‹น ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ํ•˜๋‚˜๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ด๋ฉฐ, ์ž๋™ํ™” ํ…Œ์ŠคํŠธ์—์„œ๋Š” TC๊ฐ€ ์ฝ”๋“œ ๊ตฌ์กฐ์˜ ๊ธฐ์ค€์ด ๋˜๋ฏ€๋กœ, ๋‚ด๊ฐ€ ์‹œ๋„ํ•œ ์ค‘๋ณต ๋กœ์ง ๋ถ„๋ฆฌ ๋ฐฉ์‹์€ ๋‚˜์˜์ง€ ์•Š๋‹ค๊ณ  ํ•˜์…จ๋‹ค.
๋‹ค๋งŒ ๋ณธ์ธ์ด๋ผ๋ฉด goToPage()์™€ ๊ฐ™์€ ๊ณตํ†ต ์ด๋™ ํ•จ์ˆ˜๋Š” Util ๋ชจ๋“ˆ๋กœ ๋”ฐ๋กœ ๋นผ๊ณ , ๊ฐ ํŽ˜์ด์ง€ ํด๋ž˜์Šค ๋‚ด์—์„œ๋Š” goToSecondaryPage()์ฒ˜๋Ÿผ ํ•ด๋‹น ํŽ˜์ด์ง€ ๋‚ด์˜ ์„ธ๋ถ€ ์ด๋™์€ ๋‚ด๋ถ€ ํ•จ์ˆ˜๋กœ ์ฒ˜๋ฆฌํ•  ๊ฒƒ ๊ฐ™๋‹ค๊ณ  ํ•˜์…จ๋‹ค. ์ด ๋ฐฉ์‹์ด ๋” ํšจ์œจ์ ์ธ์ง€์— ๋Œ€ํ•ด์„œ๋Š” ๊ฒ€ํ† ํ•ด๋ณผ ํ•„์š”๊ฐ€ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.
ํŽ˜์ด์ง€ ์š”์†Œ ๊ด€๋ จ ๋ณ€์ˆ˜๋ฅผ mainPage.py์™€ test_mainPage.py ๋‘ ํŒŒ์ผ์—์„œ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ํ•ด๋‹น ๋ณ€์ˆ˜๋“ค์„ ๋ณ„๋„ Util ๋ชจ๋“ˆ๋กœ ๋ถ„๋ฆฌํ•ด ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ๋” ๊น”๋”ํ•˜๋‹ค๋Š” ํ”ผ๋“œ๋ฐฑ์„ ๋ฐ›์•˜๋‹ค. ์ด์— ๋”ฐ๋ผ ์ผ๋ถ€ ๊ตฌ์กฐ๋ฅผ ๊ฐœ์„ ํ•ด, ์š”์†Œ๋ฅผ Util์—์„œ importํ•ด ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ณ€๊ฒฝํ–ˆ๋‹ค. ๋˜ํ•œ ํŽ˜์ด์ง€๋ณ„๋กœ locator ํŒŒ์ผ์„ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•˜๋ฉด, ์š”์†Œ ๋ณ€๊ฒฝ ์‹œ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์‰ฌ์›Œ์ง€๊ณ , ํ•„์š”ํ•œ ์š”์†Œ๋Š” import๋งŒ์œผ๋กœ ํŽธ๋ฆฌํ•˜๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ๋„ ์žˆ์–ด ์ด ๊ตฌ์กฐ๋ฅผ ์ฑ„ํƒํ–ˆ๋‹ค.
ํŠนํžˆ ๋‚˜๋Š” ํ•ด๋‹น ์š”์†Œ๊ฐ€ ์–ด๋–ค ๋ฐฉ์‹(id, name, xpath ๋“ฑ)์œผ๋กœ ์ •์˜๋˜์—ˆ๋Š”์ง€๊นŒ์ง€ ํ•จ๊ป˜ ๋ช…์‹œํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค๊ณ  ํŒ๋‹จํ•ด, locator๋ฅผ ํŠœํ”Œ ํ˜•ํƒœ๋กœ ์ •์˜ํ–ˆ๋‹ค. ์ด ํŠœํ”Œ์€ wait ๊ธฐ๋Šฅ์„ ํฌํ•จํ•œ getElement() ํ•จ์ˆ˜์— ๊ทธ๋Œ€๋กœ ๋„˜๊ฒจ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ์„ค๊ณ„ํ–ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์ •๋ฆฌํ•œ ๊ตฌ์กฐ๋Š” ์žฌ์‚ฌ์šฉ์„ฑ, ๊ฐ€๋…์„ฑ, ์œ ์ง€๋ณด์ˆ˜ ์ธก๋ฉด์—์„œ ๋ชจ๋‘ ๋งŒ์กฑ์Šค๋Ÿฌ์› ๊ณ , ๋ฌด์—‡๋ณด๋‹ค ์ฝ”๋“œ ์ž‘์„ฑ ์‹œ ์ƒ๊ฐ์˜ ํ๋ฆ„์ด ๋ช…ํ™•ํ•ด์ ธ์„œ ๊ฐœ์ธ์ ์œผ๋กœ๋„ ๋งค์šฐ ๋งŒ์กฑ์Šค๋Ÿฌ์šด ๋ฆฌํŒฉํ† ๋ง์ด์—ˆ๋‹ค.


๐Ÿ“Œ 3/27 - 5์ผ์ฐจ ํšŒ๊ณ  (TC๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋ณธ๊ฒฉ์ ์ธ ์ž๋™ํ™” ์ฝ”๋“œ ์ž‘์„ฑ)

 

์˜ค๋Š˜์€ ํŒ€์›๋ถ„๋“ค๊ป˜์„œ ๋กœ๊ทธ์ธ/ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€์˜ UI ์š”์†Œ๋“ค์„ ๋ชจ๋‘ ์‹๋ณ„ํ•ด์ฃผ์…จ๊ณ , ํ•ด๋‹น ์š”์†Œ๋“ค์€ ๊ณตํ†ต Util ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ์ •๋ฆฌํ–ˆ๋‹ค. ๋‚˜๋Š” ์ด ๊ณผ์ •์—์„œ ๊ธฐ์กด ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋“ค์„ ํ•จ๊ป˜ ๊ฒ€ํ† ํ•˜๋ฉด์„œ, ํ•˜๋‚˜์˜ ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ์•ˆ์—์„œ ๋™์‹œ์— ๊ฒ€์ฆํ•˜๋Š” ๊ฒƒ์ด ํšจ๊ณผ์ ์ธ ์ผ€์ด์Šค๋“ค์„ ๋ฌถ์–ด ์žฌ๊ตฌ์„ฑํ–ˆ๋‹ค. ๊ทธ ๊ฒฐ๊ณผ, ๋กœ๊ทธ์ธ/ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ๊ด€๋ จ ์ด 64๊ฐœ์˜ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ๋ถ„์„ํ•ด 25๊ฐœ์˜ ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜๋กœ ๋‚˜๋ˆ„์—ˆ๊ณ , ๊ฐ ๋ฌถ์Œ์—๋Š” ๋ณ„๋„์˜ ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ID๋ฅผ ๋ถ€์—ฌํ•ด ์ฒด๊ณ„์ ์œผ๋กœ ๊ด€๋ฆฌํ–ˆ๋‹ค. ๋˜ํ•œ, ์ค‘๋ณต๋˜๋Š” ๋™์ž‘์€ ๋ณ„๋„ ํ•จ์ˆ˜๋กœ ๋ถ„๋ฆฌํ•ด ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ •๋ฆฌํ–ˆ๋‹ค.
์ด๋ ‡๊ฒŒ ๊ธฐ๋ณธ์ ์ธ ์ค€๋น„๋ฅผ ๋งˆ์นœ ๋’ค, ๋ณธ๊ฒฉ์ ์œผ๋กœ ํ…Œ์ŠคํŠธ ์ž๋™ํ™” ์ฝ”๋“œ ์ž‘์„ฑ์„ ์‹œ์ž‘ํ–ˆ๋‹ค. ์•„์ง์€ ๊ต์œก ๋ฐ ์—ฐ์Šต ๋‹จ๊ณ„์ด๊ธฐ๋„ ํ•ด์„œ, ํŒ€์›๋“ค๊ณผ ๋กœ๊ทธ์ธ/ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€๋ฅผ ํ•จ๊ป˜ ์ž‘์—…ํ•˜๋ฉฐ ํ˜‘์—…์„ ์‹œ๋„ํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๊ณผ์ •์—์„œ Live Share์˜ ํ•œ๊ณ„๋ฅผ ๋ผˆ์ €๋ฆฌ๊ฒŒ ๋А๊ผˆ๋‹ค. ๊ฐ์ž์˜ ๋กœ์ปฌ ํ™˜๊ฒฝ์—์„œ๋Š” ํ…Œ์ŠคํŠธ ์‹คํ–‰์ด ์–ด๋ ค์› ๊ธฐ ๋•Œ๋ฌธ์—, ๋ชจ๋“  ํ…Œ์ŠคํŠธ ์‹คํ–‰์€ ๋‚ด ์ปดํ“จํ„ฐ์—์„œ๋งŒ ๊ฐ€๋Šฅํ–ˆ๊ณ , ํŒ€์›๋ถ„๋“ค์ด ํ…Œ์ŠคํŠธ๋ฅผ ์š”์ฒญํ•  ๋•Œ๋งˆ๋‹ค ๋‚ด ์ž‘์—…์€ ์ค‘๋‹จ๋  ์ˆ˜๋ฐ–์— ์—†์–ด ์ฝ”๋“œ ์ž‘์„ฑ ์†๋„๊ฐ€ ํ˜„์ €ํžˆ ๋А๋ ค์กŒ๋‹ค.
๊ฒŒ๋‹ค๊ฐ€ ํ…Œ์ŠคํŠธ ๋„์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, ์˜ค๋ฅ˜ ์›์ธ๊ณผ ๊ฐœ๋…์„ ์„ค๋ช…ํ•˜๊ณ  ์ง์ ‘ ์ˆ˜์ •์„ ๋„์™€์•ผ ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž‘์—…์— ๋Œ€ํ•œ ์ง‘์ค‘๋„๊ฐ€ ์ž์ฃผ ๋ถ„์‚ฐ๋˜์—ˆ๋‹ค. ๋ฌผ๋ก  ํŒ€์›๋“ค์˜ ์„œ๋กœ ๋‹ค๋ฅธ ์ˆ™๋ จ๋„๋ฅผ ๊ณ ๋ คํ•ด ํ•จ๊ป˜ ๊ณต๋ถ€ํ•˜๋ฉฐ ์ง„ํ–‰ํ•œ ์ ์€ ์˜๋ฏธ ์žˆ์—ˆ์ง€๋งŒ, ์ง€๊ธˆ์€ ๋‹จ์ˆœํ•œ ํ•™์Šต์ด ์•„๋‹Œ ์‹ค์ œ ๊ฒฐ๊ณผ๋ฌผ์„ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋Š” ํ”„๋กœ์ ํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์—, ์—ญํ• ์„ ๋ถ„๋‹ดํ•ด ๋ณด๋‹ค ํšจ์œจ์ ์œผ๋กœ ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ๋А๊ผˆ๋‹ค.
๋‚จ์€ ์‹œ๊ฐ„์ด ๋งŽ์ง€ ์•Š๋‹ค๋Š” ํ˜„์‹ค์ ์ธ ์ œ์•ฝ๋„ ์žˆ์–ด, ๊ณ„์† ํ•จ๊ป˜ ๋ถ™์žก๊ณ  ์ž‘์—…ํ•˜๊ธฐ์—” ์–ด๋ ค์›€์ด ์žˆ์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐ์ž๊ฐ€ ์ž‘์„ฑํ•œ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค(TC)์™€ ๊ด€๋ จ๋œ ํŽ˜์ด์ง€๋ฅผ ๊ฐœ๋ณ„์ ์œผ๋กœ ๋งก์•„ ์ž๋™ํ™” ๊ตฌํ˜„์„ ์ง„ํ–‰ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ „๋žต์„ ๋ณ€๊ฒฝํ–ˆ๋‹ค.

๋‚ด์ผ๋ถ€ํ„ฐ๋Š” ๋ณธ๊ฒฉ์ ์œผ๋กœ ๊ฐ์ž์˜ TC์™€ ๊ด€๋ จ๋œ ์ฝ”๋“œ ๊ตฌํ˜„์ด ์‹œ์ž‘๋  ์˜ˆ์ •์ด์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋‚˜๋Š” ํŒ€์›๋“ค์ด ๋ฐ”๋กœ ์ž‘์—…์— ํˆฌ์ž…๋  ์ˆ˜ ์žˆ๋„๋ก ๊ฐ์ž์˜ ์ฝ”๋“œ ํ‹€์„ ๋ฏธ๋ฆฌ ์žก์•„์ฃผ๋Š” ์ž‘์—…๋„ ํ•จ๊ป˜ ์ง„ํ–‰ํ–ˆ๋‹ค. ๊ฐ ํŽ˜์ด์ง€๋ณ„๋กœ ํ•„์š”ํ•œ ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ , ํด๋ž˜์Šค ๊ตฌ์กฐ์™€ ์ƒ์„ฑ์ž ์„ธํŒ…, ์ „์ฒด์ ์ธ ํ‹€์„ ๋จผ์ € ๊ตฌ์„ฑํ•ด ๋‘์—ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๊ธฐ๋ณธ ๊ณจ๊ฒฉ์ด ์žกํžŒ ์ƒํƒœ์—์„œ ์‹œ์ž‘ํ•˜๋ฉด ํ˜ผ๋ž€์„ ์ค„์ด๊ณ , ๊ฐ์ž ๊ตฌํ˜„์— ์ข€ ๋” ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ๋ผ ํŒ๋‹จํ–ˆ๋‹ค.

๋‚˜๋Š” ํšŒ์›๊ฐ€์ž…๊ณผ ๋กœ๊ทธ์ธ์ด ํฌํ•จ๋œ ๋ฉ”์ธ ํŽ˜์ด์ง€์˜ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ๋‹ด๋‹นํ•˜๊ณ  ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, ํ•ด๋‹น ํŽ˜์ด์ง€๋ถ€ํ„ฐ ๋น ๋ฅด๊ฒŒ ์ž๋™ํ™” ์ฝ”๋“œ๋ฅผ ์™„์„ฑํ•œ ๋’ค, ๋‹ค๋ฅธ ํŒ€์›๋“ค์ด ๋งก์€ ํŽ˜์ด์ง€ ๊ตฌํ˜„๋„ ๋„์šธ ๊ณ„ํš์ด๋‹ค. ์ด๋ ‡๊ฒŒ ์—ญํ• ์„ ๋ถ„๋ฐฐํ•˜๋ฉด ์ „์ฒด ์ง„ํ–‰ ์†๋„๋ฅผ ๋†’์ผ ์ˆ˜ ์žˆ๊ณ , ๊ฒฐ๊ณผ๋ฌผ ์™„์„ฑ์—๋„ ๋ณด๋‹ค ๊ฐ€๊นŒ์›Œ์งˆ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค๋Š” ํŒ๋‹จ์ด ๋“ค์—ˆ๋‹ค.
 


๊ทธ๋ฆฌ๊ณ  ๊ฐ์ž ํŽ˜์ด์ง€๋ฅผ ๋งก์•„ ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๋ ค๋ฉด, ๊ธฐ๋ณธ ๊ฐœ๋…์— ๋Œ€ํ•œ ์ •ํ™•ํ•œ ์ดํ•ด๊ฐ€ ํ•„์ˆ˜์ ์ด๋ผ๊ณ  ํŒ๋‹จํ–ˆ๋‹ค. ํŠนํžˆ ํŒ€์›๋ถ„๋“ค๊ป˜์„œ ํ—ท๊ฐˆ๋ คํ•˜์‹œ๋Š” ํด๋ž˜์Šค, ๊ฐ์ฒด, self, ์ƒ์„ฑ์ž ๊ฐ™์€ ๊ฐœ๋…์€ ๋ฐ˜๋ณต์ ์œผ๋กœ ์„ค๋ช…ํ•˜๋Š” ์ƒํ™ฉ์ด ์ž์ฃผ ๋ฐœ์ƒํ–ˆ๊ณ , ๊ฐ™์€ ๋‚ด์šฉ์„ ์—ฌ๋Ÿฌ ๋ฒˆ ์„ค๋ช…ํ•˜๋Š” ๊ฒƒ์ด ์ ์  ๋น„ํšจ์œจ์ ์ด๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.
๊ทธ๋ž˜์„œ ์˜ค๋Š˜์€ ๋ฐค 10์‹œ 30๋ถ„์— ์ง‘์— ๋„์ฐฉํ•˜์ž๋งˆ์ž, ํ”ผ๊ณคํ•œ ๋ชธ์„ ์ด๋Œ๊ณ  ์•„์ดํŒจ๋“œ๋ฅผ ๊บผ๋‚ด ๋“ค์—ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ตฟ๋…ธํŠธ๋ฅผ ์ด์šฉํ•ด ํ•ด๋‹น ๊ฐœ๋…๋“ค์„ ์ •๋ฆฌํ•œ PDF ์ž๋ฃŒ๋ฅผ ๋งŒ๋“ค์–ด ํŒ€์›๋“ค๊ณผ ๊ณต์œ ํ–ˆ๋‹ค. ์‚ฌ์‹ค ๋‚˜๋„ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ฒ˜์Œ ๋ฐฐ์šธ ๋•Œ ์ด ๊ฐœ๋…๋“ค์ด ์ •๋ง ํ—ท๊ฐˆ๋ ธ๋˜ ๊ธฐ์–ต์ด ์žˆ์–ด์„œ, ํŒ€์›๋“ค์˜ ์–ด๋ ค์›€์— ์ถฉ๋ถ„ํžˆ ๊ณต๊ฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.
ํ•œ ๋ฒˆ ์ •๋ฆฌํ•ด๋‘๋ฉด ์ดํ›„ ์„ค๋ช…์— ๋“œ๋Š” ์‹œ๊ฐ„๋„ ์ค„์–ด๋“ค๊ณ , ํŒ€์›๋“ค๋„ ๊ฐ์ž ๊ตฌํ˜„์„ ์ง„ํ–‰ํ•˜๋Š” ๋ฐ ํ›จ์”ฌ ์ˆ˜์›”ํ•  ๊ฒƒ ๊ฐ™์•„ ๋Šฆ์€ ์‹œ๊ฐ„์ด์—ˆ์ง€๋งŒ ์„œ๋‘˜๋Ÿฌ ์ •๋ฆฌํ•ด ๊ณต์œ ํ•˜๊ฒŒ ๋๋‹ค.


๐Ÿ“Œ 3/28 - 6์ผ์ฐจ ํšŒ๊ณ  (๋ฉ”์ธ ํŽ˜์ด์ง€ ์ž๋™ํ™” ํ…Œ์ŠคํŠธ ๊ตฌํ˜„ ์™„๋ฃŒ)

 

์˜ค๋Š˜์€ ์–ด์ œ ํŒ€์›๋ถ„๋“ค๊ป˜์„œ ์ฐพ์•„์ฃผ์‹  ๋ฉ”์ธ ํŽ˜์ด์ง€ ๋‚ด ์š”์†Œ๋“ค์„ ๋ฐ”ํƒ•์œผ๋กœ, ๋ณ€์ˆ˜๋ช…์„ ํŽ˜์ด์ง€ ๊ตฌ์กฐ์— ๋งž๊ฒŒ ์ „๋ฐ˜์ ์œผ๋กœ ์ˆ˜์ •ํ–ˆ๋‹ค. ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜ ํŽธ์˜์„ฑ์„ ๊ณ ๋ คํ•ด ์ด๋ฆ„์„ ์ผ๊ด€๋˜๊ฒŒ ์ •๋ฆฌํ–ˆ์œผ๋ฉฐ, ๊ทธ ๊ณผ์ •์—์„œ ์ž˜๋ชป ์ง€์ •๋œ ์š”์†Œ๋“ค๋„ ๊ฝค ๋งŽ์•„ ๋‚ด๊ฐ€ ์ง์ ‘ ํ•˜๋‚˜์”ฉ ํŽ˜์ด์ง€๋ฅผ ํ™•์ธํ•˜๋ฉด์„œ ์ „๋ถ€ ๊ฒ€ํ† ํ•˜๊ณ  ์ˆ˜์ •ํ–ˆ๋‹ค. ์š”์†Œ ์ •๋ฆฌ๊ฐ€ ๋งˆ๋ฌด๋ฆฌ๋œ ๋’ค์—๋Š” ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฉ”์ธ ํŽ˜์ด์ง€์™€ ๊ด€๋ จ๋œ ์ด 25๊ฐœ์˜ ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ๊ตฌํ˜„์„ ์™„๋ฃŒํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.
๊ฐ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋งˆ๋‹ค ํ•˜๋‚˜์˜ ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ์ด๋ฆ„์„ ๊ตฌ๊ธ€ ์Šคํ”„๋ ˆ๋“œ์‹œํŠธ์— ์ •๋ฆฌ๋œ ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ID์™€ ๋™์ผํ•˜๊ฒŒ ๋งž์ถ”์—ˆ๋‹ค. ๋˜ํ•œ, ํ…Œ์ŠคํŠธ๊ฐ€ pass๋œ ๊ฒฝ์šฐ ํ•ด๋‹น ํ•จ์ˆ˜ ์ด๋ฆ„์„ ์ž๋™์œผ๋กœ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก inspect ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ์•ˆ์„ ์ œ์•ˆํ–ˆ๊ณ , ๋ชจ๋‘๊ฐ€ ๊ทธ ๋ฐฉ์‹์— ๋งŒ์กฑํ•˜์—ฌ ์ •์‹์œผ๋กœ ์ฑ„ํƒํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ž๋™ํ™” ๊ฒฐ๊ณผ ๋กœ๊ทธ๋ฅผ ํ™•์ธํ•˜๋ฉด์„œ, ์–ด๋–ค ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๊ฐ€ ํ†ต๊ณผ(pass)๋˜์—ˆ๋Š”์ง€ ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ID ๊ธฐ์ค€์œผ๋กœ ์ง๊ด€์ ์œผ๋กœ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์–ด ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ ๋ถ„์„์ด ํ›จ์”ฌ ์ˆ˜์›”ํ•ด์งˆ ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€๋œ๋‹ค.
์Šฌ๋ผ์ด๋” ์ž๋™ํ™”์—์„œ๋Š” ๊ฝค ๋งŽ์€ ์‹œ๊ฐ„์„ ํ—ˆ๋น„ํ–ˆ์ง€๋งŒ, ๊ฒฐ๊ตญ ActionChains๋ฅผ ํ™œ์šฉํ•ด ์›ํ•˜๋Š” ๋™์ž‘์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์„ฑ๊ณตํ–ˆ๋‹ค. ์ฒ˜์Œ์—๋Š” ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์•„ ๋‹นํ™ฉํ–ˆ์ง€๋งŒ, ์ง์ ‘ ํ•˜๋‚˜์”ฉ ํ…Œ์ŠคํŠธํ•ด๋ณด๋ฉฐ ‘๋‚ด๊ฐ€ ์–ด๋–ค ํ–‰๋™์„ ํ–ˆ์„ ๋•Œ ์š”์†Œ์˜ ์†์„ฑ๊ฐ’์ด ์–ด๋–ป๊ฒŒ ๋ฐ”๋€Œ๋Š”์ง€’, ‘๊ทธ ๋ณ€๊ฒฝ๋œ ์†์„ฑ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณตํ–ˆ๋Š”์ง€๋ฅผ ์–ด๋–ป๊ฒŒ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ์„์ง€’, ‘ํ•ด๋‹น ์š”์†Œ์˜ ์†์„ฑ๊ฐ’ ์ค‘ ์–ด๋–ค ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ํ•˜๋ฉด ๋” ์ •ํ™•ํ•˜๊ณ  ์•ˆ์ •์ ์œผ๋กœ ์š”์†Œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์„์ง€’ ๊ฐ™์€ ๋ถ€๋ถ„๋“ค์„ ํ•˜๋‚˜์”ฉ ์ฒด๋“ํ•ด๋‚˜๊ฐ€๊ณ  ์žˆ๋‹ค๋Š” ๋А๋‚Œ์ด ๋“ค์—ˆ๋‹ค. ์˜ˆ์ „์—๋Š” ๋‹จ์ˆœํžˆ ๋ณด์ด๋Š” UI๋งŒ ๋”ฐ๋ผ๊ฐ”๋‹ค๋ฉด, ์ด์ œ๋Š” ์‹ค์ œ ์š”์†Œ์˜ ๊ตฌ์กฐ์™€ ๋ณ€ํ™”๋ฅผ ์ง์ ‘ ํŒŒ์•…ํ•˜๊ณ  ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ˆ˜์ค€์œผ๋กœ ์„ฑ์žฅํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๊ฒŒ ๋А๊ปด์ ธ์„œ ๋ฟŒ๋“ฏํ–ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์˜ค๋Š˜ Jenkins ๊ด€๋ จํ•ด์„œ ์ค‘์š”ํ•œ ๊ณต์ง€๊ฐ€ ์ „๋‹ฌ๋๋‹ค. ๋‹ค๋ฅธ ํŒ€์˜ ํ•œ ๋ถ„์ด GitLab ๋ ˆํฌ์ง€ํ† ๋ฆฌ์™€ Jenkins๋ฅผ SSH ๋ฐฉ์‹์œผ๋กœ ์—ฐ๋™ํ•˜๋Š” ์‹œ๋„๋ฅผ ํ•˜์…จ๋˜ ๋ชจ์–‘์ธ๋ฐ, ์ด ๋ฐฉ์‹์€ GitLab์˜ ๊ณต์œ  ๋Ÿฌ๋„ˆ๊ฐ€ ์ž๋™์œผ๋กœ ์ž‘๋™ํ•˜๋ฉด์„œ Merge ์‹œ ์ถฉ๋Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค. ์ด์— ๋”ฐ๋ผ ์ฝ”์น˜๋‹˜๊ป˜์„œ ์„ธ ๊ฐ€์ง€ ๋Œ€์•ˆ ๋ฐฉ๋ฒ•์„ ์•ˆ๋‚ดํ•ด์ฃผ์…จ๋‹ค.
 

  • Ngrok์„ ์ด์šฉํ•œ ๋กœ์ปฌ ํ„ฐ๋„๋ง ๋ฐฉ์‹
    → ์ด๊ฑด ๋ฐ”๋กœ ๋‚ด๊ฐ€ ๋ฉฐ์น  ์ „์— ์ง์ ‘ ์‹œ๋„ํ•ด์„œ ์„ฑ๊ณตํ–ˆ๋˜ ๋ฐฉ๋ฒ•! ๋‹ค๋งŒ ์ด ๋ฐฉ์‹์€ Ngrok์˜ ํŠน์„ฑ์ƒ ์ฃผ์†Œ๊ฐ€ ๋งค๋ฒˆ ๋ฐ”๋€Œ๊ธฐ ๋•Œ๋ฌธ์—, ์ง€์†์ ์ธ ์‚ฌ์šฉ์—๋Š” ๋‹ค์†Œ ๋ถˆ์•ˆ์ •ํ•œ ๋ฉด์ด ์žˆ๋‹ค.
  • ๊ณต์œ  ์„œ๋ฒ„๋ฅผ ์ด์šฉํ•œ CI ๊ตฌ์ถ• (์ถ”์ฒœ)
    → ๊ฐ ํŒ€๋ณ„๋กœ ๊ณต์œ  ์„œ๋ฒ„๊ฐ€ ์ œ๊ณต๋  ์˜ˆ์ •์ด๋ฉฐ, ์„ธํŒ…์ด ์™„๋ฃŒ๋˜๋Š” ๋Œ€๋กœ ํŒ€๋ณ„ ์•ˆ๋‚ด๊ฐ€ ์žˆ์„ ์˜ˆ์ •์ด๋ผ๊ณ  ํ•œ๋‹ค. ์ด ๋ฐฉ๋ฒ•์ด ๊ฐ€์žฅ ์•ˆ์ •์ ์ด๋ผ ์ถ”ํ›„ ๋‹ค์‹œ ์‹œ๋„ํ•ด๋ด์•ผ ํ•  ๊ฒƒ ๊ฐ™๋‹ค.
  • GitLab ๊ณต์œ  ๋Ÿฌ๋„ˆ๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•œ ๋’ค SSH ๋ฐฉ์‹์œผ๋กœ ์—ฐ๋™
    → ๊ณต์œ  ๋Ÿฌ๋„ˆ๊ฐ€ ์ž๋™์œผ๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š๋„๋ก ์„ค์ •ํ•œ ํ›„, SSH ๋ฐฉ์‹์œผ๋กœ Jenkins์™€ GitLab์„ ์—ฐ๊ฒฐํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

 

์˜คํ”ผ์Šค์•„์›Œ ์‹œ๊ฐ„์— ์ฝ”์น˜๋‹˜๊ป˜์„œ ์‹ค๋ฌด์—์„œ ์š”์†Œ๋ฅผ ์ฐพ๋Š” ๋ฐฉ์‹์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด์ฃผ์…จ๋‹ค. ์‹ค์ œ๋กœ๋Š” ์ „์ฒด ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋จผ์ € ๋ถˆ๋Ÿฌ์˜จ ๋’ค, ๊ทธ ์•ˆ์—์„œ ํ•„์š”ํ•œ ์š”์†Œ์— ์ ‘๊ทผํ•˜๋Š” ์‹์œผ๋กœ ์ž‘์—…ํ•œ๋‹ค๊ณ  ํ•˜์…จ๊ณ , ์ด๋Ÿฐ ๋ฐฉ์‹์ด ๋” ์•ˆ์ •์ ์ด๊ณ  ์œ ์ง€๋ณด์ˆ˜์—๋„ ์œ ๋ฆฌํ•˜๋‹ค๊ณ  ํ•˜์…จ๋‹ค.
๋˜ํ•œ ์‹ค๋ฌด์—์„œ๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•  ๋•Œ, ‘ํ•ด๋‹น ํŽ˜์ด์ง€์— <h1> ํƒœ๊ทธ๊ฐ€ ๋ช‡ ๊ฐœ ์žˆ๋Š”์ง€’์ฒ˜๋Ÿผ ๋‹จ์ˆœํ•œ ๊ธฐ์ค€์„ ํ™œ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋„ ๋งŽ๋‹ค๋Š” ํŒ๋„ ์ฃผ์…จ๋‹ค. ์ด์œ ๋Š” ๊ฐ„๋‹จํ•˜๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๋ฉด์„œ <h1> ํƒœ๊ทธ๊ฐ€ ํ•˜๋‚˜ ๋” ์ƒ๊ธฐ๋ฉด, ํ…Œ์ŠคํŠธ์—์„œ๋„ ๊ทธ ๋ณ€ํ™”๋ฅผ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, “์•„, ๋ญ”๊ฐ€ ์ถ”๊ฐ€๋๊ตฌ๋‚˜” ํ•˜๊ณ  ๋น ๋ฅด๊ฒŒ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์ด์ฒ˜๋Ÿผ ํŽ˜์ด์ง€ ๊ตฌ์กฐ ๋ณ€๊ฒฝ์— ์œ ์—ฐํ•˜๊ฒŒ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ๊ณ , ์„ธ๋ถ€ ์š”์†Œ๋ฅผ ์ผ์ผ์ด ์ง€์ •ํ•˜์ง€ ์•Š์•„๋„ ๋ณ€ํ™” ๊ฐ์ง€๊ฐ€ ๊ฐ€๋Šฅํ•œ ๋ฐฉ์‹์ด ์˜คํžˆ๋ ค ์‹ค๋ฌด์—์„œ๋Š” ๋” ์‹ค์šฉ์ ์ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด ์ธ์ƒ ๊นŠ์—ˆ๋‹ค.


๐Ÿ“š 3/29 - ๊ฐœ์ธ ๊ณต๋ถ€ (๊ฐœ์ธ ํ”ผ๋“œ ํƒญ ์ž๋™ํ™” ํ…Œ์ŠคํŠธ ๊ตฌํ˜„ ์‹œ์ž‘)

 
์˜ค๋Š˜์€ ํŒ€์› ์„ธ ๋ถ„์ด ๊ฐ์ž ๋งก์€ ํ™ˆ ํƒญ, ํŒ€ ํ”ผ๋“œ ํƒญ, ํžˆ์Šคํ† ๋ฆฌ ํƒญ์„ ์ œ์™ธํ•˜๊ณ , ์•„์ง ์•„๋ฌด๋„ ์ž‘์—…ํ•˜๊ณ  ์žˆ์ง€ ์•Š์€ ๊ฐœ์ธ ํ”ผ๋“œ ํƒญ์˜ ์ž๋™ํ™” ํ…Œ์ŠคํŠธ๋ฅผ ๋งก์•„ ์ง„ํ–‰ํ–ˆ๋‹ค. ์„œ๋กœ ๋‹ค๋ฅธ ์žฅ์†Œ์—์„œ ์ž‘์—… ์ค‘์ด๊ธฐ ๋•Œ๋ฌธ์—, ๋™์ผํ•œ ์˜์—ญ์„ ๋™์‹œ์— ์ž‘์—…ํ•˜๋ฉด ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด ๊ฐ€๋Šฅํ•œ ๊ฒน์น˜์ง€ ์•Š๋Š” ์˜์—ญ์„ ๋งก๋Š” ๊ฒŒ ์•ˆ์ „ํ•˜๋‹ค๊ณ  ํŒ๋‹จํ–ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐœ์ธ ํ”ผ๋“œ ํƒญ์„ ๋งก์•„ ์˜ค๋Š˜ ํ•˜๋ฃจ ์•ฝ 10์‹œ๊ฐ„์„ ์ง‘์ค‘ ํˆฌ์žํ–ˆ๋‹ค.
์ž๋™ํ™” ํ…Œ์ŠคํŠธ๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ ์ „, ๊ธฐ์กด ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋“ค์„ ํ•จ๊ป˜ ๊ฒ€ํ† ํ•˜๋ฉด์„œ, ํ•˜๋‚˜์˜ ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ์•ˆ์—์„œ ๋™์‹œ์— ๊ฒ€์ฆํ•˜๋Š” ๊ฒƒ์ด ํšจ๊ณผ์ ์ธ ์ผ€์ด์Šค๋“ค์„ ๋ฌถ์–ด ์žฌ๊ตฌ์„ฑํ–ˆ๋‹ค. ๊ทธ ๊ฒฐ๊ณผ, ๊ฐœ์ธ ํ”ผ๋“œ ํƒญ๊ณผ ๊ด€๋ จ๋œ ์ด 111๊ฐœ์˜ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ๋ถ„์„ํ•ด 17๊ฐœ์˜ ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜๋กœ ๋‚˜๋ˆ„์—ˆ๊ณ , ๊ฐ ๋ฌถ์Œ์—๋Š” ๋ณ„๋„์˜ ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ID๋ฅผ ๋ถ€์—ฌํ•ด ์ฒด๊ณ„์ ์œผ๋กœ ๊ด€๋ฆฌํ–ˆ๋‹ค.
 
๊ทธ๋Ÿฐ๋ฐ ๋กœ๊ทธ์ธ/ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€์— ๋น„ํ•ด ๊ฐœ์ธ ํ”ผ๋“œ ํƒญ์˜ ์š”์†Œ๋ฅผ ์ฐพ๋Š” ๊ฒŒ ์ƒ๋‹นํžˆ ๊นŒ๋‹ค๋กœ์› ๋‹ค.

  • visible ๋˜๋Š” clickable ์ƒํƒœ๊ฐ€ ๋  ๋•Œ๊นŒ์ง€ ๋ช…์‹œ์ ์œผ๋กœ ๊ธฐ๋‹ค๋ ค์•ผ ํ•˜๋Š” ์š”์†Œ๋“ค์ด ์žˆ์—ˆ๊ณ ,
  • scroll๋กœ ํ™”๋ฉด์„ ๋‚ด๋ ค์•ผ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์š”์†Œ๋“ค๋„ ์กด์žฌํ–ˆ๋‹ค.

 
์ด๋กœ ์ธํ•ด ์š”์†Œ๋ฅผ ์•ˆ์ •์ ์œผ๋กœ ํƒ์ƒ‰ํ•˜๊ณ  ์‹๋ณ„ํ•˜๋Š” ๋ฐ์—๋งŒ ์ „์ฒด ์ž‘์—… ์‹œ๊ฐ„์˜ ์ ˆ๋ฐ˜ ์ด์ƒ์ด ์†Œ์š”๋๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ ์˜ค๋Š˜ ์ฐพ์€ ์š”์†Œ๋“ค๋„ ์ „์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ, ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋„์ค‘ ๊ทธ๋•Œ๊ทธ๋•Œ ํ•„์š”ํ•œ ์š”์†Œ๋งŒ ํƒ์ƒ‰ํ•œ ์ˆ˜์ค€์ด์—ˆ๋‹ค. ๊ฒฐ๊ตญ ์˜ค๋Š˜ ํ•˜๋ฃจ ๋™์•ˆ์€ ์ด 17๊ฐœ์˜ ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ์ค‘ ๋‹จ 5๊ฐœ๋งŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์—ˆ์ง€๋งŒ, ๊ทธ ๊ณผ์ •์—์„œ ๋А๋‚€ ์ ๋„ ๋งŽ์•˜๋‹ค. ํŠนํžˆ ‘์š”์†Œ ์ฐพ๊ธฐ’์— ๋Œ€ํ•œ ๊ฐ๊ฐ์ด ํ™•์‹คํžˆ ํ–ฅ์ƒ๋˜์—ˆ๋‹ค๋Š” ์ ์—์„œ ๊ธฐ์ˆ ์ ์ธ ์„ฑ์žฅ์€ ๋ถ„๋ช…ํ•œ ํ•˜๋ฃจ์˜€๋‹ค. ์†๋„๋Š” ๊ธฐ๋Œ€๋งŒํผ ๋น ๋ฅด์ง€ ์•Š์•˜์ง€๋งŒ, ์™„์„ฑ๋„๋ฅผ ์œ„ํ•œ ๋ฐœํŒ์„ ํŠผํŠผํžˆ ๋‹ค์กŒ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.
 
๐Ÿ”ฅ ์š”์†Œ ์ฐพ๊ธฐ Tip

๋”๋ณด๊ธฐ

• /.. : ํ•ด๋‹น ์š”์†Œ์˜ ๋ถ€๋ชจ
• /preceding-sibling : ํ•ด๋‹น ์š”์†Œ์˜ ๊ฐ™์€ ๋ถ€๋ชจ ์•„๋ž˜, ์•ž์— ์žˆ๋Š” ํ˜•์ œ
• /following-sibling : ํ•ด๋‹น ์š”์†Œ์˜ ๊ฐ™์€ ๋ถ€๋ชจ ์•„๋ž˜, ๋’ค์— ์žˆ๋Š” ํ˜•์ œ
• <svg>๋Š” HTML์ด ์•„๋‹ˆ๋ผ SVG ๋„ค์ž„์ŠคํŽ˜์ด์Šค(XML ๊ธฐ๋ฐ˜)

 > //svg ๋˜๋Š” //preceding-sibling::svg ์ฒ˜๋Ÿผ ์‚ฌ์šฉ์‹œ ์‹คํŒจ ํ™•๋ฅ  ๋†’์Œ
 > *[name()='svg'] ์ฒ˜๋Ÿผ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ๋ฌด์‹œํ•˜๊ณ  svg ํƒœ๊ทธ๋กœ ์ •ํ™•ํ•˜๊ฒŒ ์ธ์‹

 > ๋„ค์ž„์ŠคํŽ˜์ด์Šค : HTML์ด๋‚˜ XML์—์„œ ๊ฐ™์€ ์ด๋ฆ„์˜ ํƒœ๊ทธ๊ฐ€ ์ถฉ๋Œํ•˜์ง€ ์•Š๋„๋ก ๊ตฌ๋ถ„ํ•ด์ฃผ๋Š” ๊ฒƒ

 



๐Ÿ“… 3/30 - ํŒ€ ๋ชจ์ž„ (์ด์ „ ์ž‘์—… ์ด์–ด ๊ฐ์ž ์ž๋™ํ™” ์ฝ”๋“œ ๊ฐœ๋ฐœ)

 

์˜ค๋Š˜์€ ํ‰์ผ ์ž‘์—…๋งŒ์œผ๋กœ๋Š” ์‹œ๊ฐ„์ด ๋ถ€์กฑํ•  ๊ฒƒ ๊ฐ™์•„, ์ฃผ๋ง์ž„์—๋„ ํŒ€์› ๋ชจ๋‘๊ฐ€ ์‹œ๊ฐ„์„ ๋‚ด์–ด ํ•จ๊ป˜ ๋ชจ์˜€๋‹ค. ๊ฐ์ž ๋งก์€ ํŽ˜์ด์ง€์˜ ๊ธฐ๋Šฅ ๊ตฌํ˜„์„ ๊ณ„์† ์ด์–ด๊ฐ”๊ณ , ๋‚˜๋Š” ์—ฌ์ „ํžˆ ๊ฐœ์ธ ํ”ผ๋“œ ํƒญ ์ž๋™ํ™” ํ•จ์ˆ˜ ๊ตฌํ˜„์— ์ง‘์ค‘์ ์œผ๋กœ ์‹œ๊ฐ„์„ ํˆฌ์žํ–ˆ๋‹ค.
์ž‘์—…์ด ์ƒ๊ฐ๋ณด๋‹ค ํšจ์œจ์ ์œผ๋กœ ์ง„ํ–‰๋œ ์ด์œ  ์ค‘ ํ•˜๋‚˜๋Š”, ํŒ€์›๋“ค์ด ๊ฐ์ž ๋ฏธ๋ฆฌ ์ž˜ ์ •๋ฆฌํ•ด๋‘” ์š”์†Œ๋“ค ๋•๋ถ„์ด์—ˆ๋‹ค. ๋‚˜ ์—ญ์‹œ ์‚ฌ์ „์— ์ •๋ฆฌํ•ด๋‘” ์š”์†Œ๋“ค์„ ํŒ€์›๋“ค๊ณผ ๊ณต์œ ํ–ˆ๊ณ , ์„œ๋กœ์˜ ์ž‘์—…์— ์‹ค์งˆ์ ์ธ ๋„์›€์ด ๋˜์—ˆ๋‹ค๋Š” ์ ์ด ์ธ์ƒ ๊นŠ์—ˆ๋‹ค. ๊ฐ์ž ๋งก์€ ์˜์—ญ์„ ๋ฌธ์„œํ™”ํ•˜๊ณ  ๊ณต์œ ํ•˜๋ฉฐ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด ์šฐ๋ฆฌ ํŒ€์—๊ฒŒ ์ž˜ ๋งž์•˜๋˜ ๊ฒƒ ๊ฐ™๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ ํŽ˜์ด์ง€ ๊ฐ„ ๊ธฐ๋Šฅ ๊ตฌ์กฐ๋„ ์œ ์‚ฌํ•ด์„œ, ํ•œ ๋ฒˆ ์ œ๋Œ€๋กœ ๋งŒ๋“  ์š”์†Œ ์ •์˜๋‚˜ ํ•จ์ˆ˜๋Š” ์—ฌ๋Ÿฌ ํ…Œ์ŠคํŠธ์—์„œ ๋ฐ˜๋ณต์ ์œผ๋กœ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ตฌ์กฐ ๋•๋ถ„์— ์ „์ฒด ์ž‘์—… ์†๋„๋„ ์ƒ๊ฐ๋ณด๋‹ค ๋” ๋น ๋ฅด๊ฒŒ ์ง„ํ–‰๋  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์˜ˆ๊ฐ์ด ๋“ ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์˜ค๋Š˜ ์ƒˆ๋กญ๊ฒŒ ์•Œ๊ฒŒ ๋œ ํŒ ํ•˜๋‚˜! CLASS NAME ์…€๋ ‰ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ, ํด๋ž˜์Šค๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ธ ์š”์†Œ๋Š” ์ •ํ™•ํ•˜๊ฒŒ ์„ ํƒ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค๋Š” ์ ์„ ๊ฒฝํ—˜ํ–ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ดํ›„์—๋Š” CSS selector๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ์ •ํ™•ํ•˜๊ณ  ์œ ์—ฐํ•˜๋‹ค๋Š” ๊ฑธ ์ƒˆ๋กญ๊ฒŒ ๋ฐฐ์› ๋‹ค.
ํ˜„์žฌ ๋ชฉํ‘œ๋Š” ํ™”์š”์ผ๊นŒ์ง€ ์ฝ”๋“œ ๊ตฌํ˜„์„ ๋ชจ๋‘ ๋งˆ๋ฌด๋ฆฌํ•˜๊ณ , Jenkins ์—ฐ๋™๊นŒ์ง€ ์™„๋ฃŒํ•˜๋Š” ๊ฒƒ. ํ•˜๋ฃจ ๋งŒ์— ๊ฐ€๋Šฅํ•˜๊ฒ ์ง€…?


๐Ÿ“Œ 3/31 - 7์ผ์ฐจ ํšŒ๊ณ  (๊ฐœ์ธ ํ”ผ๋“œ ์ž๋™ํ™” ํ…Œ์ŠคํŠธ ๊ตฌํ˜„ ์™„๋ฃŒ)

 

์—˜๋ฆฌ์Šค Lab์— ๋„์ฐฉํ•˜์ž๋งˆ์ž Jenkins ๊ด€๋ จ ๊ณต์ง€๊ฐ€ ๋„์ฐฉํ–ˆ๋‹ค. ๋†€๋ž๊ฒŒ๋„ ์—˜๋ฆฌ์Šค ์ธก์—์„œ ๊ณต์œ  ์„œ๋ฒ„๋ฅผ ์ œ๊ณตํ•ด์ค€๋‹ค๋Š” ์†Œ์‹!
๋•๋ถ„์— ๋” ์ด์ƒ ๋กœ์ปฌ์—์„œ ํ„ฐ๋„๋ง์„ ์œ„ํ•ด ngrok์„ ์“ฐ์ง€ ์•Š์•„๋„ ๋  ๊ฒƒ ๊ฐ™๋‹ค. ๊ทธ๋™์•ˆ ngrok์„ ์“ธ ๋•Œ๋งˆ๋‹ค ์ฃผ์†Œ๊ฐ€ ๊ณ„์† ๋ฐ”๋€Œ์–ด์„œ ๋ฒˆ๊ฑฐ๋กœ์› ๋Š”๋ฐ, ๊ณต์œ  ์„œ๋ฒ„ ๋•๋ถ„์— ์ด ๋ฌธ์ œ๋„ ์–ด๋А ์ •๋„ ํ•ด๊ฒฐ ๊ฐ€๋Šฅํ•  ๊ฒƒ ๊ฐ™๋‹ค. ์ด์ œ Jenkins๋ฅผ ์ข€ ๋” ์•ˆ์ •์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๋“ฏ!
 

๊ณต์œ  ์„œ๋ฒ„๋ฅผ ์ œ๊ณต๋ฐ›์ž๋งˆ์ž ๋ช‡ ๊ฐ€์ง€ ์˜๋ฌธ์ด ๋ฐ”๋กœ ๋– ์˜ฌ๋ž๋‹ค.

  • ๋‚ด๊ฐ€ ๋งŒ๋“  Docker ์ด๋ฏธ์ง€๋ฅผ ๊ทธ๋Œ€๋กœ ์จ๋„ ๋˜๋Š” ๊ฑธ๊นŒ?
  • ๊ณ ์ • IP๋ผ์„œ ์™ธ๋ถ€ ์ ‘์†์ด ๋” ํŽธํ•ด์ง„ ๊ฑด๊ฐ€?
  • ๊ทธ๋ ‡๋‹ค๋ฉด ๊ทธ๋ƒฅ ๋กœ์ปฌ์—์„œ ํ•˜๋˜ ๋ฐฉ์‹ ๊ทธ๋Œ€๋กœ ์ง„ํ–‰ํ•˜๋ฉด ๋˜๋Š” ๊ฑด ์•„๋‹๊นŒ?

๊ถ๊ธˆํ•œ ๊ฑธ ๋ฐ”๋กœ GPT์—๊ฒŒ ๋ฌผ์–ด๋ดค๋Š”๋ฐ, ์ƒ๊ฐ๋ณด๋‹ค ๋†€๋ž๊ฒŒ๋„(?) ๋‚ด๊ฐ€ ๋– ์˜ฌ๋ฆฐ ์˜๋ฌธ์ด ์ „๋ถ€ ๋งž๋Š” ๋ง์ด์—ˆ๋‹ค. ๊ฒฐ๋ก ์ ์œผ๋กœ๋Š”, ํ™˜๊ฒฝ๋งŒ ๋ฐ”๋€Œ์—ˆ์„ ๋ฟ, ๊ธฐ์กด์— ํ•˜๋˜ ๋ฐฉ์‹ ๊ทธ๋Œ€๋กœ ์ง„ํ–‰ํ•˜๋ฉด ๋œ๋‹ค. ์„œ๋ฒ„ ์œ„์น˜๋งŒ ๋‹ฌ๋ผ์กŒ์„ ๋ฟ, Docker๋„ Jenkins๋„ ์„ค์ • ๋ฐฉ์‹๋„ ์ „๋ถ€ ๋™์ผํ•˜๊ณ , ์˜คํžˆ๋ ค ๊ณ ์ • IP ๋•๋ถ„์— ์™ธ๋ถ€ ์—ฐ๋™์ด ๋” ์•ˆ์ •์ ์ด๊ณ  ์พŒ์ ํ•ด์ง„ ๋А๋‚Œ์ด๋‹ค.

๋“œ๋””์–ด.. ๊ฐœ์ธ ํ”ผ๋“œ ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ๊ตฌํ˜„ ์™„๋ฃŒ! ์˜ค๋Š˜์€ ํŒ€์›๋“ค ๊ฐ์ž ๋งก์€ ํŽ˜์ด์ง€ ๊ตฌํ˜„์— ์ง‘์ค‘ํ•˜๋А๋ผ, ๋ญ”๊ฐ€ ์ƒˆ๋กญ๊ณ  ์ธ์ƒ ๊นŠ์€ ์ธ์‚ฌ์ดํŠธ๋ฅผ ์–ป์—ˆ๋‹ค๊ธฐ๋ณด๋‹ค๋Š”, ์ „์ฒด ์ž‘์—…์„ ์ •๋ฆฌํ•˜๊ณ  ๋””ํ…Œ์ผ์„ ๋งˆ๋ฌด๋ฆฌํ•˜๋Š” ๋ฐ ์ดˆ์ ์ด ๋งž์ถฐ์ง„ ํ•˜๋ฃจ์˜€๋‹ค.
 
๊ทธ๋‚˜๋งˆ ๊ธฐ์–ต์— ๋‚จ๋Š” ๊ฑด...

  • fixture์— ๋‹ค์–‘ํ•œ ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•ด๋ณด๋‹ˆ ํ…Œ์ŠคํŠธ ์†๋„๊ฐ€ ํ™• ์ค„์—ˆ๋‹ค.
  • implicitly_wait์„ ์„ค์ •ํ•ด๋‘๋‹ˆ ์š”์†Œ๊ฐ€ ๋ฐ”๋กœ ์•ˆ ๋ณด์—ฌ๋„ n์ดˆ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์ค˜์„œ, time.sleep์ด๋ž‘ ๋ณ‘ํ–‰ํ•˜๋‹ˆ๊นŒ ์ž๊พธ ๋ฐœ์ƒํ•˜๋˜ timeout์ด ์‹น ์‚ฌ๋ผ์กŒ๋‹ค.

์•„์ฃผ ์ž‘์€ ์„ค์ • ํ•˜๋‚˜๊ฐ€ ์ „์ฒด ์•ˆ์ •์„ฑ์— ๊ฝค ํฐ ์ฐจ์ด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฑธ ๋‹ค์‹œ ๋А๊ผˆ๋‹ค.
 
๋‚จ์€ ๊ธฐ๊ฐ„ ๋™์•ˆ ๋‚ด๊ฐ€ ํ•  ์ผ ์ •๋ฆฌ

  • ํŒ€์›๋ถ„๋“ค ์ฝ”๋“œ ํ•จ๊ป˜ ๋ฆฌ๋ทฐํ•˜๊ธฐ
  • Jenkins ์—ฐ๋™ ์ง‘์ค‘์ ์œผ๋กœ ์‹œ๋„ํ•ด๋ณด๊ธฐ
  • ๊ฐ assert์— log ์ถœ๋ ฅ ๋„ฃ๊ธฐ (๋‹ค๋งŒ ์ „์ฒด ํ…Œ์ŠคํŠธ ์„ฑ๊ณต์ธ์ง€, assert ํ•˜๋‚˜ํ•˜๋‚˜์˜ ์„ฑ๊ณต์ธ์ง€๋Š” ๊ตฌ๋ถ„ํ•ด์„œ ์ ์„ ๊ฒƒ)
  • ์•„์ด์ฝ˜ ๊ธ€๋จธ๋ฆฌ ๊ธฐํ˜ธ์— ์žˆ๋Š” [ ] ๊ฐ™์€ ๋Œ€๊ด„ํ˜ธ ์ œ๊ฑฐ
  • ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ํด๋” ์ •๋ฆฌ: config, testdata
  • ๋ถˆํ•„์š”ํ•œ ํ•จ์ˆ˜ ์ œ๊ฑฐ: getVisibilityElement, isContainAllField (in myFeed class)
  • ์˜๋ฏธ ์—†๋Š” ์ฃผ์„ ์ œ๊ฑฐ

 
๊ฒฐ๋ก ์ ์œผ๋กœ๋Š”, ์ง€๊ธˆ ๋‚ด ์—ญํ• ์€ ์ฝ”๋“œ ์ •๋ฆฌ ๋งˆ๋ฌด๋ฆฌ + Jenkins ์—ฐ๋™ ์‹œ๋„!
์‹œ๊ฐ„์ด ์ข€ ๋‚จ๋Š”๋‹ค๋ฉด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง์ด๋‚˜ ๊ฐ•์˜์—์„œ ๋ฐฐ์šด @pytest.mark.parametrize ๊ฐ™์€ ๊ธฐ๋Šฅ๋„ ํ•˜๋‚˜์”ฉ ์ ์šฉํ•ด๋ณด๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.


๐Ÿ“Œ 4/1 - 8์ผ์ฐจ ํšŒ๊ณ  (Jenkins ์—ฐ๋™ ์„ฑ๊ณต / ํ…Œ์ŠคํŠธ ๋กœ๊ทธ ์ถ”๊ฐ€ ๋ฐ ๋ฆฌํŒฉํ† ๋ง)

 

๋‚˜๋Š” ๋‚ด๊ฐ€ ๋งก์€ ํŽ˜์ด์ง€๋“ค์˜ ์ž๋™ํ™” ์ฝ”๋“œ ๊ตฌํ˜„์„ ๋ชจ๋‘ ๋งˆ์นœ ์ƒํƒœ์˜€๊ธฐ ๋•Œ๋ฌธ์—, ์˜ค๋Š˜์€ ๋‹ค๋ฅธ ํŒ€์›๋ถ„๋“ค์ด ๊ฐ์ž ๋งก์€ ํŽ˜์ด์ง€ ๊ตฌํ˜„์„ ๊ณ„์† ์ง„ํ–‰ํ•˜๋Š” ๋™์•ˆ ๋ณธ๊ฒฉ์ ์œผ๋กœ Jenkins์™€ GitLab ์—ฐ๋™ ์ž‘์—…์— ๋„์ „ํ–ˆ๋‹ค.
๋ณธ๊ฒฉ์ ์ธ ์—ฐ๋™ ์ค€๋น„๋ฅผ ์œ„ํ•ด, ์ „๋‚  ์ฝ”์น˜๋‹˜๊ป˜ ๋‚ด๊ฐ€ ์‹œ๋„ํ•˜๋ ค๋Š” ๋ฐฉ์‹์— ๋Œ€ํ•ด ๋จผ์ € ์—ฌ์ญค๋ดค๋‹ค. ์ฝ”์น˜๋‹˜๊ป˜์„œ๋Š” ์—˜๋ฆฌ์Šค ์ธก์œผ๋กœ๋ถ€ํ„ฐ hostname, user, password, public IP, ๊ทธ๋ฆฌ๊ณ  ์ ‘์† ๋ฐฉ๋ฒ•๊นŒ์ง€๋งŒ ์•ˆ๋‚ด๋œ ๊ฒƒ ๊ฐ™๋‹ค๊ณ  ํ™•์ธํ•˜์‹  ํ›„, ํฌํŠธ ์„ค์ •๋„ ํ•จ๊ป˜ ์ฒดํฌํ•ด๋ณด๋Š” ๊ฒŒ ์ข‹๊ฒ ๋‹ค๊ณ  ์กฐ์–ธํ•ด์ฃผ์…จ๋‹ค. ์ด์— ๋”ฐ๋ผ ๋งค๋‹ˆ์ €๋ถ„๊ป˜ ํฌํŠธ ๊ด€๋ จ ๋ฌธ์˜๋ฅผ ๋“œ๋ ธ๊ณ , ๊ทธ์— ๋Œ€ํ•œ ๋‹ต๋ณ€์„ ๋ฐ›์•„ ํฌํŠธ ์ •๋ณด๊นŒ์ง€ ํฌํ•จํ•œ ์—ฐ๋™์— ํ•„์š”ํ•œ ๋ชจ๋“  ์ •๋ณด๋ฅผ ํ™•๋ณดํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.
 
ํฌํŠธ
 ~> ํ•˜๋‚˜์˜ ์ปดํ“จํ„ฐ(์„œ๋ฒ„) ์•ˆ์—์„œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ”„๋กœ๊ทธ๋žจ์ด ๋™์‹œ์— ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ๋Š” ‘๋ฌธ’ ์—ญํ•  (์ฆ‰, IP ์ฃผ์†Œ๋Š” ‘๊ฑด๋ฌผ ์ฃผ์†Œ’, ํฌํŠธ ๋ฒˆํ˜ธ๋Š” ‘๊ทธ ์ฃผ์†Œ ์•ˆ์˜ ๋ฌธ ๋ฒˆํ˜ธ’)
 ~> ํฌํŠธ๊ฐ€ "์—ด๋ ค ์žˆ๋‹ค'๋Š” ๊ฑด? ์„œ๋ฒ„์˜ ๋ฐฉํ™”๋ฒฝ(UFW, iptables ๋“ฑ) ํ˜น์€ ํด๋ผ์šฐ๋“œ ๋ณด์•ˆ ๊ทธ๋ฃน์ด ํ•ด๋‹น ํฌํŠธ๋กœ์˜ ์™ธ๋ถ€ ์ ‘์†์„ ํ—ˆ์šฉํ•ด์ค€ ์ƒํƒœ๋ผ๋Š” ๋œป

์„œ๋น„์Šค IP ์ฃผ์†Œ ํฌํŠธ ๋ฒˆํ˜ธ ์ „์ฒด ์ฃผ์†Œ
์›น ์„œ๋ฒ„ (Nginx) 211.175.242.65 80 http://211.175.242.65:80
Jenkins 211.175.242.65 8080 http://211.175.242.65:8080
DB (MySQL) 211.175.242.65 3306 211.175.242.65:3306

 ~> ๊ฐ™์€ ์„œ๋ฒ„์—์„œ ์—ฌ๋Ÿฌ ์„œ๋น„์Šค๊ฐ€ ๋™์ž‘ํ•  ๋•Œ, ์ด์ฒ˜๋Ÿผ ๊ฐ™์€ IP๋ฅผ ๊ฐ€์ง„ ์„œ๋ฒ„์—์„œ๋„ ํฌํŠธ๊ฐ€ ๋‹ค๋ฅด๋ฉด ์„œ๋กœ ๋‹ค๋ฅธ ์„œ๋น„์Šค์— ์ ‘์† ๊ฐ€๋Šฅ
 
๐Ÿ”ฅ ๋ณ€๊ฒฝ ์‚ฌํ•ญ

๋”๋ณด๊ธฐ

[ ๊ธฐ์กด ๋ฐฉ์‹ - Jenkins ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰ (in VS Code ํ„ฐ๋ฏธ๋„) ]

docker run -d -p 8080:8080 -p 50000:50000 --name {์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„} {์ด๋ฏธ์ง€ ์ด๋ฆ„}

 > ๊ธฐ์กด์—๋Š” ์ด๋ ‡๊ฒŒ ์‹คํ–‰ํ–ˆ๋Š”๋ฐ, ์ด ๋ฐฉ์‹์€ ๋กœ์ปฌ ํ™˜๊ฒฝ์—์„œ๋งŒ ๊ฐ€๋Šฅํ–ˆ๋˜ ๋ฐฉ์‹์ด๋‹ค.

 > ๊ธฐ์กด์—๋Š” ๋‚ด ์ปดํ“จํ„ฐ์—์„œ ์ง์ ‘ ์ ‘์†ํ•˜๋Š” ๊ตฌ์กฐ์˜€๊ธฐ ๋•Œ๋ฌธ์—, 8080:8080์ฒ˜๋Ÿผ ๋‚ด๋ถ€ ํฌํŠธ์™€ ์™ธ๋ถ€ ํฌํŠธ๋ฅผ ๋™์ผํ•˜๊ฒŒ ์—ฐ๊ฒฐํ•ด๋„ ๋ฌธ์ œ X

 

[ ๋ณ€๊ฒฝ๋œ ๋ฐฉ์‹ - Jenkins ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰ (in VS Code ํ„ฐ๋ฏธ๋„) ]

docker run -d -p {์™ธ๋ถ€ ํฌํŠธ}:{์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€ ํฌํŠธ} -p 50000:50000 --name {์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„} {์ด๋ฏธ์ง€ ์ด๋ฆ„}

 > ํ•˜์ง€๋งŒ ๊ณต์œ  ์„œ๋ฒ„ ํ™˜๊ฒฝ์—์„œ๋Š” ์„œ๋ฒ„ ์™ธ๋ถ€์—์„œ ์—ด๋ ค ์žˆ๋Š” ํฌํŠธ๊ฐ€ ์ •ํ•ด์ ธ ์žˆ๋‹ค.

 > 8080์€ Jenkins ๋‚ด๋ถ€์—์„œ ๊ณ ์ •๋œ ํฌํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€ ํฌํŠธ๋Š” ์ ˆ๋Œ€ ๋ฐ”๊พธ๋ฉด ์•ˆ ๋œ๋‹ค.

 > ๋ฐ”๊ฟ”์•ผ ํ•˜๋Š” ๊ฑด ์™ธ๋ถ€ ํฌํŠธ์ด๋ฉฐ, ์—ด๋ ค ์žˆ๋Š” ํฌํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”์ง€ ๊ผญ ํ™•์ธ์ด ํ•„์š”ํ•˜๋‹ค.

 


 
๐Ÿ”ฅ ์‹œ๋„ ๊ณผ์ •

๋”๋ณด๊ธฐ

[ ์ฐธ๊ณ ์‚ฌํ•ญ ]

์—˜๋ฆฌ์Šค์—์„œ ์ œ๊ณตํ•œ ์„œ๋ฒ„๋Š” Ubuntu ์„œ๋ฒ„์ด๋ฏ€๋กœ GUI ํ™˜๊ฒฝ ์ œ๊ณต X

 > ๋”ฐ๋ผ์„œ Docker๋Š” ํ„ฐ๋ฏธ๋„ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ์กฐ์ž‘

 

[ ๊ณต์œ  ์„œ๋ฒ„์— SSH๋กœ ์ ‘์† (in cmd) ]

ssh {user}@{Public IP}

 > ๊ณต์œ  ์„œ๋ฒ„์— ์›๊ฒฉ ์ ‘์†

 

[ ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰ ์‹œ๋„ ์ค‘, Docker ๋ฏธ์„ค์น˜๋กœ ์‹คํ–‰ ์‹คํŒจ ]

docker run -d -p 3000:8080 -p 50000 50000 team5:jenkins_custom

 > ํ•ด๋‹น ์„œ๋ฒ„์— Docker๊ฐ€ ์„ค์น˜๋˜์ง€ ์•Š์•„ ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰ ์‹คํŒจ

 

[ docker ์„ค์น˜ (in cmd) ]

sudo apt update

 > ๊ธฐ์กด ํŒจํ‚ค์ง€ ์—…๋ฐ์ดํŠธ

sudo apt install -y docker.io

 > Docker ์„ค์น˜

 

[ Dockerfile์ด ์žˆ๋Š” ํด๋” ์ „์ฒด๋ฅผ ์„œ๋ฒ„๋กœ ๋ณต์‚ฌ (in VS Code ํ„ฐ๋ฏธ๋„) ]
์œ„ Dockerfile์ด ๋‹ด๊ธด ํด๋”๋ฅผ VS Code๋กœ ์—ด๊ธฐ

scp -r . {user}@{Public IP}:{์„œ๋ฒ„์—์„œ ๋ณต์‚ฌ๋  ๊ฒฝ๋กœ}

 > ์ปค์Šคํ…€ Jenkins ์ด๋ฏธ์ง€ ์ƒ์„ฑ์„ ์œ„ํ•œ Dockerfile์ด ๋‹ด๊ธด ํด๋”๋ฅผ ์„œ๋ฒ„๋กœ ๋ณต์‚ฌ

 

[ ๋ณต์‚ฌํ•œ ํด๋”๋กœ ์ด๋™ ํ›„ ์ด๋ฏธ์ง€ ๋นŒ๋“œ (in cmd) ]

ssh{user}@{Public IP}

 > ๊ณต์œ  ์„œ๋ฒ„์— ์›๊ฒฉ ์ ‘์†

cd ~/jenkins-docker

 > ๋ณต์‚ฌํ•œ ํด๋”๋กœ ์ด๋™

ls

 > ํŒŒ์ผ์ด ์ •์ƒ์ ์œผ๋กœ ๋ณต์‚ฌ๋˜์—ˆ๋Š”์ง€ ํ™•์ธ

sudo docker build -t {์ด๋ฏธ์ง€ ์ด๋ฆ„} .

 > ๊ด€๋ฆฌ์ž ๊ถŒํ•œ์œผ๋กœ Dockerfile ๊ธฐ๋ฐ˜ ์ปค์Šคํ…€ ์ด๋ฏธ์ง€ ์ƒ์„ฑ

sudo docker images

 > ๊ด€๋ฆฌ์ž ๊ถŒํ•œ์œผ๋กœ Dockerfile ๊ธฐ๋ฐ˜ ์ปค์Šคํ…€ ์ด๋ฏธ์ง€ ์ƒ์„ฑ ํ™•์ธ

 

[ ์ƒ์„ฑ๋œ ์ด๋ฏธ์ง€๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰ (in cmd) ]

sudo docker run -d -p{์™ธ๋ถ€ ํฌํŠธ}:{์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€ ํฌํŠธ}-p 50000:50000 --name {์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„} {์ด๋ฏธ์ง€ ์ด๋ฆ„}

 > ๊ด€๋ฆฌ์ž ๊ถŒํ•œ์œผ๋กœ Jenkins์šฉ ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰ ํ›„, ์™ธ๋ถ€์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ๋กœ ๊ตฌ๋™

 

[ ์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ†ตํ•ด Jenkins ์ ‘์† ]

http://{Public IP}:{์™ธ๋ถ€ ํฌํŠธ}

 > ์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ†ตํ•ด Jenkins์— ์ ‘์†

 

[ Jenkins ์ดˆ๊ธฐ ๊ด€๋ฆฌ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ ํ™•์ธ (in cmd) ]

sudo docker exec {์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„} cat /var/jenkins_home/secrets/initialAdminPassword

 > ๊ด€๋ฆฌ์ž ๊ถŒํ•œ์œผ๋กœ ์ดˆ๊ธฐ ๋น„๋ฐ€๋ฒˆํ˜ธ ์ถœ๋ ฅ

 

[ ์—ฐ๋™ ์„ฑ๊ณตํ–ˆ์ง€๋งŒ, ๋ฌธ์ œ ๋ฐœ์ƒ ]

"No such file or directory: 'credentials.json" ์˜ค๋ฅ˜ ๋ฐœ์ƒ

 > ํ˜„์žฌ ํ”„๋กœ์ ํŠธ๋Š” credentials.json ํŒŒ์ผ ์•ˆ์— ์ €์žฅ๋œ id์™€ pw๋ฅผ ์ฝ์–ด์™€ ๋กœ๊ทธ์ธํ•˜๋Š” ๊ตฌ์กฐ

 > ์ด ํŒŒ์ผ์€ ๋ฏผ๊ฐํ•œ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— .gitignore์— ์ถ”๊ฐ€ํ•ด๋‘์—ˆ๊ณ , GitHub์—๋„ ์˜ฌ๋ผ๊ฐ€์ง€ ์•Š๋„๋ก ๊ด€๋ฆฌ

 > Jenkins์—์„œ ํ•ด๋‹น ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ๋Š” ์ด ํŒŒ์ผ์ด ์กด์žฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ํŒŒ์ผ์„ ์ฐพ์ง€ ๋ชปํ•œ๋‹ค๋Š” ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ

 > ์ด ๋ฌธ์ œ๋ฅผ ์ฝ”์น˜๋‹˜๊ป˜ ์งˆ๋ฌธํ•ด๋ณด๋‹ˆ, Jenkins ๋‚ด์˜ Credentials ๊ธฐ๋Šฅ์„ ํ†ตํ•ด ํ•ด๊ฒฐํ•  ๊ฒƒ์„ ์ถ”์ฒœ

 

[ ํŒŒ์ผ ๋“ฑ๋ก ์„ฑ๊ณตํ–ˆ์ง€๋งŒ, ๋ฌธ์ œ ๋ฐœ์ƒ ]

"cannot create credentials.json: Permission denied" ์˜ค๋ฅ˜ ๋ฐœ์ƒ

 > Secret file๋กœ credentials.json ํŒŒ์ผ์„ ๋“ฑ๋กํ–ˆ์„ ๋•Œ, ์ฒ˜์Œ์—” ์ž˜ ๋™์ž‘ํ–ˆ์ง€๋งŒ, ์–ด๋А ์ˆœ๊ฐ„๋ถ€ํ„ฐ ๊ถŒํ•œ ์˜ค๋ฅ˜๊ฐ€ ๊ณ„์† ๋ฐœ์ƒ

 > Secret text๋กœ ๋ฐ”๊ฟ”๋ณด๊ธฐ๋„ ํ–ˆ๊ณ , pipeline ์ฝ”๋“œ๋„ ์—ฌ๋Ÿฌ ๋ฒˆ ์ˆ˜์ •ํ•ด๋ดค์ง€๋งŒ ๊ฒฐ๊ตญ ๊ณ„์† ๊ฐ™์€ ๊ถŒํ•œ ์—๋Ÿฌ๋งŒ ๋ฐ˜๋ณต

 > ์•Œ๊ณ  ๋ณด๋‹ˆ Jenkins๊ฐ€ credentials ๋“ฑ๋ก ์‹œ, ์ปจํ…Œ์ด๋„ˆ์˜ ์›Œํฌ์ŠคํŽ˜์ด์Šค ๋‚ด job ๋””๋ ‰ํ† ๋ฆฌ์— ํ•ด๋‹น ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๋Š”๋ฐ,
     ์ฒ˜์Œ ๋งŒ๋“ค์–ด์กŒ๋˜ ํŒŒ์ผ(credentials.json)์ด ์ด๋ฏธ ์กด์žฌํ•œ ์ƒํƒœ์—์„œ ๊ฐ™์€ ์ด๋ฆ„์œผ๋กœ ํŒŒ์ผ์„ ๋‹ค์‹œ ๋ณต์‚ฌํ•˜๊ฑฐ๋‚˜

     ์ƒ์„ฑํ•˜๋ ค๊ณ  ํ•˜๋ฉด, ๊ธฐ์กด ํŒŒ์ผ์ด ์ฝ๊ธฐ ์ „์šฉ(read-only) ์ด๊ธฐ ๋•Œ๋ฌธ์— ์“ฐ๊ธฐ ๊ถŒํ•œ์ด ์—†์–ด์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒƒ

 

[ ๊ธฐ์กด ์ฝ”๋“œ ]

pipeline {
    agent any

    environment {
        CREDS_JSON = credentials('credentials-json')
    }
    
    stages {
        stage('Run Tests') {
            steps {
                sh '''
                    cp "$CREDS_JSON" credentials.json
                    python3 -m venv venv
                    . venv/bin/activate
                    pip install -r requirements.txt
                    python3 -m pytest
                '''
            }
        }
    }
}

 

[ ์ˆ˜์ •๋œ ์ฝ”๋“œ ]

pipeline {
    agent any
    
    stages {
        stage('Run Tests') {
            steps {
                sh '''
                    python3 -m venv venv
                    . venv/bin/activate
                    pip install -r requirements.txt
                    python3 -m pytest
                '''
            }
        }
    }
}

 > ์ฆ‰, ์ฒ˜์Œ ์‹คํ–‰ํ•  ๋•Œ๋Š” cp "$CREDS_JSON" credentials.json ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด Secret file์ด ์ •์ƒ์ ์œผ๋กœ ๋ณต์‚ฌ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ฌด๋Ÿฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•˜๋‹ค.

 > ํ•˜์ง€๋งŒ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ๋ฐ˜๋ณต ์‹คํ–‰ํ•˜๋ฉด์„œ, ์ด๋ฏธ ์กด์žฌํ•˜๋˜ credentials.json ํŒŒ์ผ์— ๋‹ค์‹œ ๋ฎ์–ด์“ฐ๋ ค๋‹ค cp ๋ช…๋ น์–ด์—์„œ "Permission denied" ์—๋Ÿฌ๊ฐ€ ๋ฐ˜๋ณต์ ์œผ๋กœ ๋ฐœ์ƒํ–ˆ๋‹ค.

 > ๊ฒฐ๊ตญ cp "$CREDS_JSON" credentials.json ์ด ํ•œ ์ค„์„ ์ œ๊ฑฐํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์ง€๋งŒ, ์–ด๋–ป๊ฒŒ ๋ณด๋ฉด ์•ผ๋งค์— ๊ฐ€๊นŒ์šด ํ•ด๊ฒฐ์ด๋‹ค.

 > ์‹œ๊ฐ„ ๋ถ€์กฑ์œผ๋กœ ๊ธ‰ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ธด ํ–ˆ์ง€๋งŒ, ๋‚˜์ค‘์— ์—ฌ์œ ๊ฐ€ ์ƒ๊ธด๋‹ค๋ฉด ๋ณด๋‹ค ์•ˆ์ •์ ์ด๊ณ  ๊น”๋”ํ•œ ๋ฐฉ์‹์œผ๋กœ ๋‹ค์‹œ ํ•œ๋ฒˆ ํ•ด๊ฒฐ ๋ฐฉ์•ˆ์„ ์ฐพ์•„๋ณด๊ณ  ์‹ถ๋‹ค.

 


 

๊ณต์œ  ์„œ๋ฒ„๋ฅผ ํ†ตํ•œ GitHub์™€ Jenkins ์—ฐ๋™์—๋Š” ์„ฑ๊ณตํ–ˆ์ง€๋งŒ, ๋กœ์ปฌ์—์„œ ์ •์ƒ์ ์œผ๋กœ ํ†ต๊ณผ๋˜๋˜ ํ…Œ์ŠคํŠธ๋“ค์ด Jenkins์—์„œ๋Š” ์‹คํŒจ ํ•˜๋Š” ํ˜„์ƒ์ด ๋ฐœ์ƒํ–ˆ๋‹ค. ์ฒ˜์Œ์—๋Š” ๊ฐ™์€ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์ธ๋ฐ ์™œ Jenkins์—์„œ๋งŒ ์‹คํŒจํ•˜๋Š”์ง€ ์˜๋ฌธ์ด ๋“ค์—ˆ๋‹ค. ์˜คํ”ผ์Šค ์•„์›Œ ์‹œ๊ฐ„์— ์ฝ”์น˜๋‹˜๊ป˜ ์งˆ๋ฌธ์„ ๋“œ๋ ธ๊ณ , ์ฝ”์น˜๋‹˜๋„ ์‹ค๋ฌด์—์„œ ์ข…์ข… ๊ฒช๋Š” ๋ฌธ์ œ๋ผ๊ณ  ํ•˜์…จ๋‹ค.
๊ทธ ์ด์œ ๋Š” Jenkins ์ž์ฒด๊ฐ€ ์–ด๋А ์ •๋„ ๋ฆฌ์†Œ์Šค๋ฅผ ์ ์œ ํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋ผ๊ณ  ์„ค๋ช…ํ•ด์ฃผ์…จ๋‹ค. ์ฆ‰, ๋กœ์ปฌ์—์„œ ํ…Œ์ŠคํŠธ๋ฅผ ๋Œ๋ฆด ๋•Œ์™€ Jenkins ์„œ๋ฒ„์—์„œ ๋Œ๋ฆด ๋•Œ์˜ ํ™˜๊ฒฝ์ด ์™„์ „ํžˆ ๋™์ผํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ, ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๊ฐ€ ์„œ๋ฒ„ ํ™˜๊ฒฝ์—์„œ๋„ ์•ˆ์ •์ ์œผ๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก, ๋” ๋งŽ์€ ๋Œ€๊ธฐ ์‹œ๊ฐ„์„ ๋ถ€์—ฌํ•˜๊ฑฐ๋‚˜ ๊ฐ€์žฅ ๋А๋ฆฌ๊ฒŒ ๋กœ๋”ฉ๋˜๋Š” ์š”์†Œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ฒ€์ฆ ํƒ€์ด๋ฐ์„ ์กฐ์ •ํ•˜๊ฑฐ๋‚˜ ์‹คํŒจ ์‹œ ์ž๋™์œผ๋กœ ์Šคํฌ๋ฆฐ์ƒท์„ ์ฐ์–ด ๋””๋ฒ„๊น…์— ํ™œ์šฉํ•˜๋Š” ๋ฐฉ์‹ ๋“ฑ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๊ณ  ํ•˜์…จ๋‹ค.
๊ฒฐ๊ตญ Jenkins ํ™˜๊ฒฝ์—์„œ์˜ ํ…Œ์ŠคํŠธ๋Š” ์†๋„๋‚˜ ์ž์› ์ฒ˜๋ฆฌ ๋ฐฉ์‹์˜ ์ฐจ์ด๋ฅผ ๊ฐ์•ˆํ•ด์„œ ์ข€ ๋” ์œ ์—ฐํ•˜๊ณ  ๋ฐฉ์–ด์ ์ธ ๋ฐฉ์‹์œผ๋กœ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ ์„ ๋‹ค์‹œ ํ•œ ๋ฒˆ ๋А๋ผ๊ฒŒ ๋˜์—ˆ๋‹ค. ์‹œ๊ฐ„์ƒ ์ด๋ฒˆ ์‹ค์Šต์—์„œ๋Š” ์ด ๋ฌธ์ œ๋ฅผ ์™„์ „ํžˆ ํ•ด๊ฒฐํ•˜์ง€๋Š” ๋ชปํ–ˆ์ง€๋งŒ, ์•ž์œผ๋กœ๋Š” Jenkins์™€ ๊ฐ™์€ CI ํ™˜๊ฒฝ์—์„œ๋„ ์•ˆ์ •์ ์œผ๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž์ฒด๋ฅผ ๋” ๊ฒฌ๊ณ ํ•˜๊ฒŒ ์„ค๊ณ„ํ•  ํ•„์š”์„ฑ์„ ๋А๊ผˆ๋‹ค.
 

๐Ÿ”ฅ ํ…Œ์ŠคํŠธ ๋กœ๊ทธ ์ถ”๊ฐ€

๋”๋ณด๊ธฐ
@pytest.mark.ys
def test_myFeed_001(createDriver):
    try:
        myfeed = myFeed(createDriver)
        myfeed.goToPage("๊ฐœ์ธ ํ”ผ๋“œ")

        assert myfeed.getElement(myFeedLocators.MY_FEED_TXT)
        assert myfeed.getElement(myFeedLocators.MY_PROFILE_CHANGE_SVG)
        assert myfeed.getElement(myFeedLocators.MY_PROFILE_STAT_IMG)
        assert myfeed.getElement(myFeedLocators.MY_MENU_PLUS_BTN)
        assert myfeed.getElement(myFeedLocators.MY_EAT_SAME_MENU_BTN)
        myfeed.logger.info("โ–ถ๏ธ myfeed_001 - ๊ฐœ์ธ ํ”ผ๋“œ ํƒญ ์„ ํƒ ์‹œ UI ์š”์†Œ ํ™•์ธ")

        myfeed.getElement(myFeedLocators.MY_FEED_BACK_PAGE).click()
        assert myfeed.getElement(myFeedLocators.HOME_TXT)
        myfeed.logger.info("โ–ถ๏ธ myfeed_002 - [๋’ค๋กœ๊ฐ€๊ธฐ] ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์ด์ „ ํŽ˜์ด์ง€๋กœ ์ด๋™ ํ™•์ธ")

        myfeed.logger.info(f"โœ… {inspect.currentframe().f_code.co_name} ํ†ต๊ณผ")
    except Exception as e:
        myfeed.logger.warning(f"โ— {inspect.currentframe().f_code.co_name} : {e}")
        raise

ํ˜„์žฌ๋Š” ์œ ์‚ฌํ•œ ํ๋ฆ„์ด๋‚˜ ๊ธฐ๋Šฅ์„ ๊ฐ–๋Š” ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋“ค์„ ๋ฌถ์–ด, ํ•˜๋‚˜์˜ ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ์•ˆ์—์„œ ์—ฌ๋Ÿฌ TC๋ฅผ ๋™์‹œ์— ๊ฒ€์ฆํ•˜๋Š” ๊ตฌ์กฐ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ๊ตฌ์„ฑํ–ˆ๋‹ค. ๊ฐ ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ์ด๋ฆ„์€ Google ์Šคํ”„๋ ˆ๋“œ์‹œํŠธ์— ์ •๋ฆฌํ•œ ์ž๋™ํ™” ํ•จ์ˆ˜ ID์™€ ๋™์ผํ•˜๊ฒŒ ์„ค์ •ํ–ˆ์œผ๋ฉฐ, inspect ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ™œ์šฉํ•ด ํ…Œ์ŠคํŠธ๊ฐ€ ์„ฑ๊ณตํ•˜๋ฉด ํ•ด๋‹น ํ•จ์ˆ˜๋ช…์ด ์ž๋™์œผ๋กœ ๋กœ๊ทธ์— ์ถœ๋ ฅ๋˜๋„๋ก ๊ตฌ์„ฑํ–ˆ๋‹ค. ๋•๋ถ„์— ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ๋‹จ์œ„๋กœ๋Š” pass/fail ์—ฌ๋ถ€๋ฅผ ์ง๊ด€์ ์œผ๋กœ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.
ํ•˜์ง€๋งŒ ๋ฌธ์ œ๋Š”, ํ•˜๋‚˜์˜ ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜์— ์—ฌ๋Ÿฌ TC๊ฐ€ ๋ฌถ์—ฌ ์žˆ๋‹ค ๋ณด๋‹ˆ, ํ•จ์ˆ˜๊ฐ€ ์‹คํŒจํ–ˆ์„ ๋•Œ ์–ด๋–ค TC์—์„œ ์‹คํŒจํ–ˆ๋Š”์ง€๊นŒ์ง€๋Š” ์•Œ ์ˆ˜ ์—†์—ˆ๋‹ค๋Š” ์ ์ด๋‹ค. ๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” ์ด ํ•œ๊ณ„๋ฅผ ๋ณด์™„ํ•˜๊ธฐ ์œ„ํ•ด, ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ๋‚ด๋ถ€์— ๊ฐ TC๋งˆ๋‹ค ๊ฐœ๋ณ„ assert๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌ์„ฑ์„ ๋ณ€๊ฒฝํ–ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํŠน์ • assert๊ฐ€ ์‹คํŒจํ–ˆ์„ ๋•Œ ์–ด๋–ค TC๊ฐ€ ๋ฌธ์ œ์˜€๋Š”์ง€ ๋กœ๊ทธ๋ฅผ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ณ , TC ๋‹จ์œ„์˜ pass/fail ์ •๋ณด๋ฅผ ํ™•๋ณดํ•˜๋ฉด์„œ๋„ ๊ธฐ์กด ํ•จ์ˆ˜ ๊ตฌ์กฐ๋Š” ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.


๐Ÿ“Œ 4/2 - 9์ผ์ฐจ ํšŒ๊ณ  (์‹œ์—ฐ ์˜์ƒ ์ œ์ž‘ ๋ฐ ๋ฐœํ‘œ ์ค€๋น„)

 
์˜ค๋Š˜์€ ์ตœ์ข… ์‹œ์—ฐ ์˜์ƒ ์ œ์ž‘์„ ์œ„ํ•œ ์ž‘์—…์„ ์ง„ํ–‰ํ–ˆ๋‹ค. ๋จผ์ € ํ…Œ์ŠคํŠธ ๋™์ž‘ ๊ณผ์ •์„ ์˜์ƒ์œผ๋กœ ๋‹ด๊ธฐ ์œ„ํ•ด, time.sleep()์„ ๊ณณ๊ณณ์— ์‚ฝ์ž…ํ•˜์—ฌ ์ž๋ง‰์„ ๋‹ฌ ์ˆ˜ ์žˆ๋Š” ์—ฌ์œ  ์‹œ๊ฐ„์„ ํ™•๋ณดํ–ˆ๋‹ค. ๊ทธ ํ›„ ๋ฐ˜๋””์บ ์„ ์„ค์น˜ํ•ด ์‹ค์ œ ํ…Œ์ŠคํŠธ ๋™์ž‘ ๊ณผ์ •์„ ๋…นํ™”ํ–ˆ๋‹ค. ๋…นํ™”๊ฐ€ ๋๋‚œ ๋’ค์—๋Š”, ๊ฐ์ž์˜ ์ฝ”๋“œ๋ฅผ ์ตœ์ข…์ ์œผ๋กœ ์ •๋ฆฌํ•œ ํ›„ develop ๋ธŒ๋žœ์น˜์— mergeํ–ˆ๊ณ , ๋ชจ๋“  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ main ๋ธŒ๋žœ์น˜๋กœ ์ตœ์ข… ๋ฐ˜์˜ํ–ˆ๋‹ค.
์˜์ƒ ์ œ์ž‘ ๊ฒฝํ—˜์ด ์žˆ๋Š” ํŒ€์›๋ถ„๊ป˜์„œ ํŽธ์ง‘๊ณผ ์˜์ƒ ์ œ์ž‘์„ ๋งก์•„์ฃผ์…จ๊ณ , ์•„์ง ์ฝ”๋“œ๋ฅผ ๋งˆ๋ฌด๋ฆฌํ•˜์ง€ ๋ชปํ•œ ํŒ€์›๋ถ„๋“ค๊ป˜์„œ๋Š” ๊ณ„์†ํ•ด์„œ ๊ฐ์ž์˜ ๊ตฌํ˜„ ์ž‘์—…์„ ์ด์–ด๋‚˜๊ฐ”๋‹ค. ๋‚˜๋Š” ๊ฐœ์ธ์ ์œผ๋กœ ์ฝ”๋“œ ์ •๋ฆฌ์™€ ๋กœ๊ทธ ์บก์ฒ˜๊นŒ์ง€ ๋ชจ๋‘ ์™„๋ฃŒํ–ˆ์œผ๋ฉฐ, ์˜์ƒ ๋…นํ™”๋„ ๋งˆ๋ฌด๋ฆฌ๋œ ์ƒํƒœ์˜€๋‹ค. ๊ทธ๋ž˜์„œ ๋ฐœํ‘œ๋ฅผ ์ค€๋น„ํ•˜์‹œ๋Š” ํŒ€์›๋ถ„์„ ๋„์™€, ํ•„์š”ํ•œ ์ž๋ฃŒ๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ  ๋ฌธ์„œ๋ฅผ ์ •๋ฆฌํ•˜๋Š” ์ž‘์—…์„ ๋งก์•˜์œผ๋ฉฐ, ํ•„์š”ํ•œ ๋‚ด์šฉ์€ ๋ฐ”๋กœ๋ฐ”๋กœ ๋ฌธ์„œ๋กœ ์ž‘์„ฑํ•ด ์ „๋‹ฌํ•˜๋ฉด์„œ ๋Œ€๋ณธ ์ž‘์„ฑ์—๋„ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๊ธฐ์—ฌํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.
 

์ง€๊ธˆ๊นŒ์ง€ ๋ฐœ๊ฒฌํ–ˆ๋˜ ์˜ค๋ฅ˜๋“ค์„ ๋ชจ๋‘ Figma์— ์ •๋ฆฌํ•ด๋‘์—ˆ๊ณ , ๋‚ด๊ฐ€ ์ง์ ‘ ๊ฒช์—ˆ๋˜ ์ž‘์—… ํ๋ฆ„๊ณผ ์‹œํ–‰์ฐฉ์˜ค, ์ฃผ์š” ๊ฒฐ์ • ์‚ฌํ•ญ๋“ค๋„ Figma์— ํƒ€์ž„๋ผ์ธ ํ˜•์‹์œผ๋กœ ์ •๋ฆฌํ•ด ๊ณต์œ ํ–ˆ๋‹ค. ์ด ์ž๋ฃŒ๋Š” ๋ฐœํ‘œ๋ฅผ ์ค€๋น„ํ•˜์‹œ๋Š” ํŒ€์›๋ถ„๊ป˜์„œ ์ „์ฒด ํ”„๋กœ์ ํŠธ ํ๋ฆ„์„ ๋น ๋ฅด๊ฒŒ ํŒŒ์•…ํ•˜๊ณ , ๋ฐœํ‘œ ์ž๋ฃŒ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐ ํฐ ๋„์›€์ด ๋˜์—ˆ๋‹ค.
 

ํŒ€์›๋ถ„๋“ค๊ป˜์„œ ๊ฐ์ž ์ฝ”๋“œ ๋งˆ๋ฌด๋ฆฌ, ๋กœ๊ทธ ์ถ”๊ฐ€, ์˜์ƒ ์ดฌ์˜ ๋ฐ ๋ฐœํ‘œ ์ค€๋น„ ๋“ฑ์œผ๋กœ ๋ฐ”์˜์‹  ์ƒํ™ฉ์ด์–ด์„œ, ํ•ด์•ผ ํ•  ์ผ๋“ค์ด ๋‹ค์†Œ ํฉ์–ด์ ธ ์žˆ๋Š” ๋А๋‚Œ์ด์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋‚ด๊ฐ€ ๋Œ€ํ‘œ๋กœ ์ „์ฒด ์ž‘์—… ํ•ญ๋ชฉ์„ ์ •๋ฆฌํ•ด To-Do ๋ฆฌ์ŠคํŠธ ํ˜•ํƒœ๋กœ ๊ณต์œ ํ–ˆ๊ณ , ์ด๋ฅผ ํ†ตํ•ด ๊ฐ์ž์˜ ์ž‘์—… ์ง„ํ–‰ ์ƒํ™ฉ๊ณผ ์•ž์œผ๋กœ ํ•ด์•ผ ํ•  ์ผ๊นŒ์ง€ ํ•œ๋ˆˆ์— ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™”๋‹ค. ์ •๋ฆฌํ•˜๋Š” ๊ณผ์ •์—์„œ ๋‚˜ ์—ญ์‹œ ํŒ€ ์ „์ฒด์˜ ํ๋ฆ„์„ ๋‹ค์‹œ ํ•œ๋ฒˆ ์ ๊ฒ€ํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ , ๊ทธ ๋•๋ถ„์— ์ดํ›„ ์ผ์ • ์กฐ์œจ์ด๋‚˜ ์ง€์›์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„์„ ๋” ๋น ๋ฅด๊ฒŒ ์บ์น˜ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.
 

Jenkins ์„ค์ • ๋ฐ ์—ฐ๋™ ๊ณผ์ •, ๊ทธ๋ฆฌ๊ณ  ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ์— ๋Œ€ํ•œ ๋ฌธ์„œ๋„ ๋‚ด๊ฐ€ ์ง์ ‘ ์ž‘์„ฑํ•ด ํŒ€์›๋“ค๊ณผ ๊ณต์œ ํ–ˆ๋‹ค. Jenkins์™€ GitLab ์—ฐ๋™์€ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ๋‚ด๊ฐ€ ์ง์ ‘ ์ง„ํ–‰ํ–ˆ๋˜ ์ž‘์—…์ด์—ˆ๊ณ , ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ ์—ญ์‹œ ๊ตฌ์„ฑ ๋ฐฉํ–ฅ์„ ์ฒ˜์Œ๋ถ€ํ„ฐ ์ •๋ฆฌํ•˜๋ฉฐ ์ฃผ๋„์ ์œผ๋กœ ์žก์•„๊ฐ”๋˜ ๋ถ€๋ถ„์ด์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, ํ•ด๋‹น ๋‚ด์šฉ์€ ๋‚ด๊ฐ€ ๊ฐ€์žฅ ์ •ํ™•ํžˆ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํŒ๋‹จํ•ด ๋ฌธ์„œ๋กœ ์ •๋ฆฌํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ์ดํ›„ ๋ฐœํ‘œ๋ฅผ ์ค€๋น„ํ•˜์‹œ๋Š” ํŒ€์›๊ป˜์„œ๋Š” ์ด ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•ด ๊ด€๋ จ ๋‚ด์šฉ์„ ๋ฐœํ‘œ ์ž๋ฃŒ์— ๋ฐ˜์˜ํ•˜์…จ๊ณ , ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ์ถ”๊ฐ€ ์ž๋ฃŒ๋„ ํ•จ๊ป˜ ์ •๋ฆฌํ•ด ๊ณต์œ ๋“œ๋ ธ๋‹ค.
 

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


๐Ÿ“Œ 4/3 - 10์ผ์ฐจ ํšŒ๊ณ  (ํ”„๋กœ์ ํŠธ ๋ฐœํ‘œ ๋ฐ ํšŒ๊ณ )

์ด ๋‚ ์€ ๋‚ด๊ฐ€ ๋งก์€ TC ์ตœ์ข… ๋งˆ๋ฌด๋ฆฌ ์ž‘์—…์„ ์ง„ํ–‰ํ–ˆ๊ณ , ๋ฐœ๊ฒฌ๋œ ์ด์Šˆ๋Š” Jira๋ฅผ ํ™œ์šฉํ•ด ๋ฒ„๊ทธ ๋ฆฌํฌํŠธ๋กœ ์ •๋ฆฌํ•ด ๊ณต์œ ํ–ˆ๋‹ค. ๋˜ํ•œ, PPT ์ œ์ž‘๊ณผ ๋ฐœํ‘œ ์ค€๋น„๋ฅผ ๋งก์œผ์‹  ๋‘ ํŒ€์›๋ถ„๋“ค์ด ์›Œ๋‚™ ๋ฐ”์œ ์ƒํ™ฉ์ด์–ด์„œ ๊ทธ๋ถ„๋“ค์„ ๋Œ€์‹ ํ•ด ํ•„์š”ํ•œ ๋ฌธ์„œ ์ž‘์„ฑ ๋ฐ ์ž๋ฃŒ ๊ณต์œ , ํŒŒ์ผ ์ •๋ฆฌ์™€ ์ž๋ฃŒ ์ˆ˜์ง‘ ๋“ฑ ๋งˆ๋ฌด๋ฆฌ ์ž‘์—…๋„ ํ•จ๊ป˜ ์ง„ํ–‰ํ–ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ ํ•˜๋‚˜ํ•˜๋‚˜ ์ •๋ฆฌ๋ฅผ ํ•˜๋‹ค ๋ณด๋‹ˆ ์–ด๋А๋ง ๋ฐœํ‘œ ์‹œ๊ฐ„์ด ๊ฐ€๊นŒ์›Œ์กŒ๊ณ , ๋ฐœํ‘œ ์ž๋ฃŒ ์ œ์ถœ ๋งˆ๊ฐ์ด ์˜คํ›„ 3์‹œ์˜€๋Š”๋ฐ, ์ •๋ง ๊ฐ„๋ฐœ์˜ ์ฐจ์ด๋กœ ์ œ์ถœ์„ ์™„๋ฃŒํ•  ์ˆ˜ ์žˆ์—ˆ์„ ๋งŒํผ ๊ธ‰๋ฐ•ํ•˜๊ฒŒ ๋Œ์•„๊ฐ”๋˜ ํ•˜๋ฃจ์˜€๋‹ค.
 

์˜คํ›„ 3์‹œ์— ๋ฐœํ‘œ ์ž๋ฃŒ๋ฅผ ์ œ์ถœํ•œ ๋’ค, ๊ณง๋ฐ”๋กœ ๋ฐœํ‘œ์šฉ PPT์™€ ๋Œ€๋ณธ์— ๋Œ€ํ•œ ํ”ผ๋“œ๋ฐฑ์„ ์ฃผ๊ณ ๋ฐ›๋‹ค ๋ณด๋‹ˆ, ์–ด๋А๋ง ๋ฐœํ‘œ ์‹œ์ž‘ ์‹œ๊ฐ„์ธ ์˜คํ›„ 5์‹œ๊ฐ€ ๋˜์–ด ์žˆ์—ˆ๋‹ค. ์šฐ๋ฆฌ ์กฐ๋Š” ์˜ค๋Š˜ ์˜คํ›„ 12์‹œ๋ถ€ํ„ฐ ๋ฐœํ‘œ๊ฐ€ ๋๋‚˜๋Š” ์˜คํ›„ 7์‹œ๊นŒ์ง€ ๋‹จ ํ•œ ๋ผ๋„ ๋จน์ง€ ๋ชปํ–ˆ๋‹ค๋Š” ์Šฌํ”ˆ ์‚ฌ์‹ค.. ์ค‘๊ฐ„์— ๋„ˆ๋ฌด ๋ฐฐ๊ฐ€ ๊ณ ํŒŒ์„œ ์ƒŒ๋“œ์œ„์น˜๋ฅผ ์‚ฌ ์˜ค๊ธด ํ–ˆ์ง€๋งŒ, ๋จน์ง€๋„ ๋ชปํ•˜๊ณ  ์Šคํ„ฐ๋””๋ฃธ ๊ฒฝ๊ณ  1ํšŒ๋งŒ ํš๋“ํ•ด๋ฒ„๋ ธ๊ณ , ๊ทธ ์ƒŒ๋“œ์œ„์น˜๋Š” ์•„์ง๋„ ๋‚ด ๋ƒ‰์žฅ๊ณ  ์•ˆ์— ๊ทธ๋Œ€๋กœ ์žˆ๋‹ค..
์‚ฌ์‹ค ์˜ค๋Š˜ ๊ณต์‹์ ์ธ ์ˆ˜์—… ์ข…๋ฃŒ ์‹œ๊ฐ„์€ ์˜คํ›„ 11์‹œ์˜€์ง€๋งŒ, ํ”„๋กœ์ ํŠธ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ๋งˆ๋ฌด๋ฆฌ๋˜๊ธฐ๋„ ํ–ˆ๊ณ , ์˜คํ”„๋ผ์ธ ์กฐ์ด๊ธฐ๋„ ํ•ด์„œ ํšŒ๊ณ ๋Š” ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ˆ ์ž๋ฆฌ์—์„œ ์ด์–ด์ง€๊ฒŒ ๋˜์—ˆ๋‹ค ใ…‹ใ…‹ ์กฐํ‡ด ์ฒ˜๋ฆฌ 1ํšŒ์ •๋„๋Š” ๊ดœ์ฐฎ์ž–์•„ ์†”์งํžˆ..


๐ŸŽฏ 1์ฐจ ํ”„๋กœ์ ํŠธ ์ตœ์ข… ํšŒ๊ณ 

 

โฌ‡๏ธ GitHub ์ฃผ์†Œ

 

GitHub - kys0529/EliceQA_First_Project

Contribute to kys0529/EliceQA_First_Project development by creating an account on GitHub.

github.com

 

โœ… ํ•จ๊ป˜ ๋งŒ๋“ , ํ•จ๊ป˜ ์„ฑ์žฅํ•œ ์—ดํ˜

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ ๊ฐ€์žฅ ์ธ์ƒ ๊นŠ์—ˆ๋˜ ์ ์€, ํŒ€ ๋ถ„์œ„๊ธฐ์™€ ํ˜‘์—…์ด ๊ฒฐ๊ณผ์— ๋ฏธ์น˜๋Š” ์˜ํ–ฅ์ด ์ •๋ง ํฌ๋‹ค๋Š” ์‚ฌ์‹ค์ด์—ˆ๋‹ค.

์‹ค๋ฌด ๊ฒฝํ—˜์ด ์—†๊ฑฐ๋‚˜ ์ฝ”๋“œ ์ž‘์„ฑ์— ์ต์ˆ™ํ•˜์ง€ ์•Š์€ ํŒ€์›๋“ค๋„ ์žˆ์—ˆ์ง€๋งŒ, ๊ฐ์ž์˜ ๊ฐ•์ ์„ ์‚ด๋ ค ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ณด์™„ํ•˜๊ณ , ์„œ๋กœ ๋ฐฐ์šฐ๋ฉฐ ํ•จ๊ป˜ ์ด๋Œ์–ด์ค€ ๋•๋ถ„์— ๋‹จ ํ•œ ๋ช…์˜ ๋‚™์˜ค ์—†์ด ๋๊นŒ์ง€ ํ•จ๊ป˜ ์™„์ฃผํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์—ญํ•  ๋ถ„๋‹ด๋„ ์ž์—ฐ์Šค๋Ÿฝ๊ณ  ํšจ์œจ์ ์œผ๋กœ ์ด๋ค„์กŒ์œผ๋ฉฐ, ๋‚˜๋Š” ํŠนํžˆ TC ์ž‘์„ฑ ๋‹จ๊ณ„์—์„œ ํŒ€์›๋“ค์—๊ฒŒ ๋งŽ์€ ๋„์›€์„ ๋ฐ›์•˜๊ณ , ๋ฐ˜๋Œ€๋กœ ์ฝ”๋“œ ๊ตฌํ˜„์ด๋‚˜ Jenkins ์—ฐ๋™ ๊ฐ™์€ ๊ธฐ์ˆ ์ ์ธ ๋ถ€๋ถ„์—์„œ๋Š” ๋‚ด๊ฐ€ ๋จผ์ € ๋‚˜์„œ์„œ ๊ธฐ์—ฌํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

ํŠนํžˆ, ์—ด๋ฆฐ ํŒ€ ๋ถ„์œ„๊ธฐ๋Š” ๋‹ค์–‘ํ•œ ์•„์ด๋””์–ด๊ฐ€ ์˜ค๊ฐˆ ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋ฐ˜์ด ๋˜์—ˆ๊ณ , ๋•๋ถ„์— ๊ธฐ๋Šฅ ๋ช…์„ธ์„œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ž‘์„ฑํ•˜๋˜ TC๋ฅผ ํ™”๋ฉด(Tab) ๋‹จ์œ„๋กœ ์ „ํ™˜ํ•˜๋Š” ๊ตฌ์กฐ์  ๊ฐœ์„ ๋„ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ด๋ฃจ์–ด์งˆ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋˜ํ•œ, goToPage ํ•จ์ˆ˜๋‚˜ Locator ํŒŒ์ผ ๋ถ„๋ฆฌ์™€ ๊ฐ™์€ ์•„์ด๋””์–ด๋„ ์ž์œ ๋กญ๊ฒŒ ์˜ค๊ฐˆ ์ˆ˜ ์žˆ์—ˆ๊ณ , ์ด๋Ÿฌํ•œ ๊ตฌ์กฐ ๊ฐœ์„ ๋“ค์€ ์ž๋™ํ™” ์ฝ”๋“œ์˜ ์™„์„ฑ๋„์™€ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ๋†’์ด๋Š” ๋ฐ ํฐ ๊ธฐ์—ฌ๋ฅผ ํ–ˆ๋‹ค.

์ „์ฒด์ ์ธ ํ๋ฆ„ ์†์—์„œ ๊ฐ€๋”์€ ํŒ€์›๋“ค์˜ ์ง‘์ค‘๋ ฅ์ด ํํŠธ๋Ÿฌ์ง€๊ฑฐ๋‚˜ ๋ฐฉํ–ฅ์ด ํ”๋“ค๋ฆฌ๋Š” ์ˆœ๊ฐ„๋“ค๋„ ์žˆ์—ˆ๋‹ค. ๊ทธ๋Ÿด ๋•Œ ๋‚˜๋Š” ๋ถ„์œ„๊ธฐ๋ฅผ ๋‹ค์žก๊ธฐ ์œ„ํ•ด ์กฐ์‹ฌ์Šค๋Ÿฝ๊ฒŒ ์“ด์†Œ๋ฆฌ๋ฅผ ํ•˜๊ธฐ๋„ ํ–ˆ๊ณ , ํ๋ฆ„์„ ๋ฒ—์–ด๋‚˜์ง€ ์•Š๋„๋ก ์ค‘์‹ฌ์„ ๋‹ค์‹œ ์žก๋Š” ์—ญํ• ์„ ํ•˜๋ ค ๋…ธ๋ ฅํ–ˆ๋‹ค. ๋‹จ์ˆœํžˆ ์ž˜ํ•ด๋ณด์ž๋Š” ๋งˆ์Œ๋งŒ์œผ๋กœ๋Š” ๋ถ€์กฑํ•˜๋‹ค๋Š” ๊ฑธ ๋ˆ„๊ตฌ๋ณด๋‹ค ์ž˜ ์•Œ๊ณ  ์žˆ์—ˆ๊ธฐ์—, ํŒ€์˜ ์ค‘์‹ฌ์„ ์žก๊ณ  ํํŠธ๋Ÿฌ์ง€์ง€ ์•Š๋„๋ก ํ•จ๊ป˜ ๊ฐ€๊ณ  ์‹ถ์—ˆ๋‹ค. ๊ฒฐ๊ตญ ๊ทธ๋Ÿฐ ๊ณผ์ •์„ ๊ฑฐ์น˜๋ฉฐ, ์šฐ๋ฆฌ ํŒ€์€ ๋๊นŒ์ง€ ์ง‘์ค‘๋ ฅ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ , ์Šค์Šค๋กœ๋„ ํŒ€ ์ „์ฒด๊ฐ€ ์ž˜ ๋งˆ๋ฌด๋ฆฌ๋  ์ˆ˜ ์žˆ๋„๋ก ์กฐ๊ธˆ์ด๋‚˜๋งˆ ๋ฐฉํ–ฅ์„ ์žก์•„์ฃผ๋Š” ์—ญํ• ์„ ํ–ˆ๋‹ค๋Š” ์ ์ด ๋ฟŒ๋“ฏํ•˜๊ฒŒ ๋А๊ปด์กŒ๋‹ค.

๋งค์ผ๋งค์ผ ์ •์‹ ์—†์ด ๋ฐ”๋นด์ง€๋งŒ, ํŒ€์›๋ถ„๋“ค ๋•๋ถ„์— ๊ทธ๋งŒํผ ๋งŽ์ด ์›ƒ์—ˆ๋˜ ์‹œ๊ฐ„๋“ค๋„ ๋งŽ์•˜๊ณ , ์ •๋ง ์˜ค๋žœ๋งŒ์— ์‚ฌ๋žŒ ๊ด€๋ จํ•œ ์ŠคํŠธ๋ ˆ์Šค๋Š” ํฌ๊ฒŒ ์—†์—ˆ๋˜ ๊ฒƒ ๊ฐ™๊ณ , ๋‚˜๋ฆ„ ์ฆ๊ฒ๊ฒŒ ์ผํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ์กฐํ•ฉ์ด์—ˆ๋˜ ๊ฒƒ ๊ฐ™๋‹ค. ๊ฒฐ๊ณผ๊ฐ€ ์–ด๋–ป๋“ , ์ด๋ฒˆ ํŒ€ ํ”„๋กœ์ ํŠธ๋ฅผ ํ†ตํ•ด ์ •๋ง ๋งŽ์ด ๋ฐฐ์šฐ๊ณ  ์„ฑ์žฅํ–ˆ๋‹ค๋Š” ์‚ฌ์‹ค๋งŒํผ์€ ๋ถ„๋ช…ํ•˜๋‹ค. ์งง์ง€๋งŒ ๊ฐ•๋ ฌํ–ˆ๋˜ 10์ผ์ด์—ˆ๋‹ค!

 

โœ… ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์ž‘์„ฑ๊ณผ ์ž๋™ํ™” ๊ตฌํ˜„์—์„œ์˜ ๊ณ ๋ฏผ๋“ค

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

๊ทธ๋ ‡์ง€๋งŒ ์šฐ๋ฆฌ ํŒ€์€ ์ด ์„ธ์„ธํ•˜๊ฒŒ ๋‚˜๋‰œ TC๋“ค์„ ํ•˜๋‚˜์˜ ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ์•ˆ์—์„œ ๋™์‹œ์— ๊ฒ€์ฆํ•˜๋Š” ๊ฒƒ์ด ํšจ๊ณผ์ ์ธ ์ผ€์ด์Šค๋“ค๋กœ ๋ฌถ์–ด, ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ID๋ฅผ ๋ถ€์—ฌํ•ด ์ฒด๊ณ„์ ์œผ๋กœ ๊ด€๋ฆฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ •ํ™•์„ฑ๊ณผ ํšจ์œจ์„ฑ์ด๋ผ๋Š” ๋‘ ๋งˆ๋ฆฌ ํ† ๋ผ๋ฅผ ๋ชจ๋‘ ์žก์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ์ ‘๊ทผ์€ ์ž๋™ํ™” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๊ฐ€๋ฉฐ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ํ•œ๊ณ„๋ฅผ ์ฒด๊ฐํ–ˆ๊ณ , ๊ทธ๋•Œ๊ทธ๋•Œ ์œ ์—ฐํ•˜๊ฒŒ ๋Œ€์ฒ˜ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋Šฅํ–ˆ๋˜ ๊ฒฐ๊ณผ์˜€๋‹ค๊ณ  ๋А๋‚€๋‹ค.

 

โœ… Jenkins ์—ฐ๋™๊ณผ ์‹ค๋ฌด ๊ฐ๊ฐ

Jenkins ์—ฐ๋™์€ ๋‚ด๊ฐ€ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ์ง์ ‘ ๋งก์•„ ์ง„ํ–‰ํ•œ ์ž‘์—…์œผ๋กœ, ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ํ†ตํ•ด CI ํ™˜๊ฒฝ์„ ์Šค์Šค๋กœ ๊ตฌ์ถ•ํ•ด๋ณด๋Š” ๊ฒฝํ—˜์„ ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ํ˜ผ์ž์„œ ํ•ด๋‚ด์•ผ ํ•œ๋‹ค๋Š” ์ฑ…์ž„๊ฐ๊ณผ ๋ถ€๋‹ด๊ฐ ์†์—์„œ, ํ•˜๋ฃจ์— 10์‹œ๊ฐ„ ๋„˜๊ฒŒ, ์ดํ‹€ ๋„˜๋„๋ก ์‚ฝ์งˆํ•˜๋ฉฐ ๋…ธ๋ ฅํ•œ ๋์— ๊ฒฐ๊ตญ ์—ฐ๋™์— ์„ฑ๊ณตํ–ˆ๊ณ , ๊ทธ ์ˆœ๊ฐ„์˜ ๋ฟŒ๋“ฏํ•จ์€ ์ •๋ง ์ปธ๋‹ค.

์ด ๊ณผ์ •์—์„œ Docker๋ฅผ ํ™œ์šฉํ•œ Jenkins ์ด๋ฏธ์ง€ ๋นŒ๋“œ์™€ ์ปจํ…Œ์ด๋„ˆ ์ƒ์„ฑ, ํ”„๋กœ์ ํŠธ์— ๋งž์ถ˜ ํ™˜๊ฒฝ ์„ธํŒ…, ๊ทธ๋ฆฌ๊ณ  ํŒ€์›๋“ค์—๊ฒŒ ๋™์ผํ•œ ํ™˜๊ฒฝ์„ ๋น ๋ฅด๊ฒŒ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•œ Dockerfile ์ œ์ž‘๊นŒ์ง€ ์ •๋ง ๋งŽ์€ ์‹ค์ „ ๊ฒฝํ—˜์„ ํ•ด๋ณผ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๊ทธ๋งŒํผ ๋ฐฐ์šด ๊ฒƒ๋„ ๊ฐ€์žฅ ๋งŽ์•˜๋˜ ํŒŒํŠธ์˜€๊ณ , ๋™์‹œ์— ๊ฐ€์žฅ ๋‚˜๋ฅผ ๊ดด๋กญํ˜”๋˜ ํŒŒํŠธ์ด๊ธฐ๋„ ํ–ˆ๋‹ค. ๋งŽ์ด ํž˜๋“ค๊ธด ํ–ˆ์ง€๋งŒ, ๊ทธ ๊ณผ์ •์„ ํ†ตํ•ด ์ด๋ก  ์ˆ˜์—…๋ณด๋‹ค ํ›จ์”ฌ ๊ฐ•๋ ฅํ•œ ์‹ค์ „ ๊ฐ๊ฐ์„ ์–ป๊ฒŒ ๋˜์—ˆ๋‹ค๊ณ  ๋А๋‚€๋‹ค.

 

โœ… ์ž๋™ํ™” ์ฝ”๋“œ์™€ ๊ตฌ์กฐ ์„ค๊ณ„

์ž๋™ํ™” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ ๊ฐ€์žฅ ํฌ๊ฒŒ ๋А๋‚€ ์ ์€, “์•„๋ฌด๋ฆฌ ์ž๋™ํ™”๋ฅผ ํ•˜๋”๋ผ๋„ ๋ฐ˜๋ณต์€ ์กด์žฌํ•œ๋‹ค”๋Š” ํ˜„์‹ค์ด์—ˆ๋‹ค.

๋ฐ˜๋ณต์„ ์ตœ๋Œ€ํ•œ ์ค„์ด๊ธฐ ์œ„ํ•ด

  • ์ค‘๋ณต ๋™์ž‘์€ goToPage() ํ•จ์ˆ˜๋กœ ๋ถ„๋ฆฌํ•˜๊ณ ,
  • ํŽ˜์ด์ง€๋ณ„๋กœ locator ํŒŒ์ผ์„ ๋”ฐ๋กœ ๊ด€๋ฆฌํ–ˆ์œผ๋ฉฐ,
  • ๋ฐ˜๋ณต๋˜๋Š” ์ฝ”๋“œ ํ๋ฆ„์€ ํ•จ์ˆ˜ํ™”ํ•˜์—ฌ ์žฌ์‚ฌ์šฉ์„ฑ์„ ๋†’์ด๊ณ ์ž ํ–ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๊ตฌ์กฐ๋Š” ์‹ค์ œ๋กœ ์œ ์ง€๋ณด์ˆ˜์„ฑ๊ณผ ํ˜‘์—… ํšจ์œจ์„ ๋†’์ด๋Š” ๋ฐ ๊ฝค ํšจ๊ณผ์ ์ด์—ˆ๋‹ค.
๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , ์—ฌ์ „ํžˆ ๋ฐ˜๋ณต์ ์ธ ๊ตฌ์กฐ๋กœ ํ˜๋Ÿฌ๊ฐ€๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด์„œ “์ž๋™ํ™” ์—ญ์‹œ ๋ฐ˜๋ณต์ ์ด๋‹ค ๋ณด๋‹ˆ ์‹ค๋ฌด์—์„œ ํ˜„ํƒ€๊ฐ€ ์˜ค๊ธฐ๋„ ํ•œ๋‹ค”๋Š” ์˜คํ”ผ์Šค ์•„์›Œ ์ฝ”์น˜๋‹˜์˜ ๋ง์”€์ด ์ •๋ง ๊ณต๊ฐ๋˜์—ˆ๋‹ค. ์•„๋ฌด๋ฆฌ ์ž๋™ํ™”๋ฅผ ํ•ด๋„ ๊ฒฐ๊ตญ ๋ณ€ํ™”์— ๋”ฐ๋ผ ์œ ์ง€๋ณด์ˆ˜๋Š” ํ•„์ˆ˜์ด๊ณ , "์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ๋” ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์„๊นŒ?"๋ผ๋Š” ๊ณ ๋ฏผ์€ ์•ž์œผ๋กœ๋„ ๊ณ„์† ๋ฐ˜๋ณต๋  ์ˆ˜๋ฐ–์— ์—†๋Š” ์ˆ™์ œ์ฒ˜๋Ÿผ ๋А๊ปด์กŒ๋‹ค.

 

โœ… ํŒ€์›Œํฌ, ํ†ต์ผ์„ฑ, ๊ทธ๋ฆฌ๊ณ  ์ง„์งœ ์‹ค๋ฌด ๊ฐ๊ฐ

ํ”„๋กœ์ ํŠธ ํ›„๋ฐ˜๋ถ€๋กœ ๊ฐˆ์ˆ˜๋ก ์ผ์ •์ด ์ด‰๋ฐ•ํ•ด์กŒ๊ณ , ์ž๋ฃŒ ์ •๋ฆฌ, ๋ฐœํ‘œ ์ค€๋น„, ์˜์ƒ ์ดฌ์˜ ๋“ฑ ํ•ด์•ผ ํ•  ์ผ๋“ค์ด ํ•œ๊บผ๋ฒˆ์— ๋ชฐ๋ฆฌ๋ฉด์„œ ์ „๋ฐ˜์ ์œผ๋กœ ๋‹ค์†Œ ๊ธ‰๋ฐ•ํ•œ ๋ถ„์œ„๊ธฐ๊ฐ€ ์žˆ์—ˆ๋˜ ์ ์€ ์•„์‰ฌ์›€์œผ๋กœ ๋‚จ๋Š”๋‹ค. ๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , ๋ชจ๋‘๊ฐ€ ์ž๊ธฐ ์—ญํ• ์„ ๋†“์ง€ ์•Š๊ณ  ๋๊นŒ์ง€ ์™„์ฃผํ–ˆ๋‹ค๋Š” ์ ์€ ์ •๋ง ์ž๋ž‘์Šค๋Ÿฌ์› ๋‹ค.

ํŠนํžˆ ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” Git์„ ํ™œ์šฉํ•œ ํ˜‘์—… ๋ฐฉ์‹์— ๋Œ€ํ•ด ์‹ค์งˆ์ ์œผ๋กœ ๋งŽ์ด ๊ฒฝํ—˜ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๊ฐ ๊ธฐ๋Šฅ์„ ๊ฐœ๋ณ„ ๋ธŒ๋žœ์น˜๋กœ ๋ถ„๋ฆฌํ•ด์„œ ์ž‘์—…ํ•˜๊ณ , PR(Merge Request)์„ ํ†ตํ•ด ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ณต์œ ํ•˜๊ณ  ๋ฆฌ๋ทฐํ•˜๋ฉฐ ์ถฉ๋Œ์„ ๋ฐฉ์ง€ํ•˜๋Š” ํ๋ฆ„์„ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ตํ˜”๋‹ค. ๋˜ํ•œ ์ปค๋ฐ‹ ์‹œ์—๋Š” [ADD], [UPDATE], [DELETE] ๋“ฑ Prefix๋ฅผ ๋ถ™์—ฌ ์ž‘์—… ๋‚ด์—ญ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ๋ถ„ํ•˜๊ณ , ๊ฐ„๋‹จํ•œ ๋ณ€๊ฒฝ์ด๋ผ๋„ ์˜๋ฏธ ์žˆ๋Š” ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€๋ฅผ ์ž‘์„ฑํ•˜๋ ค๋Š” ์Šต๊ด€์„ ์ตํžˆ๊ฒŒ ๋˜์—ˆ๋‹ค. Git ๋ช…๋ น์–ด๋ฟ ์•„๋‹ˆ๋ผ GitHub Desktop, Sourcetree ๋“ฑ ๋‹ค์–‘ํ•œ ๋„๊ตฌ๋“ค์„ ์‹ค์ „์—์„œ ์‚ฌ์šฉํ•ด๋ดค๊ณ , ์‹ค์ œ ํ˜‘์—… ์ƒํ™ฉ์—์„œ ๋ธŒ๋žœ์น˜ ์ „๋žต๊ณผ ๋ฒ„์ „ ๊ด€๋ฆฌ๊ฐ€ ์–ผ๋งˆ๋‚˜ ์ค‘์š”ํ•œ์ง€ ์ฒด๊ฐํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

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

 

โœ… ์„ฑ๊ณผ์™€ ๊ทธ ์˜๋ฏธ

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋Š” ๋‹จ์ˆœํžˆ ๊ฒฐ๊ณผ๋ฌผ์„ ๋งŒ๋“œ๋Š” ๋ฐ์„œ ๋๋‚˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ํŒ€์›Œํฌ, ์ž๋™ํ™” ๊ธฐ์ˆ , ์‹ค๋ฌด ๊ฐ๊ฐ, ํ˜‘์—… ๋„๊ตฌ ํ™œ์šฉ ๋“ฑ ๋‹ค์–‘ํ•œ ์˜์—ญ์—์„œ ์„ฑ์žฅ์„ ์ด๋Œ์–ด๋‚ธ ์—ฌ์ •์ด์—ˆ๋‹ค. ๊ทธ๋ ‡๊ฒŒ 10์ผ๊ฐ„์˜ ๋œจ๊ฑฐ์šด ๋ชฐ์ž…๊ณผ ์„ฑ์‹คํ•œ ํ˜‘์—… ๋์—, ์šฐ๋ฆฌ ํŒ€์€ ์šฐ์ˆ˜์ƒ(2๋“ฑ)์ด๋ผ๋Š” ๋œป๊นŠ์€ ๊ฒฐ๊ณผ๋ฅผ ์–ป๊ฒŒ ๋˜์—ˆ๊ณ , ๋‚˜๋Š” ์šด ์ข‹๊ฒŒ๋„ ๋ฆฌ๋”์ƒ๊นŒ์ง€ ์ˆ˜์ƒํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋ฆฌ๋”์ƒ์„ ์ˆ˜์ƒํ•˜๊ฒŒ ๋œ ๊ฒƒ๋„, ๋‹จ์ˆœํžˆ ๋‚ด๊ฐ€ ๋งก์€ ์—ญํ• ๋งŒ ์ถฉ์‹คํžˆ ์ˆ˜ํ–‰ํ•ด์„œ๊ฐ€ ์•„๋‹ˆ๋ผ ํŒ€์˜ ํ๋ฆ„์„ ์ฃผ๋„ํ•˜๊ณ , ๋ฐฉํ–ฅ์„ฑ์„ ํ•จ๊ป˜ ๊ณ ๋ฏผํ•˜๋ฉฐ ์กฐ์œจํ•ด๋‚˜๊ฐ”๋˜ ๊ณผ์ •์ด ์žˆ์—ˆ๊ธฐ์— ๊ฐ€๋Šฅํ–ˆ๋˜ ๊ฒฐ๊ณผ๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ๋ฌผ๋ก  ์ด ๊ฒฐ๊ณผ๊ฐ€ ์ „๋ถ€๋Š” ์•„๋‹ˆ์ง€๋งŒ, ์šฐ๋ฆฌ๊ฐ€ ํ•จ๊ป˜ ๊ณ ์ƒํ•˜๊ณ  ๊ณ ๋ฏผํ–ˆ๋˜ ๊ณผ์ •์ด ํ—›๋˜์ง€ ์•Š์•˜๋‹ค๋Š” ์ž‘์€ ์ฆ๊ฑฐ์ฒ˜๋Ÿผ ๋А๊ปด์ ธ์„œ ๋”์šฑ ์˜๋ฏธ ์žˆ๊ฒŒ ๋‹ค๊ฐ€์™”๋‹ค.
ํŠนํžˆ ํŒ€์› ๊ฐ์ž๊ฐ€ ๋งก์€ ์—ญํ• ์„ ๋๊นŒ์ง€ ์ฑ…์ž„๊ฐ ์žˆ๊ฒŒ ์ˆ˜ํ–‰ํ–ˆ๊ณ , ๋‚ด๊ฐ€ ํŒ€์žฅ์„ ๋งก์•„ ํŒ€ ์ „์ฒด์˜ ๋ฐฉํ–ฅ์„ ์กฐ์œจํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ–ˆ๋˜ ์‹œ๊ฐ„์ด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ํ•˜๋‚˜์˜ ํ๋ฆ„์œผ๋กœ ์ด์–ด์กŒ๋‹ค๋Š” ์ ์—์„œ ํฐ ๋ณด๋žŒ์„ ๋А๋‚„ ์ˆ˜ ์žˆ์—ˆ๋‹ค. ๋ฌด์—‡๋ณด๋‹ค ์ด ์ƒ์€ ๋‚˜ ํ˜ผ์ž๋งŒ์˜ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ํ•จ๊ป˜ ์„ฑ์žฅํ•˜๊ณ  ํ•จ๊ป˜ ๋ฒ„ํ…จ๋‚ธ ํŒ€์› ๋ชจ๋‘์—๊ฒŒ ์ฃผ์–ด์ง„ ๊ฒฐ๊ณผ๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค. ์ด๋ฒˆ ๊ฒฝํ—˜์€ ๋‹จ์ˆœํ•œ ํ”„๋กœ์ ํŠธ ๊ทธ ์ด์ƒ์˜ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง€๋ฉฐ, ์•ž์œผ๋กœ์˜ ์ปค๋ฆฌ์–ด์— ์žˆ์–ด ๋“ ๋“ ํ•œ ์ฒซ ๋ฒˆ์งธ ์‹ค๋ฌด ๊ฒฝํ—˜์œผ๋กœ ๋‚จ์„ ๊ฒƒ ๊ฐ™๋‹ค.

 

728x90
์ €์ž‘์žํ‘œ์‹œ ๋น„์˜๋ฆฌ ๋ณ€๊ฒฝ๊ธˆ์ง€ (์ƒˆ์ฐฝ์—ด๋ฆผ)

'๐Ÿ“‚ Quality Assurance > ๐Ÿ”ฅ ์—˜๋ฆฌ์Šค SW QAํŠธ๋ž™' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[์—˜๋ฆฌ์Šค SW QA ํŠธ๋ž™ 12์ฃผ์ฐจ] ํ•™์Šต ๋‚ด์šฉ ์ •๋ฆฌ ๋ฐ ํšŒ๊ณ  (API ํ…Œ์ŠคํŠธ ์ž๋™ํ™”)  (0) 2025.04.17
[์—˜๋ฆฌ์Šค SW QA ํŠธ๋ž™ 11์ฃผ์ฐจ] ํ•™์Šต ๋‚ด์šฉ ์ •๋ฆฌ ๋ฐ ํšŒ๊ณ  (๊ณ ๊ธ‰ ์›น ํ…Œ์ŠคํŠธ ์ž๋™ํ™”)  (0) 2025.04.10
[์—˜๋ฆฌ์Šค SW QA ํŠธ๋ž™ 8์ฃผ์ฐจ] ํ•™์Šต ๋‚ด์šฉ ์ •๋ฆฌ ๋ฐ ํšŒ๊ณ  (Git๊ณผ Jenkins๋ฅผ ํ™œ์šฉํ•œ CI/CD ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์ถ•)  (0) 2025.03.20
[์—˜๋ฆฌ์Šค SW QA ํŠธ๋ž™ 7์ฃผ์ฐจ] ํ•™์Šต ๋‚ด์šฉ ์ •๋ฆฌ ๋ฐ ํšŒ๊ณ  (Python์„ ํ™œ์šฉํ•œ ํ…Œ์ŠคํŠธ ์ž๋™ํ™”)  (0) 2025.03.13
[์—˜๋ฆฌ์Šค SW QA ํŠธ๋ž™ 6์ฃผ์ฐจ] ํ•™์Šต ๋‚ด์šฉ ์ •๋ฆฌ ๋ฐ ํšŒ๊ณ  (Selenium์„ ํ™œ์šฉํ•œ ์›น ํ…Œ์ŠคํŠธ ์ž๋™ํ™”)  (0) 2025.03.06
'๐Ÿ“‚ Quality Assurance/๐Ÿ”ฅ ์—˜๋ฆฌ์Šค SW QAํŠธ๋ž™' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [์—˜๋ฆฌ์Šค SW QA ํŠธ๋ž™ 12์ฃผ์ฐจ] ํ•™์Šต ๋‚ด์šฉ ์ •๋ฆฌ ๋ฐ ํšŒ๊ณ  (API ํ…Œ์ŠคํŠธ ์ž๋™ํ™”)
  • [์—˜๋ฆฌ์Šค SW QA ํŠธ๋ž™ 11์ฃผ์ฐจ] ํ•™์Šต ๋‚ด์šฉ ์ •๋ฆฌ ๋ฐ ํšŒ๊ณ  (๊ณ ๊ธ‰ ์›น ํ…Œ์ŠคํŠธ ์ž๋™ํ™”)
  • [์—˜๋ฆฌ์Šค SW QA ํŠธ๋ž™ 8์ฃผ์ฐจ] ํ•™์Šต ๋‚ด์šฉ ์ •๋ฆฌ ๋ฐ ํšŒ๊ณ  (Git๊ณผ Jenkins๋ฅผ ํ™œ์šฉํ•œ CI/CD ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์ถ•)
  • [์—˜๋ฆฌ์Šค SW QA ํŠธ๋ž™ 7์ฃผ์ฐจ] ํ•™์Šต ๋‚ด์šฉ ์ •๋ฆฌ ๋ฐ ํšŒ๊ณ  (Python์„ ํ™œ์šฉํ•œ ํ…Œ์ŠคํŠธ ์ž๋™ํ™”)
YeonSu02
YeonSu02
Email : rkddustn2519@naver.com
  • YeonSu02
    IsLiife2
    YeonSu02
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ
      • ๐Ÿ“‚ Computer Science
      • ๐Ÿ“‚ Unity Engine
        • ๐Ÿ“„ Unity Lecture
        • ๐Ÿ“„ Unity References
        • ๐Ÿ’ป Game Development
      • ๐Ÿ“‚ Quality Assurance
        • ๐Ÿ”ฅ ์—˜๋ฆฌ์Šค SW QAํŠธ๋ž™
        • ๐Ÿ“„ Experience & Insight
        • ๐Ÿ“„ QA References
      • ๐Ÿ“‚ Program Language
        • ๐Ÿ“„ C#
        • ๐Ÿ“„ Python
        • ๐Ÿ“„ JavaScript
        • ๐Ÿ“„ TypeScript
      • ๐Ÿ“‚ Additional
        • ๐Ÿ“„ Docker
        • ๐Ÿ“„ Jenkins
        • ๐Ÿ“„ Playwright
        • ๐Ÿ“„ AI
      • ๐Ÿ“‚ Book Review
      • ๐Ÿ“‚ License
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํ™ˆ
  • ๋งํฌ

    • GitHub
  • ์ธ๊ธฐ ๊ธ€

  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.3
YeonSu02
[์—˜๋ฆฌ์Šค SW QA ํŠธ๋ž™ 9~10์ฃผ์ฐจ] 1์ฐจ ํŒ€ ํ”„๋กœ์ ํŠธ ํšŒ๊ณ 
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”