<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>DDingji</title>
        <link>https://velog.io/</link>
        <description>1년차 주니어 백엔드 개발자, 기록으로 완성하는 나</description>
        <lastBuildDate>Sun, 23 Jul 2023 08:52:37 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>DDingji</title>
            <url>https://velog.velcdn.com/images/myoungji-kim/profile/2c96b129-befe-485a-9456-27e96a36acc4/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. DDingji. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/myoungji-kim" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[1년 차 주니어 개발자가 느낀, 성장하기 좋은 근무 환경]]></title>
            <link>https://velog.io/@myoungji-kim/best-workspace-for-developer</link>
            <guid>https://velog.io/@myoungji-kim/best-workspace-for-developer</guid>
            <pubDate>Sun, 23 Jul 2023 08:52:37 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>⏰ <strong>읽는 시간: 15분</strong></p>
</blockquote>
<h2 id="들어가기-전">들어가기 전</h2>
<p>2022년 8월 8일,
백엔드 개발자로서의 첫 커리어가 시작되었다.</p>
<p>처음 3년이 중요하다라는 주변의 조언을 들으며 긴장 반, 설렘 반을 안고 입사하였는데
정신차려보니 벌써 1년차 개발자가 되어가고 있었다.</p>
<p>중요하다는 3년의 1/3을 보내며 
&#39;나는 입사 초와 많이 달라졌는가?&#39;를 고민했을 때 정말 많이 달라졌다고 느낀다.</p>
<hr>
<h3 id="before">Before</h3>
<ul>
<li>Task를 정리할 때 <strong>나만 이해할 수 있는 글</strong>로 작성했다</li>
<li>나에게 주어진 업무를 제대로 이해하지 못해 <strong>하루 가까이 고민</strong>을 했다</li>
<li>개발 계획을 <strong>사전에 공유하지 않고</strong> 진행했다가, <strong>결국 처음부터 다시 시작</strong>했다</li>
<li>다른 사람의 코드를 이해하기 어려워 <strong>코드리뷰에 적극적으로 참여할 수 없었다</strong></li>
<li>혼자 처리해야하는 업무라고 생각해서 다른 파트에 필요한 <strong>협업 요청을 하는 것을 어려워했다</strong></li>
</ul>
<h3 id="now">Now</h3>
<ul>
<li>Task를 정리할 때 <span style="background-color:#E6E6FA"><strong>적절한 카테고리 분류</strong></span>를 통해 <span style="background-color:#E6E6FA"><strong>누구나 쉽게 읽을 수 있는 글</strong></span>로 작성한다</li>
<li>주어진 <span style="background-color:#E6E6FA"><strong>업무에 대해 파악하는 시간이 빨라졌다</strong></span> (시간이 너무 오래 걸린다 싶으면 바로 질문한다)</li>
<li>개발 계획을 <span style="background-color:#E6E6FA"><strong>Flow로 미리 정리</strong></span>해보고, <span style="background-color:#E6E6FA"><strong>1회 이상 피드백을 받은 다음</strong></span> 개발을 시작한다</li>
<li>다른 사람의 코드를 충분히 이해하고, <span style="background-color:#E6E6FA"><strong>코드리뷰에 적극적으로 참여</strong></span>하며 다양하게 고민해본다</li>
<li>파트별로 담당하는 업무의 카테고리에 대해 이해하고, <span style="background-color:#E6E6FA"><strong>필요에 따라 적절하게 협업 요청</strong></span>을 한다</li>
</ul>
<hr>
<p>현재와 같이 변화하기까지 혼자 나름대로의 많은 시간과 노력이 필요했다.
퇴근하고도 이슈를 해결하기 위해 어떻게 개발해야할지 고민하거나
회사에서 작성해둔 업무 Task를 다시 읽어보며 효과적으로 글을 작성하는 방법에 대해서도 고민했다.</p>
<p>스스로 고군분투하며 많은 산을 넘은 것도 있지만, 1년차가 되는 시점에서 다시 돌아보니
<strong>내가 성장할 수 있게 뒤에서 잘 받쳐준 <span style="background-color:#fff5b1">우리 팀 덕분도 크다</span>고 생각</strong>이 들었다.</p>
<p>그래서 1년 간의 회사 생활을 돌아보며 이번 포스팅을 작성하게 되었다.
<span style="background-color:#fff5b1"><strong>주니어가 잘 성장할 수 있는 근무 환경의 조건에는 무엇이 있을까?</strong></span></p>
<p>물론 개인마다 생각하는 기준은 다르겠지만, 내 의견을 한 스푼 담아 작성해보려고 한다.</p>
<hr>
<h2 id="고민을-모두에게-알리자-🔊">고민을 모두에게 알리자 🔊</h2>
<p>입사 초, 일하면서 <em>&#39;지금 이 질문을 해도 되는걸까?&#39;</em> 라는 고민이 나를 가장 힘들게 했다.
만약 누군가에게 물어봤다면 빠르게 해결할 수 있었을 문제인데,</p>
<p>_&quot;제대로 알아보지도 않고, 혹은 제대로 고민해보지도 않고 일단 물어보는 것처럼 보일 수 있지 않을까?&quot; _
하는 생각 때문에 선뜻 질문하지 못했다.</p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/c8e0fb33-78f0-4d45-8c43-1e7288d709c4/image.png" alt=""></p>
<p>알고보니 나 뿐만 아니라 파트 전반적으로 혼자서 최대한 해결해봐야하지 않을까 하며 오랜 시간 고민하는 분위기였다. 보다못한 팀장님께서(🤣) 파트 채팅방에 &quot;고민 3시간 이상 금지!&quot; 라는 공지를 올리셨다.</p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/26f7869f-a514-49f7-97bb-fd7bc903c501/image.png" alt=""></p>
<p>물론 혼자서 생각하는 시간도 필요하지만
그게 너무 길어지면 다같이 고민해보는 것이 더 좋은 방향으로 나아갈 수 있다는 입장이셨다</p>
<p>팀장님께서 먼저 이렇게 고민은 적극적으로 공유하자고 언급해주시니
모두가 SOS를 좀더 적극적으로 요청하는 분위기로 변화하게 되었다👍</p>
<hr>
<h2 id="사수의-중요성-🧚♂️">사수의 중요성 🧚‍♂️</h2>
<p>우리 파트는 보통 <strong>1 Task에 대하여 1명의 개발 담당자가 지정</strong>된다</p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/1e55b3a3-dc9a-4725-93d8-ccac0272151d/image.png" alt=""></p>
<p>우리 파트 모두가 같은 서비스를 담당하고 있지만, 각자 진행하는 테스크는 다르기 때문에 아무래도 본인의 개발 건에 대해 다른 사람에게 물어보는 것이 쉽지는 않다. 테스크에 대해 처음부터 설명을 하고 질문을 해야하다보니 상대방의 시간을 많이 뺏는다고 생각이 들면 한없이 미안해지기 때문에..</p>
<p>특히 주니어에게는 딜레마가 자주 발생한다 🥺</p>
<pre><code>혼자서는 도저히 답이 안 나올 것 같은데
그렇다고 질문하기는 어렵고
그렇다고 혼자서 해결하려니 막연하게 시간만 흐르고...</code></pre><p>이와 같은 무한 굴레에 빠져버리게 된다.
<strong>내가 이러한 딜레마에서 빠르게 벗어날 수 있었던 가장 큰 이유는 &#39;사수&#39;의 존재</strong>였다.</p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/97910bf5-8fcd-4146-b5ef-8b0743d7b611/image.png" alt=""></p>
<p>우리 파트는 <strong>사수-부사수</strong>로 매칭되어있다. 
매칭의 기준은 파트장님의 판단이며 <strong>현재는 사수(대리, 과장)-부사수(사원)으로 구성</strong>되어 있다.
<span style="color:gray">(아마 사수-부사수 문화가 생긴 것이 혼자서 끙끙거리는 시간이 길어지는 것을 방지하기 위한 하나의 해결책이 아니었을까?)</span></p>
<p>파트 전반적으로 <strong>&#39;잘 도와주는 것&#39;에 대해 긍정적으로 바라보고 있기</strong>에
사수님들은 질문을 받을 때마다 적극적으로 도움의 손길을 내밀어주신다.
그리고 <strong>부사수의 입장에서는 언제든지 편하게 고민을 물어볼 수 있는 사람이 있다는 점에서 심적 부담감이 많이 줄어든다.</strong></p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/1b3adfde-2423-448c-864c-6de8daebd13d/image.png" alt=""></p>
<p>현재 사수님은 스스로 한번 고민해볼만한 내용에 대해서는 과제 느낌으로 던져주시기도 한다📝 
좋은 방향으로 성장할 수 있도록 잘 이끌어주셔서 항상 감사하다
그래도 너-무 시간을 뺏는 상황은 생기지 않도록 항상 주의하고 있다🧐</p>
<hr>
<h2 id="아는-만큼-도와주기-👌">아는 만큼 도와주기 👌</h2>
<p>입사 초 나는 정말 많은 사람들에게 도움을 받았고, 덕분에 회사에 잘 적응할 수 있었다
그래서인지 <strong>나도 누군가에게 잘 베풀고 좋은 방향으로 이끌어줄 수 있는 사람이 되어야겠다</strong>는 생각을 항상 가지고 있다</p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/2a6cd83f-226d-4ac1-b726-d08a1f9e2c4b/image.png" alt=""></p>
<p>최근에는 우리 파트에 신규 입사자로 4명 정도 들어왔는데 신규 입사자 가이드 작성을 내가 맡기도 했고, 
편하게 질문하실 수 있도록 말씀을 드렸는데 그 효과가 있었던 것 같다</p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/216b6f46-d9e8-483d-9593-0e4ef5713afb/image.png" alt=""></p>
<p><span style="color:gray">(캡쳐 모음을 보니 왜 넴넴봇처럼 보이지.. 그렇지만 그때그때 진심으로 답변을 한건 사실이에여..)</span></p>
<p><strong>서로 적극적으로 도와주는 분위기를 만들기 위해 나부터 실천해야 한다는 생각</strong>도 있어서
아는 만큼 열심히 도와드렸고, 신규로 오신 분들도 자연스럽게 이런 분위기에 적응하신 것 같아 
<strong>나중에 팀 내 협업 시 더 좋은 시너지가 나지 않을까 생각한다</strong>🥳</p>
<p>사실 도와주는게 상대방에게만 실력+1이 되는 것은 아니다
나도 한번더 찾아보고 고민해보며 공부하는 시간을 갖게 되는 경우도 있어서
질문자도, 답변자도 모두 배워가는 순간들이 쌓여나가는 것 같다 ✏️</p>
<hr>
<h2 id="주기적인-기술-공유-시간-👏">주기적인 기술 공유 시간 👏</h2>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/8d480fd8-ff89-4cc1-a3f2-270b332f386f/image.png" alt=""></p>
<p>우리 회사 개발실의 전체 인원은 약 100명 정도이며 여러 파트로 구성되어 있다. 
<span style="color:gray">(프론트, 백엔드, 모바일, 데봅스, 데이터운영, 보안 등) </span>
파트에 상관없이 <strong>기술 공유로 다룰만한 좋은 주제들은 수요일 오후 2시마다 온라인 상으로 발표</strong>를 한다.</p>
<p>Kafka, Vault, MySQL 버전업 등 다양한 주제가 있었는데
실제로 내가 작업한 적은 없지만 이런 것들도 있구나~하고 <strong>미리 배경지식으로 쌓아두기 좋은 것 같다</strong>
더불어 개발실에서 요즘 <strong>어떤 포인트를 트렌드로 잡고 작업을 하는 지도 알기 쉽다</strong>
<span style="color:gray">나는 Kafka에 대한 강의를 조만간 들어볼까 생각 중이다 !</span></p>
<p>이런 기술 공유 시간은 발표를 하는 사람도, 발표를 듣는 사람에게도 
모두 도움이 되는 좋은 시간이 아닐까 싶다</p>
<hr>
<h2 id="좋은-건-다같이-알고-넘어가자-😲">좋은 건 다같이 알고 넘어가자 😲</h2>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/b6f1a2e2-eb37-4883-b738-ce184aa8bca9/image.png" alt=""></p>
<p>카카오, 네이버, NHN, 인프런 등 개발자 컨퍼런스 참가신청을 받는 기간에는
팀장님께서 항상 개발자 단체 메신저 방에 관련 링크를 공유해주신다</p>
<p>다양한 컨퍼런스에 참여하여 <strong>시야를 넓히는 것이 중요하다고 생각</strong>하시는 것 같아
개발실 사람들은 <strong>가고 싶은 컨퍼런스가 있으면 부담없이 다녀오는 편</strong>이다</p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/0b6b6d94-8b43-4a79-bd23-61351f7bb9db/image.png" alt=""></p>
<p>실제로 나와 우리 파트 중 일부는 작년에 NHN컨퍼런스, 올해에 네이버 데뷰에 다녀왔다.
가서 리프레시도 하고, 다녀와서 좋았던 점은 서로 공유도 하곤 했다</p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/58dbf7da-75d9-4309-b72c-e5ce8f789809/image.png" alt=""></p>
<p>행사 뿐만 아니라, 한번씩 보면 좋을 개발 관련 영상들도 단체방에 올라온다
<span style="color:gray">(영상 보고 후기 남겨야하는 그런 분위기 아니고 그냥 툭툭-올라오곤 합니다 ㅎㅎ)</span></p>
<p>가끔 업무가 붕 떠서 여유롭거나 출퇴근길에 하나씩 봐도 시간이 잘 가서
나는 이렇게 공유해주시는 영상이나 기술블로그 포스팅들이 넘넘 좋다🤗</p>
<p>말로 어렵게 설명하는 것보다, 
<strong>잘 정리된 영상으로 공유하고 싶은 내용을 알리는 것도 좋은 방법</strong>인 것 같다</p>
<hr>
<h2 id="피드백은-구체적으로-🧐">피드백은 구체적으로 🧐</h2>
<p>입사 초, <strong>Task 작성에 대해서 정말 많은 피드백을 받았다.</strong></p>
<p>나는 나름대로 내가 고민했던 내용들을 자세히 녹여내는 것이 좋겠다고 생각했는데
추후에 그 테스크를 봐야하는 사람들에게는 너무 구구절절하게 작성된 글이었을 뿐이었다.
아니면 오히려 너무 내용을 덜어내서 필요한 내용이 제대로 적혀있지 않은 경우도 있었다.</p>
<pre><code>&#39;너무 읽기 힘들어요&#39;
&#39;좀 더 쉽게 써주세요&#39;
&#39;업무 글은 이렇게 쓰면 안돼요. 다시 써주세요.&#39;</code></pre><p>글 작성은 개인의 주관이 많이 반영되는 작업인 만큼
글에 대한 평가도 위와 같이 추상적으로 될 수 있는데</p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/97103509-4c62-4402-9e84-f9342a0e2722/image.png" alt=""></p>
<p>파트장님께서는 <strong>항상 피드백을 구체적으로 주셨고</strong>
덕분에 <strong>내 글쓰기의 문제점을 좀더 빠르게 파악할 수 있었다.</strong>
만약 주변에서 조언을 주지 않았다면, 나는 아직까지도 불친절한 글쓰기를 반복하고 있었을 것 같다.</p>
<p>요즘은 Task 작성 시 항상 <strong>카테고리를 활용</strong>한다.</p>
<table>
<thead>
<tr>
<th align="left">유지보수 Task</th>
<th align="left">신규 기능 개발 Task</th>
</tr>
</thead>
<tbody><tr>
<td align="left">이슈 <br> - Task 등록하게 된 배경 간단 요약</td>
<td align="left">이슈 <br> - Task 등록하게 된 배경 간단 요약</td>
</tr>
<tr>
<td align="left">원인/분석 <br> - 이슈가 발생한 원인 <br> - 원인을 찾기까지의 분석 과정</td>
<td align="left">계획 (Flow) <br> -  개발 계획에 대한 Flow 이미지 첨부 <br> - 그외 개발 순서, 협업 요청 계획 등</td>
</tr>
<tr>
<td align="left">해결 <br> - 문제 해결 방법 <br> - 관련 건 PR 링크 및 브랜치명</td>
<td align="left">작업 <br> - 관련 건 PR 링크 및 브랜치명</td>
</tr>
</tbody></table>
<p>위 카테고리에 맞춰 작성하니 나도 좀더 글을 깔끔하게 쓸 수 있게 되었고
테스크를 공유할 때도, 읽는 사람이 부담없이 보는 것 같았다.</p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/95c19058-c7a9-4eb9-8e1d-4e3e33ad5634/image.png" alt=""></p>
<p>요즘은 피드백을 요청할 때마다 긍정적인 답변을 자주 받고 있어서
이전에 비해 많이 성장했구나를 느끼고 있다🥰</p>
<hr>
<h2 id="적극적인-코드-리뷰-📝">적극적인 코드 리뷰 📝</h2>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/00536428-f6c9-4fe1-ab53-9a56f0cac542/image.png" alt=""></p>
<p>코드 리뷰는 특히 주니어 개발자에게 정말 도움이 많이 된다.
리뷰를 받는 것도, 리뷰에 참여하는 것도!</p>
<p>1년 간 코드 리뷰를 통해 얻을 수 있는 장점은 크게 5가지였다</p>
<ul>
<li><strong>commit에 작업 내역을 적절하게 반영</strong>시키기</li>
<li><strong>branch 관리</strong>하는 방법 배우기</li>
<li>내 코드에 불편한 점은 없을까?에 대해 계속 되짚어보기</li>
<li><strong>더 나은 네이밍, 더 나은 구조</strong>에 대해 생각하고 찾아보기 
<span style="color:gray">(더 나아가 디자인패턴까지 찾아볼 수 있다)</span></li>
<li>코드에 대한 <strong>의견을 교환하는 커뮤니케이션 능력 키우기</strong></li>
</ul>
<p>우리 파트는 <strong>매일 오전에는 전날에 올라온 PR을 보며 코드리뷰를 적극적으로 하기로 약속</strong>했다
갑자기 이슈가 터지거나 장애가 발생하는 등 다들 바쁠 때는 코드 리뷰를 하지 못하는 경우도 있지만 ㅠㅠ
그래도 사수-부사수의 PR은 서로 꼭 확인해주고자 하는 분위기라 최소 1명 이상의 approve는 받고 있어서 괜찮다 ㅎㅎ 그리고 나는 PR 올라오면 꼭 확인하는 편이라, <strong>다른 사람의 코드를 이해하는 실력이 많이 좋아졌다</strong>👍</p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/567ff778-6142-4648-a6c0-44b7cdf177f1/image.png" alt=""></p>
<p>리뷰를 남겨주고 나서, 이렇게 메신저를 받을 때면 너무 뿌듯하구 ㅜ
<strong>코드 리뷰만큼은 단점 없는 좋은 문화인 것 같다</strong> 😎</p>
<hr>
<h2 id="달달한-커피타임-☕️">달달한 커피타임 ☕️</h2>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/b1b6f850-3749-43dd-8145-c9857e440eba/image.png" alt=""></p>
<p>파트장님, 팀장님께서 2-3달에 1번씩 커피타임을 하자고 메신저를 보내주신다
첫 커피타임을 가질 때는 긴장했는데, 이제는 마음 편하게 수다를 떨고 오는 시간이라고 생각해서 좋아졌다</p>
<p><strong>진짜 스몰토크를 하는 경우도 있고,
중간중간 힘든 점이나 구성원으로써 개선점에 대해 내고 싶은 의견이 있는지 물어봐주시는데
항상 파트의 이야기에 귀기울여주고 신경써준다는 느낌이 들어서 좋았다</strong>👂</p>
<p>신기했던 점은, 분명 리더로서 힘든 점들도 있으실텐데
항상 조직원들 앞에서 그런 내색 없이 오히려 잘 업무를 해낼 수 있도록 서포트를 하는 모습을 보여주셔서
리더로서 어떻게 행동해야 파트원들에게 긍정적인 영향을 줄 수 있는지 속으로 많이 배웠다</p>
<p><strong>고민 많은 주니어 개발자들에게 달달한 커피타임은 
생각 정리에 큰 도움이 되는 좋은 시간인 것 같다</strong></p>
<hr>
<h2 id="마무리하며">마무리하며</h2>
<p>1년 동안 느낀 점들을 쭉 작성해보았는데,
나는 정말 운이 좋게도 좋은 조직에서 잘 배우고 성장하고 있는 사람인 것 같다</p>
<p>앞으로도 기운 내서 더 잘해봐야지! ❤️</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[주니어 개발자의 현업에서 배운 Git Flow]]></title>
            <link>https://velog.io/@myoungji-kim/git-flow</link>
            <guid>https://velog.io/@myoungji-kim/git-flow</guid>
            <pubDate>Fri, 21 Jul 2023 14:49:39 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>⏰ <strong>읽는 시간: 10분</strong></p>
</blockquote>
<h2 id="들어가기-전">들어가기 전</h2>
<p>회사에 들어오기 전, 나는 Git을 거의 몰랐다
git commit, git push 등 간단한 작업만 알고 있었고 이마저도 IDE에서 지원하는 GUI를 활용해왔다.
내가 들어온 파트에서는 적극적으로 Git Flow 전략을 사용하고 있었고
회사 서비스 소스코드에 적응하는 것과 동시에 Git에 대해 파악하느라 꽤 고생했던 기억이 있다.</p>
<p>지금은 기본적으로 필요한 Git 작업들은 충분히 숙지되어있고
<strong>커밋 충돌이나 rebase 작업 등이 필요한 상황에서 어려워하는 파트원들에게 먼저 다가가 도움을 주곤 한다</strong></p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/cb9f5bb0-1c33-4247-9868-7ff986bfb13a/image.png" alt=""></p>
<p>😎😎😎
1년 간 열심히 공부하고 배운 만큼, 이번 기회에 필수적인 내용에 대해 정리해보고자 한다</p>
<p>(+ 본 포스팅은 하이라이팅이 많이 첨부되어 있습니다. <span style="color:red"><strong>다크모드 대신 라이트모드로 읽는 것을 권장드립니다.</strong></span>)</p>
<hr>
<h2 id="파트에서-사용하는-git-flow">파트에서 사용하는 Git Flow</h2>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/0f857cab-2474-4b33-872f-573742c0e9b1/image.png" alt=""></p>
<p>출처: <a href="https://blog.jetbrains.com/space/2023/04/18/space-git-flow/">https://blog.jetbrains.com/space/2023/04/18/space-git-flow/</a></p>
<h4 id="branch별-역할-사내-기준">Branch별 역할 (사내 기준)</h4>
<ul>
<li><strong><span style="background-color:#C0FFFF">main</span></strong>
실제 운영에 반영되어 있는 소스 코드들이 있는 브랜치</li>
<li><strong><span style="background-color:#DCFFE4">release</span></strong>
베타 배포 및 베타 QA를 위한 브랜치
<span style="background-color:#C0FFFF">main</span> 배포 예정인 <span style="background-color:#E6E6FA">feature</span> 브랜치들을 <span style="background-color:#DCFFE4">release</span>에 취합한 후,
Real 배포 전에 <span style="background-color:#DCFFE4">release</span>-&gt;<span style="background-color:#C0FFFF">main</span>으로 merge 한다</li>
<li><strong><span style="background-color:#fff5b1">develop</span></strong>
알파 배포 및 알파 QA를 위한 브랜치
<span style="background-color:#E6E6FA">feature</span> 브랜치 개발이 완료되어 알파QA를 원할 경우, 
배포 일정과 관계 없이 바로 <span style="background-color:#fff5b1">develop</span> 브랜치에 적용하여 알파 환경에서 테스트를 진행한다</li>
<li><strong><span style="background-color:#E6E6FA">feature</span></strong>
기능 개발을 진행하는 브랜치
우리 파트에서는 <span style="background-color:#C0FFFF">main</span> 브랜치를 기준으로 <span style="background-color:#E6E6FA">feature</span> 브랜치를 생성했다
(<span style="background-color:#E6E6FA">feature</span> 브랜치의 시작 브랜치는 상황에 따라 전략을 다르게 가져갈 수 있을 것 같다)</li>
<li><strong><span style="background-color:#FFE6E6">hotfix</span></strong>
main 배포 후 급하게 수정해야할 경우 생성되는 브랜치 </li>
</ul>
<hr>
<h2 id="git-flow를-따라-작업해보자">Git Flow를 따라 작업해보자</h2>
<h3 id="github에-이슈업하기">Github에 이슈업하기</h3>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/518ccec5-adad-4ef1-84f1-aece167c0dbe/image.png" alt=""></p>
<p>먼저 개발하고자 하는 테스크에 대한 이슈를 github에서 등록한다</p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/eb9aac68-9e5c-487f-9aa7-4bc1976b32ae/image.png" alt=""></p>
<p>이슈 생성 후 확인 가능한 이슈번호가 feature 브랜치 번호의 기준이 된다.
(ex. <code>feature/#26</code>)</p>
<h3 id="local의-span-stylebackground-colorc0ffffmainspan-브랜치-최신화하기">local의 <span style="background-color:#C0FFFF">main</span> 브랜치 최신화하기</h3>
<pre><code class="language-bash">$ git switch main
$ (main) git fetch
$ (main) git pull origin main</code></pre>
<p><code>git log</code>로 <code>local main</code>의 최신 커밋이 <span style="background-color:#C0FFFF">origin main</span>의 최신 커밋과 동일한지 체크해주자</p>
<h3 id="span-stylebackground-colore6e6fa부모-featurespan-브랜치-생성하기"><span style="background-color:#E6E6FA">부모 feature</span> 브랜치 생성하기</h3>
<p>이슈 번호는 10으로 가정하고 진행하겠다</p>
<pre><code class="language-bash">$ (main) git switch -c feature/10
$ (feature/10) git push origin feature/10</code></pre>
<h3 id="span-stylebackground-colore6d0ff자식-featurespan-브랜치-생성하기"><span style="background-color:#E6D0FF">자식 feature</span> 브랜치 생성하기</h3>
<pre><code class="language-bash">$ (feature/10) git switch -c feature/10-1
$ (feature/10-1)</code></pre>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/6bc843ad-eb06-48cb-bb2e-f339c56fe0c8/image.png" alt=""></p>
<p>우리 파트의 경우 <span style="background-color:#E6D0FF">자식 feature</span> -&gt; <span style="background-color:#E6E6FA">부모 feature</span>로 merge하는 pr을 올리는 시점에 코드리뷰를 진행했다
즉, <strong><span style="background-color:#E6E6FA">부모 feature</span> 브랜치는 해당 기능 개발건이 완벽하게 되어있다는 보장</strong>이 되도록 방향을 잡았다</p>
<h3 id="개발-진행">개발 진행</h3>
<p>이제 <span style="background-color:#E6D0FF">자식 feature</span> 브랜치에서 자유롭게 개발을 진행한다
파트에서 commit 명에 대한 세세한 규칙은 아직 정하지 않았지만
최근 유지보수를 하다보니 커밋만으로 이슈와 PR을 찾기가 어려워 히스토리 추적이 오래 걸렸던 적이 있었다.
그래서 방법을 고민하다가 <strong>커밋명 앞에 이슈번호를 붙여주는 방법</strong>을 선택했다.
<span style="color:gray">(혼자서만 도입한 방법이라 슬금슬금 파트에 커밋 네이밍 룰을 전파해볼 생각이다)</span></p>
<h4 id="as-is">AS-IS</h4>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/363c52b1-4224-4723-950d-df19a774468f/image.png" alt=""></p>
<h4 id="to-be">TO-BE</h4>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/8de0ba01-36ff-4e1a-bdd2-b4f8ba38a2b3/image.png" alt=""></p>
<h4 id="to-to-be-0728업데이트">TO-TO-BE (07.28.업데이트)</h4>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/d8a29c64-898c-4ff3-91ec-bd5e5532e0bc/image.png" alt=""></p>
<p>최근에 새로 알게 된 사실..
rebase 작업 후 터미널에서 커밋 메시지 정리하고 마치려는데</p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/f27ed850-347c-4a27-af03-cff63f65b681/image.png" alt=""></p>
<p>커밋 맨 앞에 붙은 <code>#</code>으로 인해 해당 라인이 전체 주석 처리가 되어버린 이슈가 있었다</p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/6c577862-cf2f-461b-8198-5b5313c1b8fd/image.png" alt=""></p>
<p>그래서 현재는 <code>[#이슈번호] 커밋메시지</code> 패턴으로 작업하고 있다.</p>
<hr>
<p>개발을 진행하다 <span style="background-color:#C0FFFF">main</span> 브랜치가 최신화되는 경우가 있을 수 있다
추후 conflict을 방지하기 위해 상시로 <span style="background-color:#E6E6FA">feature</span> 브랜치를 최신화해주어야 한다</p>
<pre><code class="language-bash">$ (feature/10-1) git switch feature/10
$ (feature/10) git pull (origin) main --rebase
$ (feature/10) git push origin +feature/10</code></pre>
<p><span style="background-color:#E6E6FA">부모 feature</span> 브랜치를 무시하고 <span style="background-color:#E6D0FF">자식 feature</span> 브랜치에서만 <span style="background-color:#C0FFFF">main</span>을 pull rebase 받아오면 안된다
왜냐하면 <code>main -&gt; feature/10 -&gt; feature/10-1</code> 순서로 브랜치를 따왔기 때문에 이 순서를 지켜주어야 한다 !</p>
<p>이때 rebase 옵션을 주는 이유는 <code>feature 브랜치에서 추가된 커밋이 항상 HEAD에 올 수 있도록</code> 하기 위해서다. 작업 시간대별로 commit 순서가 정렬되면 추후 커밋 리스트 보기가 힘들어진다.</p>
<p>최신화가 완료된 <span style="background-color:#E6E6FA">부모 feature</span> 브랜치를 origin에 push할 때는 경우에 따라 force push가 필요할 수 있다(<code>+</code>)
<del>사실 나는 귀찮아서 항상 붙여주긴 한다..</del></p>
<pre><code class="language-bash">$ (feature/10) git switch feature/10-1
$ (feature/10-1) git pull (origin) feature/10</code></pre>
<p>이제 <span style="background-color:#E6D0FF">자식 feature</span> 브랜치까지 최신화 완료! 이어서 개발을 진행하자</p>
<h3 id="origin에-리뷰-받을-pr-생성하기">Origin에 리뷰 받을 PR 생성하기</h3>
<pre><code class="language-bash">$ (feature/10-1) git push origin feature/10-1</code></pre>
<p>이제 개발이 완료되었다면 origin에 올려주자</p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/826e94c3-4b6e-4b65-8ae1-a6b8f45e2d31/image.png" alt=""></p>
<p>우리 파트의 경우, 개발 PR과 연관된 테스크를 dooray에서 따로 작성하고 있어서 두레이 링크를 함께 첨부해두고, PR 작업 내역에 대해 간단히 소개한다</p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/f17e5dbb-a696-4981-ae8f-1843638b7af0/image.png" alt=""></p>
<p>그리고 이어지는 활발한 코드리뷰! 🥳
PR에서 코멘트로 티키타카를 주고 받기 부족하면 <code>메신저로도 열띤 토론을 펼치곤</code> 한다</p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/e78ffc76-5de1-4271-8fef-b14f290a1288/image.png" alt=""></p>
<p>우리 파트는 누군가의 코드에 대해 다같이 열심히 고민해주는 분위기라 다같이 성장하기 좋은 것 같다 👍</p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/58d29eb3-137a-4c88-90cf-618e556a98ab/image.png" alt=""></p>
<p>리뷰어의 피드백을 반영하여 소스코드가 수정될 경우,
<code>수정했는데 의도하신 피드백 방향에 맞을까요? 한번 확인해주세요!</code>라는 의미를 담아 한번더 리뷰어를 멘션걸어 커밋 번호와 함께 답글을 남긴다.</p>
<p>만약 리뷰어가 수정한 커밋에 대해 만족한다면, 👍을 남겨주고 해당 대화는 resolve 처리를 한다.</p>
<h3 id="span-stylebackground-colore6e6fafeaturespan-브랜치에서는-force-push도-괜찮다"><span style="background-color:#E6E6FA">feature</span> 브랜치에서는 force push도 괜찮다</h3>
<pre><code class="language-bash">$ (feature/10-1) git rebase -i abcdef^
-&gt; 터미널에 보여지는 commit 목록 중 수정하고자 하는 커밋의 pick을 edit로 변경
-&gt; 소스코드 수정 후, 수정한 파일을 git add 하고
-&gt; git rebase --continue로 작업 마무리</code></pre>
<p>만일 이미 origin에 올라간 커밋이라고 해도
<span style="background-color:#E6E6FA">feature</span> 브랜치, 즉 개인 브랜치의 영역에서는 force push를 허용하기로 했기 때문에 rebase를 자유롭게 활용하고 있다.</p>
<p>물론 <code>코드리뷰에 대한 피드백을 rebase로 처리</code>하게 되면 
<code>리뷰어가 수정 내역만 보기 어렵다는 단점이 존재</code>하긴 하지만.. 
이건 파트에서 룰을 세부적으로 정해나가야할 것 같다</p>
<h3 id="merge-pull-request">Merge Pull Request</h3>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/5e65eeab-0a63-4380-8bfc-8d231dba0bf5/image.png" alt=""></p>
<p>코드 리뷰에 참여한 사람들의 approve가 확인되면 이제 <span style="background-color:#E6E6FA">부모 feature</span> 브랜치로의 Merge를 진행한다
우리 파트는 merge branch가 생기는걸 방지하기 위해 <code>Rebase and merge</code> 옵션을 선택하고 있다</p>
<blockquote>
<p>merge 옵션별 설명은 <a href="https://im-developer.tistory.com/182">https://im-developer.tistory.com/182</a> 포스팅에서 너무 설명이 잘 되어 있다</p>
</blockquote>
<h3 id="span-stylebackground-colore6e6fafeaturespan---span-stylebackground-colorfff5b1developspan"><span style="background-color:#E6E6FA">feature</span> -&gt; <span style="background-color:#fff5b1">develop</span></h3>
<p><span style="background-color:#E6E6FA">feature</span> 개발이 완료되었다면 alpha QA를 위해 <span style="background-color:#fff5b1">develop</span>에 <span style="background-color:#E6E6FA">feature</span> 브랜치를 merge 한다.
알파 QA 과정에서 결함 건이 발견되었다면 다시 <span style="background-color:#E6D0FF">자식 feature</span> 브랜치를 생성하여 작업을 반복한다.</p>
<h3 id="span-stylebackground-colore6e6fafeaturespan---span-stylebackground-colordcffe4releasespan"><span style="background-color:#E6E6FA">feature</span> -&gt; <span style="background-color:#DCFFE4">release</span></h3>
<p>알파 QA가 끝나고 배포 일정이 정해졌다면, 배포 전 베타 QA 기간에 맞춰 <span style="background-color:#DCFFE4">release</span>에 <span style="background-color:#E6E6FA">feature</span> 브랜치를 merge 한다. 베타 QA 과정에서 결함 건이 발견되었다면 다시 <span style="background-color:#E6D0FF">자식 feature</span> 브랜치를 생성하여 작업을 반복한다.</p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/86ea1c9c-d410-4dbe-956c-51231c68ebb3/image.png" alt=""></p>
<p>우리 파트에서는 정해진 배포 일에 여러 <span style="background-color:#E6E6FA">feature</span> 개발건이 배포가 나갈 경우,
<code>release에 배포나갈 feature 브랜치들을 취합한다</code>고 표현하고 있다.</p>
<h3 id="span-stylebackground-colordcffe4releasespan---span-stylebackground-colorc0ffffmainspan"><span style="background-color:#DCFFE4">release</span> -&gt; <span style="background-color:#C0FFFF">main</span></h3>
<p><span style="background-color:#DCFFE4">release</span>-&gt;<span style="background-color:#C0FFFF">main</span>으로 merge 하기 전, <span style="background-color:#DCFFE4">release</span> 브랜치는 베타 QA 후 결함건 수정까지 완료되어있는 상태다.
실제 배포일에 <span style="background-color:#DCFFE4">release</span> 브랜치를 <span style="background-color:#C0FFFF">main</span>으로 merge하고 <span style="background-color:#C0FFFF">main</span> 브랜치를 기준으로 운영 환경에 배포를 진행한다.</p>
<h3 id="span-stylebackground-colorffe6e6hotfixspan"><span style="background-color:#FFE6E6">hotfix</span></h3>
<pre><code class="language-bash">$ (main) git switch -c hotfix/10</code></pre>
<p>만일 <span style="background-color:#C0FFFF">main</span> 배포 후, 급한 수정건이 발생할 경우 <span style="background-color:#C0FFFF">main</span> 브랜치를 기준으로 <span style="background-color:#FFE6E6">hotfix</span> 브랜치를 생성하여 빠르게 수정 작업을 진행한다. <del>hotfix를 만드는 사람이 내가 아니길 항상 빌고 있다.</del>
<img src="https://velog.velcdn.com/images/myoungji-kim/post/cb9edc44-5eb1-4c6a-9add-05d39a109a47/image.png" alt=""></p>
<p><span style="background-color:#FFE6E6">hotfix</span> 브랜치 작업이 완료되면 다시 <span style="background-color:#FFE6E6">hotfix</span>-&gt;<span style="background-color:#C0FFFF">main</span>으로 merge 하여 <span style="background-color:#C0FFFF">main</span> 브랜치를 기준으로 배포한다</p>
<h3 id="span-stylebackground-colorc0ffffmainspan-배포-후에는-꼭-브랜치-최신화를"><span style="background-color:#C0FFFF">main</span> 배포 후에는 꼭 브랜치 최신화를!</h3>
<p><span style="background-color:#C0FFFF">main</span> 배포 후에는 <span style="background-color:#fff5b1">develop</span>과 <span style="background-color:#DCFFE4">release</span> 브랜치가 <span style="background-color:#C0FFFF">main</span>에 있는 커밋을 모두 가질 수 있도록 최신화를 진행해야한다. 종종 배포 담당자가 이를 놓치게 되는 경우가 있는데, 최신화가 적절한 시점에 되어 있지 않으면 추후 conflict이 발생할 가능성이 높고 공용 브랜치다보니 빠르게 원인을 찾아 바로 해결하기 어려운 경우가 발생한다. 
<img src="https://velog.velcdn.com/images/myoungji-kim/post/432af3be-a8aa-410a-b6d5-f28a840a0a28/image.png" alt=""></p>
<p><span style="background-color:#fff5b1">develop</span> 브랜치가 복구가 어려울 정도로 꼬여있으면 브랜치 삭제 후, <span style="background-color:#C0FFFF">main</span> 기준으로 다시 <span style="background-color:#fff5b1">develop</span> 브랜치를 생성해야 한다. 이럴 경우 <span style="background-color:#fff5b1">develop</span> 브랜치에만 알파QA 할 <span style="background-color:#E6E6FA">feature</span> 브랜치를 merge 해둔 개발 담당자들은 이 작업을 1번더 해야 하기 때문에 번거로운 상황이 온다 🥺
꼭 브랜치 최신화는 바로바로 챙겨주자!</p>
<hr>
<h2 id="정리하며">정리하며</h2>
<p>여기까지 파트에서 사용하고 있는 Git Flow 전략을 좀더 상세하게 정리해보았다
git 백지 상태에서 1년 동안 열심히 공부해서 여기까지 성장할 수 있어서 다행이라는 생각이 든다
이제 정말 Git이 왜 편한지 알게 되었다!
그리고.. rebase가 무섭지 않게 될 때, 정말 열심히 공부했구나를 느꼈다😎</p>
<p>머릿속에만 그려두고 있다가 처음으로 글로 정리해보았는데
우리 파트의 git flow 전략에 많이 적응되어 있어서 
refresh를 위해 다른 git 전략도 찾아보며 다양하게 알아두어야겠다는 생각이 문득 들었다 :)</p>
<p>오늘의 포스팅은 여기까지!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[사내 E2E 테스트 도입 경험기 #3 - 배포 프로세스에 E2E 테스트 추가하기]]></title>
            <link>https://velog.io/@myoungji-kim/e2e-deploy</link>
            <guid>https://velog.io/@myoungji-kim/e2e-deploy</guid>
            <pubDate>Sun, 30 Apr 2023 05:34:49 GMT</pubDate>
            <description><![CDATA[<h2 id="첫-계획은-단순했다">첫 계획은 단순했다</h2>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/d39a58a1-fe55-4a84-9fdf-e965da72c269/image.png" alt=""></p>
<p>E2E 테스트 프로젝트를 처음 맡고 나서 생각했던 플로우는 단지 이것 뿐이었다.</p>
<hr>
<h2 id="단순히-생각할-프로세스가-아니였다">단순히 생각할 프로세스가 아니였다</h2>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/be36888c-c05c-48d2-a899-7312b15dc5c2/image.png" alt=""></p>
<p>결과적으로 현재 구성된 프로세스는 위와 같다. 
<span style="color:#2D3748; background-color:#fff5b1">혼자서 저 결과를 이끌어내기까지 정말 많은 고민과 갈아엎음이 필요</span>했다..🫠
위 프로세스는 알파 배포를 기준으로 작성한 플로우다.</p>
<p>글로 아무리 친절하게 설명하는 것보다, 
<strong>깔끔한 플로우 그림 하나가 더 완벽한 설명</strong>이 될 것 같아
구구절절한 설명은 생략하려고 한다.</p>
<hr>
<h3 id="deploy">DEPLOY</h3>
<p>E2E 테스트 실행 전에 가장 먼저 필요했던 것은 <span style="color:#2D3748; background-color:#fff5b1">알파 서버 젠킨스 배포 환경 구축</span>이었다.
베타, 리얼의 경우에는 젠킨스 배포가 가능하도록 되어있었지만
알파는 특이하게 직접 터미널에서 알파 서버에 접속하여 <code>git pull origin develop</code>하는 과정이 필요했다.
변경되지 않은 이유는 크게 2개 같았다.</p>
<ul>
<li>기존에는 젠킨스 파이프라인 소스코드 관리를 데봅스에서 맡았다.<ul>
<li>파이프라인 개선을 위해서는 수정이 필요한 이유와 방향을 설명하는 커뮤니케이션이 필요했다.</li>
<li>아무래도 우선순위가 높지 않아서 현상 유지가 되었던 것 같다.</li>
</ul>
</li>
<li>젠킨스 관리 권한이 데봅스에서 솔루션으로 넘어온지 얼마 되지 않았다.<ul>
<li>대부분의 솔루션 개발자들은 <strong>groovy</strong>에 익숙하지 않았다. (쓸 일도 없었다.) </li>
<li>기존 소스코드에 대한 러닝 타임이 필요했다.</li>
<li>결국 우선순위 높은 테스크를 먼저 처리하느라 신경 쓸 시간이 없었다.</li>
</ul>
</li>
</ul>
<p>그래서 E2E 테스트 실행 프로세스 추가와 함께, 
<span style="color:#2D3748; background-color:#fff5b1">전반적인 Jenkins 파이프라인 개선까지 함께 맡아 처리</span>하였다. </p>
<p><img src="https://velog.velcdn.com/images/myoungji-kim/post/10633223-2947-4171-b793-977875070d46/image.png" alt=""></p>
<p>기존에는 git에서 tag를 add&amp;push하고 해당 태그명을 젠킨스 빌드 시 파라미터값으로 직접 입력해줘야 하는 과정이 있었다면, 이번에는 원클릭으로 앞선 프로세스가 자동으로 되도록 구현하였다.</p>
<blockquote>
<ol>
<li>origin develop 최신 커밋에 <code>(날짜)_(시간)_devleop</code> 으로 태그 생성 및 origin push</li>
<li>server /www/ 하위 경로로 소스코드 배포</li>
</ol>
</blockquote>
<img src="https://velog.velcdn.com/images/myoungji-kim/post/4595d88a-03e9-47f0-8901-1466fc44ea34/image.png" width="300">


<p><span style="color:#777777"><em>다들 은근한 불편함은 느끼고 계셨던 것 같다..ㅎㅎ 
개선 후 긍정 리액션을 받을 때마다 기분이 너무 좋았달까 !</em></span></p>
<p>다시 본론으로 돌아와서, DEPLOY를 개선하니 Jenkins 빌드 시 생성된 태그로 바로 Test를 돌릴 수 있고 롤백 관리를 할 수 있어서 더욱 깔끔해졌다.
이제 Deploy가 완료되면 배포된 서버를 대상으로 본격적인 Test가 실행까지 진행된다.</p>
<hr>
<h3 id="test">TEST</h3>
<p>Test 실행을 서비스 배포 파이프라인에서 직접 하지는 않는다.
명확한 역할 구분을 위해 E2E 파이프라인을 따로 만들었고, 
<span style="color:#2D3748; background-color:#fff5b1">TEST 단계에서는 E2E 파이프라인을 cURL로 실행</span>하도록 하였다.</p>
<table>
<thead>
<tr>
<th align="center">상황</th>
<th align="center">조건1</th>
<th align="center">조건2</th>
<th align="center">수행</th>
</tr>
</thead>
<tbody><tr>
<td align="center">테스트 시작</td>
<td align="center">X</td>
<td align="center">X</td>
<td align="center">Dooray Hook으로 테스트 시작 및 정보 알람</td>
</tr>
<tr>
<td align="center">테스트 종료</td>
<td align="center">테스트 스킨이 남음</td>
<td align="center">X</td>
<td align="center">다음 스킨 테스트를 위한 E2E 파이프라인 빌드</td>
</tr>
<tr>
<td align="center">테스트 종료</td>
<td align="center">테스트 스킨이 남지 않음</td>
<td align="center">테스트 결과 성공</td>
<td align="center">종료</td>
</tr>
<tr>
<td align="center">테스트 종료</td>
<td align="center">테스트 스킨이 남지 않음</td>
<td align="center">테스트 결과 실패</td>
<td align="center">이전 태그로 롤백</td>
</tr>
</tbody></table>
<p>자세한 플로우는 위 그림으로 그렸고, 큼지막하게만 정리하면 위의 표와 같다.</p>
<p>Playwright 자체에서 특정 조건일 경우 전체 테스트를 다시 수행하도록 로직을 작성하는 것이 쉽지 않아 고민이 많았는데, <strong>젠킨스 재빌드를 하면 깔끔하게 해결</strong>되는 문제였다.</p>
<hr>
<h3 id="이제-실제로-사용할-차례">이제 실제로 사용할 차례</h3>
<p>프로세스 구축은 끝났지만, 아직은 환경 개발에 집중하느라 테스트 케이스를 많이 추가해두지 못했다.
그렇지만 반대로 말하면 <span style="color:#2D3748; background-color:#fff5b1">테스트 케이스만 추가하면 돼</span>인 상황이기도 하다.
사실 환경을 구현해두니 다른 우선순위 테스크가 많아지면서 단순 작업인 테스트 케이스 개발이 점차 밀려나고 있다.. 그래서 근무 시간이 아니더라도 퇴근 후나 여유가 있을 때마다 조금씩이라도 해둬야겠다는 생각을 했다.</p>
<p>아마 실제로 사용하게 되는 순간이 오면 다시 여러 시행착오가 발생하지 않을까 싶다.
그때는 다시 포스팅으로 어떤 난관이 있었고 어떻게 극복해나갔는지 작성해봐야했다.
<span style="color:#2D3748; background-color:#fff5b1">기업에서 실제로 E2E 프로세스 도입을 성공시킨 사례가 많지 않아 걱정이 컸는데, 그럼에도 구축을 완료해두어서 참 다행이라는 생각이다.</span></p>
<p>내가 주도적으로 맡아 진행한 프로젝트인 만큼, <strong>묻히지 않고 사내 개발 문화 중 하나로 자리 잡을 수 있도록 꾸준히 관심을 갖고 개선해나가야겠다.</strong> 그럼 이번 포스팅은 여기까지!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[사내 E2E 테스트 도입 경험기 #2 - Playwright로 E2E 테스트 개발하기]]></title>
            <link>https://velog.io/@myoungji-kim/e2e-playwright</link>
            <guid>https://velog.io/@myoungji-kim/e2e-playwright</guid>
            <pubDate>Sun, 30 Apr 2023 03:12:26 GMT</pubDate>
            <description><![CDATA[<h2 id="무엇으로">무엇으로?</h2>
<table>
<thead>
<tr>
<th align="center">주제</th>
<th align="center">대상</th>
</tr>
</thead>
<tbody><tr>
<td align="center">IDE</td>
<td align="center">VSCode</td>
</tr>
<tr>
<td align="center">언어</td>
<td align="center">TypeScript</td>
</tr>
<tr>
<td align="center">실행 (빌드)</td>
<td align="center">Jenkins</td>
</tr>
<tr>
<td align="center">테스트 로그 관리</td>
<td align="center">NHN Cloud Object Storage</td>
</tr>
<tr>
<td align="center">테스트 결과 알림</td>
<td align="center">NHN Dooray Hook</td>
</tr>
</tbody></table>
<p>E2E 테스트를 위해 고려되었던 것들은 위의 표 내용 정도로 간단하게 정리가 된다.</p>
<h4 id="vscode">VSCode</h4>
<p>나는 IntelliJ를 좋아하지만, 
VSCode의 Extension에서 Playwright 확장 프로그램이 설치가 가능한 것을 보고 바로 VSCode로 넘어왔다. 테스트 실행은 GUI로 하는 것이 굉-장히 편리하기 때문에..!! </p>
<p>나중에 찾아보니 Jetbrains에서 테스트를 위한 IDE인 <span style="color:#2D3748; background-color:#fff5b1">Aqua</span> 베타 버전을 무료로 제공해주고 있다는 것을 알고 한번 써볼까 했는데.. 아쉽게도 현재는 셀레니움까지만 지원을 해주며 Playwright는 준비 중이라고 해서 VSCode로 시작을 했다.</p>
<h4 id="typescript">TypeScript</h4>
<p>이번 프로젝트 덕분에 TypeScript를 처음 접해보았다.
TypeScript 언어 자체의 장점도 많아서 한번쯤 도전해보고 싶어서 다른 언어와 크게 비교하면서 깊게 고민하지는 않았던 것 같다.</p>
<p>그리고.. 솔직하게 말하면, 아직 Playwright에 대한 커뮤니티가 크게 활성화되어 있지 않다.
그나마 활성화된 커뮤니티에서 TypeScript로 Playwright를 사용하여 개발한 사례가 비중이 높았기 때문에 좀더 편리한 개발을 위해 선택하였다. 주니어인 나에게는 같은 언어로 고민하는 사람들의 이야기를 보는 것이 훨씬 이해도 빠르고 효율도 좋을 것이라고 생각했다.</p>
<h4 id="jenkins">Jenkins</h4>
<p>이번 E2E 프로젝트의 최종 목표는 <span style="color:#2D3748; background-color:#fff5b1">QA 서버 배포 직후 자동으로 E2E 테스트까지 실행</span>되는 것.
그래서 빌드 프로세스에 E2E 실행까지 포함되어야 했기 때문에 <strong>Jenkins 파이프라인 설계</strong>까지 작업이 필요했다.</p>
<h4 id="테스트-로그-관리">테스트 로그 관리</h4>
<p>젠킨스에서 테스트 실행을 목적으로 하는 빌드가 진행될 때, 미리 빌드된 도커 이미지를 실행함으로써 테스트가 돌아가게 된다. 테스트가 끝난 직후, <span style="color:#2D3748; background-color:#fff5b1">테스트 로그를 확인하기 위해 직접 도커 컨테이너에 접근하여 로그 파일을 찾아 들어가는 과정은 매우 불편하고 비효율적</span>이라 <span style="color:#2D3748; background-color:#fff5b1">테스트가 종료되면 로그를 한 곳으로 자동으로 업로드하여 관리를 해줄 필요</span>가 있었다. 
결론적으로 <strong>NHN Cloud에서 제공하는 Object Storage</strong>에 로그를 올려서 확인 가능하도록 하였다.</p>
<h4 id="테스트-결과-알람">테스트 결과 알람</h4>
<p>테스트 시작, 테스트 종료, 테스트 성공 및 실패 여부에 대해 <span style="color:#2D3748; background-color:#fff5b1">알람을 실시간으로 받을 필요</span>가 있었다. 알람을 받을 창구로 사내 메신저로 사용 중인 <strong>NHN Dooray의 Hook API</strong>를 사용하기로 하였다.</p>
<hr>
<h2 id="어떻게">어떻게?</h2>
<h3 id="page-object-model-pom">Page Object Model (POM)</h3>
<p>MVC, Singleton 등의 패턴은 알고 있었지만
막상 <em>&quot;E2E 테스트를 위한 디자인 패턴..?&quot;</em> 을 생각하니 어떤 것을 참고해야 하나 고민이 컸다.</p>
<p><a href="https://playwright.dev/docs/pom">https://playwright.dev/docs/pom</a>
Playwright 공식 문서에서는 <span style="color:#2D3748; background-color:#fff5b1">POM 모델</span>을 추천했고,
Celenium 등 E2E 테스트를 위해 다른 라이브러리를 사용하는 경우에도 일반적으로 POM 모델을 따르고 있었다.</p>
<p>간단하게는 테스트가 진행되는 Page와,
Page를 구성하는 Object로 나뉘어 설계를 한다고 생각하면 된다.</p>
<h3 id="디렉토리-구조-잡기">디렉토리 구조 잡기</h3>
<p>POM 모델을 바탕으로 테스트 케이스를 추가하며 디렉토리 구조를 설계하기 시작했다.
그리고.. 정말 많이 고민하고 많이 갈아엎었다.</p>
<p>대략적인 구조는 아래와 같다.</p>
<h4 id="src">SRC</h4>
<pre><code>src
├── admin
└── front
    ├── page-locators
    │   ├── mobile
    │   └── pc
    │       ├── login
    │       │   ├── ILoginLocators.ts
    │       │   ├── LoginPage.ts
    │       │   ├── skinA
    │       │   │   └── LoginLocators.ts
    │       │   └── skinB
    │       │       └── LoginLocators.ts
    │       └── ...
    └── paths
        └── PagePaths.ts</code></pre><table>
<thead>
<tr>
<th align="center">Depth</th>
<th align="center">대상</th>
<th align="left">구분 이유</th>
</tr>
</thead>
<tbody><tr>
<td align="center">1</td>
<td align="center">환경</td>
<td align="left">환경에 따라 테스트가 아예 달라짐 (pc / mobile)</td>
</tr>
<tr>
<td align="center">2</td>
<td align="center">서비스</td>
<td align="left">스킨에 따라 제공되는 서비스가 다르지 않음, 스킨이 달라도 동일한 Page를 공유함</td>
</tr>
<tr>
<td align="center">3</td>
<td align="center">스킨</td>
<td align="left">위(2)와 동일</td>
</tr>
</tbody></table>
<hr>
<h4 id="common">COMMON</h4>
<p>Page, Object 세팅과 관련된 요소들을 src 하위로 위치시켰다면,
테스트 실행 전후, 테스트에서 전반적으로 활용되는 요소들은 common 하위로 위치시켰다.</p>
<p>☑️ common/data</p>
<pre><code>common
├── data
│   └── ...</code></pre><p><span style="color:#2D3748; background-color:#fff5b1">static 변수로 값을 저장하여 프로젝트 전반에서 활용되어야 하는 data 정보를 관리</span>하는 곳이다.</p>
<p>테스트 실행 시, 테스트 정보에 대한 파라미터는 env 값으로 전달 받는데,
env 값을 static 변수로 저장하여 프로젝트 전반에서 활용할 수 있도록 해야했다.
지금은 이 역할을 <code>common/data/**</code> 에서 담당하고 있다.</p>
<pre><code class="language-ts">// common/data/env/Domain
export class Domain {
    static hasDomain: boolean = process.env.DOMAIN !== undefined

    static DOMAIN: string = Domain.hasDomain ? process.env.DOMAIN! : &quot;&quot;
    static SUBDOMAIN: string = Domain.hasDomain ? (new URL(process.env.DOMAIN!).hostname!).split(&#39;.&#39;)[0] : &quot;&quot;
    // ... 생략
}</code></pre>
<hr>
<p>☑️ common/external</p>
<p>외부 서비스와의 연동이 필요한 경우가 많았다.
Dooray Hook 알람, Jenkins 빌드, OBS 업로드 등등..
<span style="color:#2D3748; background-color:#fff5b1">외부 서비스와 api로 통신하는 곳은 external 폴더 하위로 분류</span>하였다.</p>
<pre><code>├── external
│   ├── dooray
│   ├── jenkins
│   └── obs</code></pre><hr>
<p>☑️ common/fixture</p>
<pre><code>├── fixture
│   ├── Fixture.ts
│   └── (domain)
│       ├── Member.json
│       └── ...</code></pre><p>테스트에 필요한 실제 데이터 값을 보관하고, 읽는 곳이다.
<span style="color:#2D3748; background-color:#fff5b1">Fixture 클래스는 json 파일을 읽어 원하는 데이터를 array로 반환해주는 역할을 담당</span>한다.</p>
<pre><code class="language-ts">import { Domain } from &#39;@common/data/env/Domain&#39;
import * as fs from &#39;fs&#39;

export class Fixture {
    static get(fileNm: string, key: string) {
        const jsonFile = fs.readFileSync(`common/fixture/${Domain.SUBDOMAIN}/${fileNm}.json`, &#39;utf8&#39;)
        const fixture = JSON.parse(jsonFile)[key]
        return fixture
    }
}
</code></pre>
<p>예를 들어 Memeber.json 파일 내에는 아래와 같이 데이터가 저장되어 있고,</p>
<pre><code class="language-json">{
    &quot;testUser&quot;: {
        &quot;id&quot;: &quot;(id)&quot;,
        &quot;name&quot;: &quot;(name)&quot;,
        &quot;pw&quot;: &quot;(password)&quot;
    },
    ...
}</code></pre>
<p>실제로 값을 읽을 때는 아래와 같이 호출한다.</p>
<pre><code class="language-ts">const fixture = Fixture.get(&quot;Member&quot;, &quot;testUser&quot;)</code></pre>
<hr>
<p>☑️ common/hook</p>
<pre><code>├── hook
│   ├── CustomReporter.ts
│   ├── afterEach
│   │   └── ...
│   └── beforeEach
│       └── ...</code></pre><p>Playwright에서 기본적으로 제공해주는 Reporter 인터페이스를 implements하면 
본인이 원하는 커스텀 레포트를 만들 수 있다.</p>
<pre><code class="language-ts">export default class CustomReporter implements Reporter {
    // 전체 테스트 시작 전
      onBegin(config: FullConfig, suite: Suite): Promise&lt;void&gt; { }

      // 전체 테스트 종료 후
      onEnd(result: FullResult): Promise&lt;void&gt; { }

      // 개별 테스트 시작 전
      onTestBegin(test: TestCase, result: TestResult): void { }

      // 개별 테스트 종료 후
      onTestEnd(test: TestCase, result: TestResult): void { }
}
</code></pre>
<p>각 케이스에 따라 적절하게 로그나 외부 api 호출 등을 추가하여 테스트 실행 결과 관리를 하였다.</p>
<hr>
<p>☑️ common/log</p>
<pre><code>├── log
│   └── Logging.ts</code></pre><p>이번 프로젝트에서는 winston로 로그 관리를 하였다.
로그 작성에 대한 소스코드는 위 클래스로 관리하였다.</p>
<hr>
<p>☑️ common/page</p>
<pre><code>├── page
│   ├── Admin
│   │   └── AdminPageCommon.ts
│   ├── Front
│   │   ├── MobilePageCommon.ts
│   │   └── PcPageCommon.ts
│   └── PageCommon.ts</code></pre><p>Page 관리에 대해 Common한 요소들만 모아놓은 곳이다.
Page 공통적으로 필요한, 특정 페이지를 여는 것을 <code>Page.open()</code>이라는 하나의 메서드로 통일시키기 위해 고민한 결과이다. 이건 별도의 포스팅으로 정리하는 것이 좋을 듯 싶다.</p>
<p><em>➡️ (포스팅 완성 후, 여기에 링크가 생성될 예정입니다.)</em></p>
<hr>
<h4 id="tests">tests</h4>
<pre><code>tests
├── admin
│   └── Login.spec.ts
└── front
    ├── mobile
    │   └── Login.spec.ts
    └── pc
        └── Login.spec.ts</code></pre><p>tests 내부도 src와 같이 depth를 <code>환경 - 서비스 - 스킨</code>으로 잡았다.
테스트 코드 작성은 보통 아래와 같은 구조를 따른다.</p>
<pre><code class="language-ts">/**
 * @Title ( 테스트 제목 )
 * @Level ( 테스트 우선순위 )
 * @Given
 * ( 테스트 사전 조건)
 * @When
 * ( 테스트 수행 절차 )
 * @Then
 * ( 테스트 기대 결과 )
 */
test(&quot;[FRONT][PC] Login_0001: 로그인_성공&quot;, async ({ page }) =&gt; {
    // given
    let mainPage = new MainPage(page)
    let header = new Header(page)
    let loginPage = new LoginPage(page)
    const fixture = Fixture.get(&quot;Member&quot;, &quot;commonUser&quot;)

    // when
    await mainPage.open()
    await page.click(header.locators.aLogin)
    await page.fill(loginPage.locators.inputId, fixture.id)
    await page.fill(loginPage.locators.inputPw, fixture.pw)
    await page.click(loginPage.locators.buttonLogin)
    await page.waitForNavigation({ waitUntil: &quot;load&quot;, timeout: 10000 })

    // then
    const expected = Skin.SKIN == &quot;(skinA)&quot; ? &quot;LOGOUT&quot; : &quot;로그아웃&quot;
    expect(await page.textContent(header.locators.aLogout)).toBe(expected)
})</code></pre>
<p>테스트 코드를 보면 아마 아래와 같이 구분한 이유가 더 명확하게 보이지 않을까 싶다.</p>
<pre><code>├── login
   ├── ILoginLocators.ts
   ├── LoginPage.ts
   ├── skinA
   │   └── LoginLocators.ts
   └── skinB
       └── LoginLocators.ts</code></pre><p>스킨별 Locators 클래스는 같은 Locators 인터페이스를 바라본다.</p>
<pre><code class="language-ts">const { LoginLocators } = require (&quot;./&quot; + Skin.SKIN + &quot;/LoginLocators&quot;)

export class LoginPage extends PcPageCommon {
    readonly locators: ILoginLocators

    constructor(page: Page) {
        super(page, PagePath.LOGIN_PAGE)
        this.locators = new LoginLocators()
    }
}</code></pre>
<p>구체적인 Locators 값은 각 스킨별로 구분되어있기 때문에 
<span style="color:#2D3748; background-color:#fff5b1">테스트가 돌아가는 skin env 값에 따라 자동으로 적절한 skin의 Locators를 가져오게 된다.</span></p>
<hr>
<h2 id="테스트-개발-완료">테스트 개발 완료</h2>
<p>위 구조를 바탕으로 전반적인 테스트 케이스 개발이 가능해졌다.
내가 고민해서 만든 구조가 정답인지는 모르겠지만.. 여러번 갈아엎는 과정에서 비효율적인 구조를 정말 많이 버렸기 때문에 평균 이상의 역할은 하고 있다고 생각한다. </p>
<p>테스트 코드 작성이 완료되었다면, <span style="color:#2D3748; background-color:#fff5b1">이제는 실제 배포 프로세스에 E2E 테스트를 녹일 차례</span>다.
이건 다음 포스팅에서 이어서 진행해야겠다 !</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[사내 E2E 테스트 도입 경험기 #1 - 도입 배경]]></title>
            <link>https://velog.io/@myoungji-kim/e2e-background</link>
            <guid>https://velog.io/@myoungji-kim/e2e-background</guid>
            <pubDate>Sun, 23 Apr 2023 11:32:49 GMT</pubDate>
            <description><![CDATA[<h3 id="들어가기-전에">들어가기 전에</h3>
<p>작년 말, E2E 도입이 처음 이슈업 되었고
2023년이 시작되면서 본격적으로 E2E 테스트 프로세스 도입을 내가 맡게 되었다.</p>
<p>처음에는 _&#39;테스트 케이스만 추가하면 되는건가&#39;_라고 생각하는 등
일의 난이도나 깊이에 대해 정확하게 파악을 하지 못했다.</p>
<p>그리고 <span style="color:#2D3748; background-color:#fff5b1">수많은 시행착오를 겪어오면서 현재는 E2E 도입이 가능한 프로세스 구축까지 구현</span>해두었다.
지금부터 풀어볼 이야기는 시작부터 지금까지의 도전 이야기,
그리고 실제 E2E 테스트를 하며 앞으로 겪게 될 또 다른 시행착오들도 함께 풀어나가지 않을까 싶다.</p>
<hr>
<h3 id="e2e-테스트가-뭔데요">E2E 테스트가 뭔데요?</h3>
<p><strong>End-to-End</strong> 테스트의 약자로,
실제 사용자 시나리오를 시뮬레이션하여 프로그램의 전체 흐름을 테스트하는 유형을 의미한다.
단위, 구성테스트에서 발견하기 어려운 통합 단위의 문제를 파악하기 위한 테스트이기도 하다.</p>
<p>우리팀에서는 <span style="color:#2D3748; background-color:#fff5b1">Playwright</span> 라이브러리를 활용하기로 했다.</p>
<p>이유는 크게 3가지였다.</p>
<ul>
<li>빠른 테스트 속도: 테스트 병렬 실행 가능</li>
<li>Microsoft 사 라이브러리: 오랜 기간 관리될 가능성 높음</li>
<li>codegen 기능: 빠른 테스트코드 작성에 도움을 줌</li>
</ul>
<hr>
<h3 id="e2e-테스트가-왜-필요했나요">E2E 테스트가 왜 필요했나요?</h3>
<h4 id="사실-테스트-문화를-만들기에는-다들-너무-바빴다">사실 테스트 문화를 만들기에는 다들 너무 바빴다</h4>
<p>테스트 코드, 
꼼꼼하게 잘 작성되고 모두가 테스트 문화를 지켜나간다면 너무 좋지만
여러 개발팀에서는 시간에 쫓기다보니 일이 바쁜 경우에는 
테스트코드가 우선순위에서 계속 밀려나게 된다.</p>
<p>현재 내가 속한 서비스 개발팀도 일이 많이 쌓여있다보니
다들 테스트 코드에 대한 문화를 고민할 여유가 없는 상황이 지속되고 있었다.</p>
<p>이런 상황에서 내가 어떻게 E2E 테스트 프로세스 구축을 맡게 되었을까,
사실 E2E 테스트 문화만큼은 우선순위를 조금 더 높여 도입해야했던 이유가 있었다.</p>
<h4 id="배포-때마다-반복되는-수동-qa-비효율적인-과정은-제거하자">배포 때마다 반복되는 수동 QA, 비효율적인 과정은 제거하자</h4>
<p>우리 팀이 웹서비스를 개발하고 배포하는 과정은 아래와 같다.</p>
<blockquote>
<p>로컬 개발 -&gt; 알파 배포 -&gt; 베타 배포 -&gt; 리얼 배포</p>
</blockquote>
<ul>
<li>1달에 1번 진행하는 정기배포 (+ 베타 배포)</li>
<li>그외 필요할 때마다 진행되는 수시배포 (+ 베타 배포)</li>
</ul>
<p><strong>베타 배포, 리얼 배포</strong> 직후 <strong>필수로 진행해야 하는 E2E QA 리스트</strong>가 있었는데
우선순위 1번째 QA 리스트라는 의미에서 팀에서는 <strong>P1 테스트</strong>라고 명명한다.</p>
<p>그리고 기획팀에서 1달에 최소 2회 이상의 정해진 P1 테스트를 직접 진행해왔다.
<em>(그리고 P1 리스트에 속해있는 테스트 케이스들의 수는 거의 200~300개)</em></p>
<p>고정된 테스트를 매번 사람이 직접 반복적으로 확인하는 상황 자체가 굉장히 비효율적이었고,
이 문제를 개선하기 위해 <span style="color:#2D3748; background-color:#fff5b1">P1 테스트만큼은 배포 직후 자동으로 테스트가 수행되도록 하는 프로세스가 필요</span>했다.</p>
<p>그리고 난 정말 용감하게도 &quot;제가 해봐도 되나요?&quot;라고 말해버렸다.
그 당시 생각했던 테스크의 규모와, 지금 내가 되돌아보는 이 테스크의 규모 차이는 극과 극이랄까..
그래도 많이 배울 수 있었던 너무 좋은 기회였다 
(기회였다...? 사실 아직 -ing 중이다 🫠)</p>
<hr>
<h3 id="근데-e2e-레퍼런스가-너무-없다">근데 E2E 레퍼런스가 너무 없다</h3>
<p>사실 이번 테스크를 시작하면서 E2E 테스트라는 것에 대해 처음 찾아보게 되었고, 
생각보다 너무 자료가 없어서.. 당황스러웠다.</p>
<p>여기서 쓴 자료가 없다는 말은 아래와 같다.</p>
<ul>
<li>타 기업에서 Playwright를 활용한 성공 사례가 없다.</li>
<li>사실 타 라이브러리로도 E2E를 성공적으로 도입한 기업 사례가 거의 없다.</li>
<li>그래서인지 E2E 관련 컨퍼런스 영상이.. 1-2개 뿐이랄까..? 사실 이마저도 현재 우리팀 상황과 많이 달라서 아쉬웠다.</li>
</ul>
<p>누군가가 잠깐 공부하려고 올린 포스팅은 사실 필요한 정보들에 가깝지 않았기 때문에
결국 맨땅에 헤딩을 하듯이 공식 문서를 미친듯이 찾아보고, 혼자 구조를 설계하며 새롭게 꾸며가게 되었다.</p>
<p>1년차도 안된 내가 회사에서 무언가를 처음부터 이끌고 문화를 만들어 나간다는게 조금 부담스럽기도 했고, 
그만큼 잘 해내고 싶은 욕심이 컸는데 내 실력이 따라와주지 않아 속상했던 적도 많았다. </p>
<p>그래도 지금 포스팅으로 회고록을 작성하기 시작할 정도로 진도가 많이 나갔기 때문에
중간에 포기하지 않고 잘 이끌고 왔다고 스스로에게 칭찬 한 마디 건네주고 싶다 💪</p>
<hr>
<h3 id="다음-포스팅에서">다음 포스팅에서</h3>
<p>다음 포스팅부터는 내가 구현한 E2E 테스트 프로세스에 대해 조금더 deep하게 소개할 예정이다.
이번 글은 약간의 빌드업과 지금까지 느낀 내 생각 정리랄까 ㅎㅎ</p>
<p>그렇다면 이제 2편에서 마저 작성해보는걸로!🔔</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[첫 글]]></title>
            <link>https://velog.io/@myoungji-kim/%EC%B2%AB-%EA%B8%80</link>
            <guid>https://velog.io/@myoungji-kim/%EC%B2%AB-%EA%B8%80</guid>
            <pubDate>Sun, 23 Apr 2023 06:17:42 GMT</pubDate>
            <description><![CDATA[<h3 id="기존-velog를-삭제했다">기존 velog를 삭제했다</h3>
<p>최근 들어 개인 공부의 흔적을 다시 github에 남기기 시작해야겠다는 다짐을 했다.
오랜만에 들어간 github에는 취준생 시절 맨땅에 헤딩을 하며 공부했던 흔적들이 가득했다.</p>
<p>첫 입사를 한 날짜는 2022-08-08,
이제 겨우 9개월 차 주니어 백엔드 개발자이지만
그럼에도 입사 전과 현재의 내 모습은 한참 비교가 되었다.</p>
<p>즉, 그 당시에는 멋모르고 올렸던 다양한 공부 기록들이 
지금은 조금 부끄러운 병아리 수준의 기록이 되었달까..</p>
<p>심지어 간단히 맛보기 수준으로 코드를 작성한 것까지 레포로 모두 올려두었던 것을 보며 
한시라도 빨리 정리를 해야겠다는 생각이 들었다.</p>
<p>github 레포들을 정리하고, 리드미 파일을 수정하다가 내 velog에 오랜만에 들어가보게 되었다.
지금 내 상황에서 참고할 만한 의미 있는 포스팅이 전혀 없었고,
약간의 검색을 통해 쉽게 찾을 수 있던 것들까지 모두 포스팅으로 올려서 개수는 매우 많았다.
내 벨로그를 다시 구경하며 &#39;양은 많고 질은 떨어지는 블로그가 되어있었구나&#39;라는 생각 뿐이었다.</p>
<p>그래서 게시글을 전부 삭제하려고 보니
벨로그에는 게시글 전체 삭제 기능이 따로 제공되지 않는 것 같았다.
그래서 큰맘 먹고 회원 탈퇴를 했다.</p>
<p>미련이 남는다기보다는 
진짜 개발자스러운 블로그를 가꿔나갈 수 있겠다는 설렘에 기분이 좋았다.</p>
<hr>
<h3 id="어떤걸-올려볼까">어떤걸 올려볼까</h3>
<p>올리고 싶은 내용은 많다.
신입 개발자로서 회사에서 배우는 다양한 것들, 그리고 느낀 점들도 대외비를 지키는 선에서 정리해볼까 한다.</p>
<p>지금 책들도 계속 읽고 있는데
사실 작년까지만해도 처음에는 교과서를 그대로 필기노트화 시키는 것처럼 정리를 했고,
지금 돌아보니 온전히 내꺼로 만든 듯한 정리는 아니였다.
책을 내껄로 습득해 다시 내 색을 담은 포스팅을 올리고 싶다.</p>
<hr>
<p>👍 할 수 있다! 화이팅!</p>
]]></description>
        </item>
    </channel>
</rss>