한국인이 외국계에서 살아남기 위한 3가지 조언

2022. 1. 25. 09:12

2021년 MIT 경영 대학에서 발표한 재미난 연구 결과가 있었습니다. 미국에서 리더로 자리잡은 사람들의 비율로 판단해보면 동북아 (한국,중국,일본 등) 지역 인재들이 동남아 (방글라데시,인도,파키스탄 등) 지역 인재들에 비해 저평가 된다는 건데요. 그 이유가 언어나 편견, 업무 동기가 아닌 미국 문화 적합성에 있다는 연구였습니다. 겸손, 순응이 미덕인 동북아 지역의 문화가 Assertiveness로 표현되는 미국 문화에서 불리하다다는 거죠.

Assertiveness 를 한국어로 정의하기는 참 어렵습니다. 굳이 풀어보자면 수동과 능동의 가운데, 적절한 당당함의 느낌입니다. 적어도 네트워킹, 자기주장, 자기자랑 3가지 능력을 겸비해야 Assertive하다라고 할 수 있습니다. 딱봐도 겸손과 순응과는 좀 거리가 있습니다.

그럼 한국인이 위 3가지를 어떻게 잘해낼 수 있을까요? 관련하여 미국계 기업에서 잘 생존하고 계신 선배들의 조언을 좀 들어봤습니다.

출처: pixabay

1. 네트워킹 이벤트
해외 기업 행사에서(코시국이전)는 칵테일 파티 비어챗 등 네트워킹 시간이 자주 마련되어 있습니다. 모르는 사람과도 학창시절 동창 만난듯 어울리는 사람들(주로 외국인)이 있는 반면 조용히 홀로 구석에 서성이는 사람들(한국,중국,일본인)이 있습니다. 혹은 이미 알던 사람끼리 모여있지요. 이 시간을 잘 활용하면 없던 인맥을 만들고 나를 알리고 또 생각도 못한 도움을 받는 경우도 생깁니다. 이런 자리를 활용하는 팁인데요. 참석자들 중 알고 싶은 사람 소수를 정하고 이야기거리를 준비해간다는 겁니다. 그리고 그 사람을 레버리지로 다른 사람과 안면을 트는 식으로 네트워킹을 해나가는 거죠. 이야기 거리를 미리 준비하는 센스가 필요한 거였습니다.

2. 자기 주장
정답을 맞추는 식의 교육과정을 적어도 12년을 겪어서일까요? 틀린 답을 말하거나 모른다고 이야기하기를 꺼리는 건 한국인의 공통적인 특징인 것 같습니다. 그래서인지 말을 아끼게 되고 목소리를 내야하는 자리에서 가만히 있는 실력없는 사람으로 오해를 받는 일도 종종 있습니다. 자연히 질문도 줄어듭니다. 이런 성향을 조금이나마 보완하기 위해 아래와 같은 마음가짐이 도움이 된다고 합니다. "완벽한 의견, 정답은 없다.", "남들도 모른다","틀릴 수 있다 그래도 괜찮다"

3. 자기 표현
한국 회사에서는 일을 잘해내고 자랑하지 않는 것이 미덕이었습니다. 리더만 알아준다면 자연히 빛이 나는 상황이 만들어집니다. 이런 일을 해냈다고 떠들고 다니면 잘난척한다고 손가락질 당하기가 더 쉬웠습니다. 외국계에 와서 보니 일을 잘해내는 게 끝이 아니었습니다. 그걸 잘 포장해서 알리는 것까지 해야 깔끔한 마무리입니다. 나 잘했다고 자랑하는 것이 낯간지럽고 익숙하지 않습니다. 그런 "자기자랑" 시작이라도 하기위해 마인드셋의 전환을 조언해주셨습니다. 내가 잘한 일을 알리고 인정받는 것 그것은 나만을 위한 게 아니라는 겁니다. 결국 나의 리더와 팀원들에게 도움이 되는 일이라는 이야기에 크게 한 대 맞은 기분이었습니다. 그리고 내가 잘한 일 그리고 나를 알리는 일은 회사와 팀원들에게 나를 어떻게 사용할지에 대한 나 사용 설명서가 된다는 말씀도 크게 도움이 되었습니다.

Assertiveness 이외의 조언들도 있었습니다. 도움을 요청하는데 주저하지 말자, 영어가 모국어가 아닌 이상 발표는 스크립트를 준비하고 연습, 또 연습하자, 말보다는 진심이 전달 되면 된다는 등이었네요.

역시 회사생활은 쉽지 않습니다. 일을 잘하는 건 기본 그에 더한 무언가가 필요한 것 같습니다.

TechTrip IT Tech

TRACS 프로젝트 관리 방법론 (TRACS Project Management Framework)

2021. 7. 29. 23:20

얼마 전 접하게 된 TRACS 라는 프로젝트 관리 방법에 대해 짧게 공유합니다.

출처: https://pixabay.com/images/id-163518

TRACS라는 약어부터 왠지 의미를 가지고 있는 것 같아서 마음에 드는 방법론이었습니다.
"Are we on track?"
이런 말 자주 하니까요.

프로젝트 관리에 대해 이야기하기 전에 먼저 프로젝트의 정의부터 명확히 하겠습니다. 굉장히 애매한 단어 이기도 하구요.

제가 여기서 언급하는 프로젝트는 정해진 기간과 예산, 특별한 목적을 가진 일시적인 업무입니다. 모든 상황과 조건이 동일한 프로젝트는 없습니다. 이전의 업무 경험들이 동일하게 적용이 어려울 수 있기 때문에 관리할 방법론이 꼭 필요합니다.

TRACS는 아래 단어들의 앞 글자만 따온 것입니다.
Timing
Resources
Actions
Communication
Stakeholders

프로젝트 계획/관리에 있어 빠져서는 안될 것들인데요. 간략하게 의미만 살짝 살짝 언급하고 넘어가겠습니다.

Timing
프로젝트의 중요한 타임라인입니다.
시작과 끝, 중간 점검을 위한 마일스톤, 보고 등 중요한 이벤트 시점을 의미합니다.

Resources
프로젝트에 투입 가능한 인력, 예산과 같은 것들입니다.

Actions
프로젝트 진행에 있어 작은 단위 할 일들입니다. 가장 인상적이었던 부분은 개인 단위로 책임질 수 있을 정도로 작게 쪼개야 한다는 점이었습니다. 기대하는 결과물, 할 일들 간의 의존성도 놓치지 말아야 합니다.

Communication
소통 방법입니다. 진척 사항 관리라든지 의존된 업무들 간의 효율적인 협업 등에 대한 것들입니다.

Stakeholders
직,간접적인 모든 이해관계자를 파악하는 것입니다. 프로젝트 원부터 보고 라인 및 프로젝트로 수혜받는 고객 등입니다.

단어 하나 하나만 해도 수많은 주제와 그를 위한 도구들이 있지만 프로젝트를 관리하기 위한 커다란 툴로써 TRACS는 꽤 효율적이고 의미있는 방법론이라고 생각합니다.

TechTrip IT Tech

구글 코리아 면접 후기

2021. 6. 29. 22:28

개인적인 기록 및 향후 인터뷰를 앞 둔 분들께 조금이나마 도움이 되었으면 하는 마음으로 후기를 남깁니다.

인터뷰의 구체적인 질문들은 기밀사항으로 공유하지 않습니다. 다만 비행기 안에 탁구공이 몇 개나 들어가는지 등의 Brain Teaser 질문은 몇 년전부터 더이상 하지 않는 다네요. (다행이었습니다.)

먼저 구글 지원 및 입사까지의 타임라인입니다.
약 3개월이 걸렸습니다. 중간에 설명절이 있어서 더 길어진 감도 있습니다.

1월 24일 구글 커리어 페이지에 Resume 제출
1월 25일 리크루터로부터 메일로 연락옴
1월 28일 전화인터뷰 진행
2월 4일 면접 2회
2월 9일 리크루터와 follow up call
3월 3일 면접 2회
3월 4일 리크루터와 follow up call
(Hiring Committee 진행)
3월 24일 offer meeting + 연봉협상
4월 말 입사

Noogler Hat on my lovely kid

지원한 직무는 Mobile Solutions Consultant로 개발업무와 영업을 연결하는 다리 역할의 직무입니다. 사실 지원은 개발 직무로 했는데 리크루터 분의 제안으로 저에게 더 적합한 포지션으로 직무를 변경하여 지원하였습니다.

인터뷰 준비는 저 자신과 제가 해온 업무에 대해 정리하는 것부터 시작했고, 그 이후에 구글에 대해서 공부했습니다. Jeff H sipe, Clement Mihailescu YouTube를 많이 봤습니다. Resume는 1장짜리 PDF로 만들었습니다.

전화인터뷰는 편한토크 + 직무 상식 퀴즈로 이루어졌습니다. 사실 직무 상식 퀴즈는 별도의 콜을 잡아도 되었었는데 다시 일정을 잡는게 서로에게 번거로울 듯 하여 한 번에 진행했네요. 직무 상식 퀴즈는 일종의 1차 스크리닝 느낌이었고 한 문제라도 틀리면 안되는 듯 했습니다. (확실치 않음)

4번의 인터뷰는 Google Meet로 진행했고, 아래와 같은 영역의 질문들로 이루어졌습니다.
1. Role Related Knowledge
2. General Cognitive Ability (Problem Solving)
3. Leadership
4. Googleyness
인터뷰 질문들은 2가지 이상의 주제가 복합적으로 연관된 문제들이라고 느꼈습니다. Problem Solving의 상황이 주어지고 그 배경으로 Role Related Knowledge가 필요한 질문이 더러 있었네요. Leadership과 Googleyness 역시 개인적으로 느끼기에 딱 나눠지기 어려운 영역이 존재합니다.

인터뷰에 사용한 언어는 한국어 60%, 영어 40% 정도였지만 배정되는 인터뷰어에 따라 다를 듯합니다. 코딩 질문은 비즈니스 쪽 직군이라 그런지 문법이나 알고리즘 자체보다는 논리적 사고를 통한 해결력 측면을 좀 더 중요시하는 분위기였습니다.

리크루터와 인터뷰어들 모두 굉장히 편안한 분위기를 만들고 제 실력을 발휘할 수 있도록 독려해줍니다. 합격, 불합격을 떠나 인터뷰 자체가 스스로를 돌아보고 배울 수 있는 좋은 기회라고 느꼈습니다. 매우 긍정적인 경험이었습니다.(4번의 인터뷰 결과를 가지고 합격/불합격을 결정하는 Hiring Committee가 열리는데 시간이 좀 걸려 많은 생각을 하게 됩니다.)

마지막으로 늦게서야 깨달은 팁입니다.
다른 회사에도 함께 지원하여 최종 offer를 받아두는 것이 연봉협상에서 유리합니다. 연봉협상력을 가지기 위해 비슷한 레벨의 다른 회사도 합격해서 Offer를 받아놓는 게 좋습니다. 그렇지 않으면 이전 연봉을 기준으로 협상이 이루어질 수 밖에 없더라구요. 회사 입장에서 생각해보면 후보가 얼마나 능력있는 사람인가에 대한 객관적인 몇 안되는 지표가 현재 연봉, 타사 Offer인 것 같습니다.

저의 경험이 조금이나마 도움 및 참고가 되셨으면 좋겠습니다.

TechTrip IT Tech

CORS 로컬 개발용 우회 방법

2020. 6. 6. 21:36

프론트엔드 개발을 하다보면 종종 CORS(Cross Origin Resource Sharing) 오류 메시지를 마주치게 됩니다.

이 오류는 간단히 말해서 접속한 사이트가 내부적으로 다른 도메인(Domain) 혹은 포트(Port)의 자원(Resource)을 요청했을 때 브라우저가 보안 상의 이유로 해당 요청을 허용하지 않기 때문에 발생하는 오류입니다.

보통 운영 환경에서는 API서버와 프론트 서버를 같은 도메인 상에 묶어 놓는 경우가 많습니다. 다만 개발 시에는 서로 다른 도메인 혹은 포트 상에서 진행되는 경우가 대부분이죠. 프론트엔드 서버와 API 서버를 로컬의 서로 다른 포트에 두거나 개발은 로컬에서 API서버는 별도의 서버에 기동되는 등의 경우입니다. 결국 개발 시에는 CORS 오류를 마주할 가능성이 높다는 이야기죠.

이에 대한 근본적인 해결책은 물론 API 서버 측에서 CORS를 허용하는 쿠키를 넣거나, 프록시 세팅을 통해 두 서버를 같은 도메인으로 묶거나 하는 등의 방법이 있습니다. 하지만 단지 개발을 위해 그런 처리를 하기에는 귀찮죠. 간단하게 테스트 용으로만 사용할 수 있는 방법이 있어 공유합니다.

그 방법은 바로 로컬의 브라우저의 보안을 꺼버리는 것 입니다. 이미 말씀드렸듯이 테스트 용도입니다. 안전하지 않기 때문이죠. 신뢰할 수 있는 자신이 개발하는 코드의 테스트 용도로는 딱입니다.

윈도우에서 예로들면 아래와 같은 명령을 통해 Chrome 브라우저의 보안을 끄고 CORS 오류 없이 작업이 가능해집니다.

"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security --user-data-dir="C:\Temp"


그러면 아래와 같은 Chrome창을 확인할 수 있습니다.

 

브라우저 보안이 해제된 Chrome

 

'지원되지 않는 명령줄 플래그(--disable-web-security)를 사용 중이므로 안전성과 보안에 문제가 발생합니다'라고 하는 안내문구가 보이시죠? 바로 저 안내문구가 CORS 오류를 체크하지 않는 다는 것을 의미합니다. 물론 이 뿐만 아니라 사용자를 보호하기 위한 다른 보안 기능들도 꺼져있다고 보시면 됩니다. 개발 시에 사용하는 임시방편이라는 의미죠. 하지만 다른 CORS 툴을 깔거나 고생하는 것보다는 훨씬 편리한 방법입니다.

TechTrip IT Tech

Galaxy Fold를 대응할 반응형웹?!

2020. 5. 23. 14:01

많은 디바이스의 다양한 해상도에 대응하기란 참 어렵습니다. 그 중 대표적인 것 하나가 반응형 웹사이트입니다. 브라우저의 너비(Viewport)에 따라 다른 스타일을 보여주는 방식이지요.

하지만 이 또한 한계가 있습니다. 전환점(Breakpoint)에 따라 디자인을 다르게 하려면 그 또한 시간과 비용이 듭니다. 결국 어느 정도 선에서 타협이 이루어집니다. 제가 속한 프로젝트는 진행 속도를 위해 모바일/데스크탑용 2종류 디자인을 가지고 그 중간 영역에서는 비율에 따른 너비(vw)로 대응하였습니다.

아래와 같이 나누었지요.
1. ~360px (모바일 디자인)
2. 361px ~ 768px (모바일 디자인 비율 확대)
3. 768px ~ 1440px (데스크탑 디자인 비율 축소)
4. 1440px~ (데스크탑 디자인)

그런데 Galaxy Fold라는 디바이스로 위기를 맞이합니다. 안타깝게도 이 디바이스는 접힌 화면의 너비(Viewport)는 320px, 펼친 화면의 너비는(Viewport) 535~683px 입니다. 디바이스의 글자크기 설정(작게, 중간, 크게)에 따라 브라우저의 너비(Viewport)가 535, 586, 683px로 달라집니다.

Galaxy Fold Viwport (글자크기 크게)

접힌 화면(320px)에서는 가로 스크롤이 생기고, 펼친 화면의 애매한 크기(535~683px)는 확대된 모바일 컨텐츠가 잘리는 안타까운 상황이었습니다. 딱히 묘안은 없었고 결국 Breakpoint를 추가할 수 밖에 없었습니다. 초기에 작업했던 것들은 전부 재작업해야했죠.

대상 디바이스에 대한 조사가 선행되고 전환점(Breakpoint)에 대한 고민을 했다면 오히려 시간을 아꼈을 수 있겠다는 아쉬움이 남네요. 적어도 폴드는 작년에 나왔으니까요. 앞으로도 다양한 디바이스들이 계속 출시될텐데 반응형 디자인에 대한 고민은 계속 되어야할 것 같습니다. 하나의 소스로 모두 대응하려는 방식(One source multi-use)은 어쩌면 독이 될 수도 있다는 생각도 하게 됩니다.

TechTrip IT Tech

아토믹 디자인(Atomic Design) 적용해볼까?

2020. 5. 17. 22:34

이 글은 아토믹 디자인(Atomic Design)이 무엇인가에 대한 글은 아닙니다. 아토믹 디자인 컨셉을 활용해 본 후기입니다.

아토믹 디자인은 아래 블로그에서 자세히 확인하실 수 있습니다.

Brad Frost의 아토믹 디자인 컨셉

 

아토믹 디자인이라는 용어를 접한 건 작년 2019년 입니다. 아토믹 디자인은 쉽게 말해서 화면을 구성할 수 있는 아주 작은 단위의 요소부터 디자인 시스템을 만들어가는 방법론이라고 볼 수 있습니다.

놀랍게도 2013년도부터 이 용어가 쓰여졌는데요. 2016년에는 책도 쓰였으니 꽤나 오래된 개념이라고 볼 수 있겠네요. 제가 이 용어를 접하게 된 계기는 재미있게도 디자인이 아닌 개발 효율화 측면이었습니다. 비슷한 모양의 비슷한 기능을 하는 스타일코드와 스크립트들이 중복하여 존재하는 프로젝트가 있었습니다. 이를 개선할 방법은 중복 코드의 제거를 통한 효율화인데 프로젝트의 오너는 비개발자여서 이를 더 멋지게 설명할 그럴듯한 단어가 필요하여 아토믹 디자인을 발견하게 되었습니다. 최신 웹 개발 프레임워크(Angular, React, Vue 등)들이 컴포넌트 단위의 개발을 지원하기에 아토믹 디자인과 디자인시스템의 도입은 개발 측면에서도 상당한 이득을 가져다 줄 수 있었습니다.

여기까지가 머리 속에서 그린 청사진이지요. 안타깝게도 현실은 만만치가 않습니다. 머리 속에서 그렸던대로 흘러가지 않았습니다. 제가 마주한 어려움들 몇 가지를 공유하며 아토믹 디자인을 적용하기 위한 전제에 대해 적어봅니다.

1. 아토믹 디자인은 모든 팀원이 이해하고 시작해야 합니다.
어떤 방법론이든 참여자들의 이해를 기반하여 성과가 나온다는 것은 명확합니다. 아토믹 디자인은 특히나 기획/디자인/개발 역할자 모두가 아토믹 디자인이 어떤 식으로 흘러가는지 이해할 필요가 있습니다. 일반적인 작업 방식과 순서부터가 다릅니다. 전체적인 그림을 그리고 부분적으로 채워가는 Top-Down 방식이 아닌 가장 작은 요소부터 만들어가는 Bottom-Up 방식으로 만들어집니다. 요즘은 애자일이라 부르고 짧은 일정에 디자인과 개발이 병렬적으로 수행되는 경우가 많은데 이런 상황에서는 기획/디자인이 Top-Down 방식으로 가는 이상 개발에서 아토믹 디자인을 적용하기 상당히 어렵습니다. 논의를 통해 공통요소를 도출하고 적어도 스타일 가이드는 만들어가야 그나마 흉내는 낼 수 있죠. 다만 상당히 고생할 수 밖에 없습니다.

2. 이미 정의된 아토믹 요소를 공유할 체계가 필요합니다.
프로젝트는 여러 사람이 함께합니다. 아토믹한 요소들에 대해 모두가 숙지하고 있다면 좋겠지만 큰 프로젝트의 경우 스타일 가이드를 완성해가는 사람들과 실제 화면을 디자인해가는 사람들이 다릅니다. 따라서 디자인의 근간이 되는 요소들이 실시간으로 공유될 체계가 잡혀있어야합니다. Zeplin이든 Sketch Library든 또는 코드가 포함된 Style Guide든 (PatternLab, Storybook, Fractal 등) 눈으로 쉽게 확인할 수 있는 방법과 무엇이 언제 왜 업데이트가 되는 지에 대한 내용이 문서이든 협업 도구든(Slack, Jira, Confluence, Wiki 등) 잘 기록되고 관리되어야합니다. 아무 체계 없이 가다가는 혼란스러울 뿐입니다.

3. 적당한 경계를 잘판단해야 합니다.
가장 어려운 단어인 '적당한'이 등장 합니다. 어디까지가 표준이고 공통이며 어디부터가 변용인지 명확한 경계가 없습니다. 팀원들이 잘 정해나가야하죠. 표준이 너무 강하면 디자인의 자유도가 떨어지고, 변용이 너무 강하면 표준이 의미가 없어집니다. 브랜딩인지 마케팅인지 성능인지 사용성인지 방향성을 잘잡고 가야합니다.

주저리 주저리 적어봤지만 너무 추상적이 되어버렸네요. 컴포넌트 단위의 개발, 스타일 가이드, 디자인 시스템이 효율적인 방법론을 제공하는 것은 분명합니다만, 쓸 줄 모르는 도구는 때론 안쓰는 것만 못할 때가 있다라는 더 추상적인 말로 마무리 짓겠습니다.

'IT Tech > UX' 카테고리의 다른 글

전문가로서 가져야할 마음가짐  (0) 2017.06.12

TechTrip IT Tech/UX

Angular Test Tips (Mock)

2019. 6. 1. 15:35

한동안 개발 잉여력이 떨어져서 오래 쉬었네요.

회사에서 바쁘면 집에서 개발을 덜하게 됩니다.

개발을 천천히 하니 글 쓸 일을 더욱 없다는게...

 

그렇다해서 지금 바쁘지 않다는건 아니지만.

더 밀리면 안쓰고 넘어갈 것 같아서 기록합니다.

기록하다보면 더 정리되는 기분도 있구요.

 

TDD를 연습하자는 취지로 진행중인데,

소스가 많아질 수록 점점 Test가 어려워집니다.

Angular 또한 예외는 아니구요.

 

그 어려움을 덜어낸 방법 2가지 공유합니다.

 

1. Component Mocking

 

자식(Child) 컴포넌트를 포함하는

부모(Parent) 컴포넌트를 테스트하다보면

점점 테스트 설정이 무거워집니다.

 

부모 컴포넌트의 의존성 뿐 아니라

자식 컴포넌트의 의존성을 모두 주입해야하니까요.

그래서 자식컴포넌트를 Mock으로 주입하고

자식의 의존성은 생략해버리는 것이 유용합니다.

 

제 프로젝트는 아래와 같은 포함관계가 있습니다.

Budget > Calendar > Day Component

Budget 컴포넌트의 테스트가 비대해지는 중이죠.

그래서 Calendar 컴포넌트를 Mock을 했습니다.

의존성도 덜어냈구요.

그 방법은 아래와 같습니다.

 

1) Mock 컴포넌트의 선언

 

테스트(spec.js)에 가짜(Mock) 컴포넌트를 선언합니다. 실제와 동일한 selector를 가지도록 말이지요. Input, Output과 같이 테스트가 필요한 부분은 포함합니다.

...
@Component({
  selector: 'app-calendar',
  template: 'mock calendar'
})
class MockCalendarComponent {
  @Input('date') date: Date;
  @Output('dateChange') dateChange: EventEmitter = new EventEmitter();
}

 

2) Mock 컴포넌트의 사용

 

하위 컴포넌트를 추가해주었던 declarations에 선언해준 Mock 컴포넌트를 넣습니다.

describe('BudgetComponent', () => {
  let component: BudgetComponent;
  let fixture: ComponentFixture;
  let testableDailyExpenseState: Observable;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [BudgetComponent, MockCalendarComponent],
      imports: [
      ...
      ])]
    }).compileComponents();
  }));
  ...

 

이제 Calendar나 Day 컴포넌트의 의존성은 Budget 컴포넌트의 테스트에 더이상 필요가 없습니다.

자식 컴포넌트를 위한 설정 코드들도 덜어집니다.

 

2. Override Private Property

 

사실 이 방법은 좋은 방법은 아닙니다.

부득이하게 쓸 경우가 있어서 정리해둡니다.

NGXS를 쓰다보니 테스트가 난해하더군요.

Store 값을 변경하기가 까다로워서요. 

 

Selector로 가져오는 값이 private이기 때문.

Javascript의 Object.defineProperty를 이용했습니다. 이미 component에 정의된 속성을 수정하고 테스트용 값을 넣어주는 방식입니다.

beforeEach(() => {
    ...
    Object.defineProperty(component, 'dailyExpense$', { writable: true });
    let dailyExpenseState = {
      //test data
      ...
    }
    testableDailyExpenseState = of(dailyExpenseState)
    component.dailyExpense$ = testableDailyExpenseState;
    ...
  });

위와 같이 component의 private 속성에

원하는 테스트 값을 넣는 것이 가능합니다.

 

위와 같은 방법을 이용하여 Angular의 테스트를 조금 더 수월하게 하였습니다.

 

Angular 테스트 코드가 점점 무거워지고,

수많은 의존성과 설정에 불편하신 분들께

도움이 되었으면 좋겠습니다.

 

전체 소스는 아래 github에서 보실 수 있습니다.

소스주소: https://github.com/jsrho1023/account-book

'IT Tech > Angular' 카테고리의 다른 글

Angular Dialog(Material Design)  (0) 2019.01.01
Angular Component Communication (Output)  (0) 2018.12.16
Angular Component Communication (Input)  (0) 2018.12.02
Angular Test Headless  (0) 2018.11.18
Angular Pipes  (0) 2018.11.12

TechTrip IT Tech/Angular

NodeJS 개발 시 Mocha 테스트 디버깅

2019. 2. 23. 18:49

Express를 이용한 API 서버를 개발중입니다.

Express는 JS(JavaScript) 프레임워크 입니다.

Mocha를 이용한 단위테스트를 하고 있죠.


Java나 C#과 달리 디버깅이 까다롭더라구요.

Mocha 구동 시 옵션을 넣어주어야합니다.

그리고 Chrome을 사용합니다.


1. package.json 수정


pakage.json 파일을 수정합니다.

npm 스크립트에 debug 옵션을 넣었죠.

"scripts": {
  "test": "./node_modules/.bin/mocha --recursive --exit",
  "debug": "./node_modules/.bin/mocha --recursive --inspect-brk"
}

물론 npm run을 사용하지 않아도 됩니다.

mocha에 옵션을 주어 직접 실행도 가능해요.


2. 테스트 코드에 debugger 추가


디버그를 하고 싶은 위치에 코드를 넣습니다.

Chrome 디버거가 멈출 위치에요.

it('...', function () {
  ...
  const expenseController = new ExpenseController(mockDailyExpense);
  expenseController.saveDailyExpense(request, response);
  debugger
  
  saveDailyExpenseStub.calledOnceWithExactly(...);
  saveDailyExpenseStub.restore();
})


3. npm run debug


디버그 스크립트를 실행합니다.

npm run debug

만약 package.json을 수정하지 않았다면

mocha를 직접 실행하는 것도 가능합니다.

mocha --inspect-brk '파일명'

그러면 아래와 같은 문구가 나옵니다.


Debugger listening on ws://127.0.0.1:9229/...

For help see https://nodejs.org/en/docs/inspector


4. Chrome 실행 (chrome://inspect/)


크롬을 실행해서 주소창에 아래를 입력합니다.

chrome://inspect

node 테스트가 실행 중인 것이 보입니다.


chrome inspect 실행 화면


5. inspect 클릭 후 Debug


inspect를 클릭하면 디버거 창이 실행됩니다.

테스트가 시작되지 않고 멈춰있죠.

실행을 시키면 테스트가 시작됩니다.

그리고 debugger 위치에서 멈추게 되지요.


Chrome 디버그 화면

익숙한 사용 경험으로 충분히 디버깅이 됩니다.

Control 영역을 통해 코드 진행이 가능하구요.

Scope에서 변수들의 값 확인이 가능합니다.

Console 창에서 코드 입력/실행도 됩니다.


nodeJS 테스트가 막힌다면 큰 도움이 되실거에요.

문제를 훨씬 빠르게 파악하는 것이 가능하답니다.

TechTrip IT Tech/NodeJS

Angular Dialog(Material Design)

2019. 1. 1. 23:24

이번에는 Material Dialog를 추가해보겠습니다.

Dialog는 아래와 같이 동작합니다.


Dialog 동작화면


부모창이 어두워집니다. (dimmed)

모달(modal) 창이 뜨고 입력한 값이 부모로 전달되죠.


Material의 장점은 역시 미리 구현된 동작입니다.

 - 모달(modal)과 부모 컴포넌트간 데이터 전달

 - 모달(modal) 이외 영역 클릭시 닫기

 - ESC로 창닫기

 - 웹접근성 고려(자동 포커스)

   (창을 닫고 아이콘이 포커스 되는 그 부분)


그럼 코드로 살펴보겠습니다.


1. Import MatDialogModule


app module에 MatDialogModule을 추가합니다.

@angular/material 모듈에 포함되어있습니다.

import { MatDialogModule } from '@angular/material';
...

@NgModule({
  ...
  imports: [
    ...
    MatDialogModule,
    ...
  ],
  ...
})
export class AppModule { }


2. Dialog Component 생성


Dialog에 구성될 화면을 만듭니다.

저는 컴포넌트를 따로 분리하였습니다.

컴포넌트 생성은 굉장히 쉽죠?

(ng g c '이름' Angular 새로 Component 만들기)


Dialog는 부모 컴포넌트로 data를 전달합니다.

MatDialogRef 라는 의존성을 주입합니다.

(여기서 설명했었죠? Angular Service 만들기)

import { Component } from '@angular/core';
import { MatDialogRef } from '@angular/material'
...

@Component({
  selector: 'app-consumption',
  templateUrl: './consumption.component.html',
  styleUrls: ['./consumption.component.css']
})
export class ConsumptionComponent {

  constructor(private dialogRef: MatDialogRef) { }
  ...
  
  onCancel(){
    this.dialogRef.close();
  }

  onSave(){
    const returnData = {
      amount: this.consumptionForm.controls.amount.value,
      desc: this.consumptionForm.controls.desc.value
    }
    this.dialogRef.close(returnData)
  }
}

cancel 버튼과 save 버튼에 이벤트를 연결했죠.

dialogRef의 close 메서드에 data를 전달합니다.

화면 Template은 생략하겠습니다.

그저 Form 컨트롤일뿐.

(Angular Forms)


3. Dialog Component Factory에 등록


그럼 생성해준 Dialog는 동적으로 만들어집니다.

이런 컴포넌트들은 다른 설정이 필요해요.

app module에 entryComponents 라는 것이죠.

...

@NgModule({
  ...
  entryComponents: [
    ConsumptionComponent
  ],
  ...
})
export class AppModule { }

위와 같은 설정으로 Dialog를 그릴 수 있게됩니다.

Component Factory에 추가가 되기 때문이죠.


4. Dialog 표출


부모 컴포넌트에서 Dialog를 보여주면 됩니다.

아래와 같이 가능합니다.

import { MatDialog } from '@angular/material';
import { ConsumptionComponent } from '../consumption/consumption.component';
...

@Component({
  ...
})
export class BudgetComponent implements OnInit {
  ...
  constructor(public store: Store, public dialog: MatDialog) { }
  ...

  onAdd() {
    const dialogRef = this.dialog.open(ConsumptionComponent, {
        width: '250px'
    });

    dialogRef.afterClosed().subscribe(result => {
        if (result) {
            let amount: number = Number(result.amount);
            let desc: string = result.desc;
            this.addConsumption(new Consumption(amount, desc));
        }
    });
  }
  ...
}

MatDialog 의존성 주입이 되었구요.

(여기서 설명했었죠? Angular Service 만들기)

MatDialog의 메서드를 호출해주면 됩니다.

open이라는 메서드입니다.

dialog에 사용할 컴포넌트와 정보를 넣었죠.

width이외에 data도 전달할 수 있습니다.


open 메서드는 dialogRef를 리턴합니다.

dialogRef를 이용해 닫혔을 때 동작을 정의합니다.

observer 패턴이에요.

result라는 객체로 dialog에서 전달한 값을 받습니다.


조금 복잡하지만 크게 수고를 덜 수 있습니다.

물론 디자인을 변경하려면....

나중에 필요해지면 해보도록 하죠.


전체 소스는 아래 링크에서 볼 수 있습니다.

https://github.com/jsrho1023/account-book

'IT Tech > Angular' 카테고리의 다른 글

Angular Test Tips (Mock)  (0) 2019.06.01
Angular Component Communication (Output)  (0) 2018.12.16
Angular Component Communication (Input)  (0) 2018.12.02
Angular Test Headless  (0) 2018.11.18
Angular Pipes  (0) 2018.11.12

TechTrip IT Tech/Angular

Angular Component Communication (Output)

2018. 12. 16. 19:30

지난 번에는 부모(Parent)에서 자식(Child)으로 

Input을 통해 데이터를 전달하였습니다.

Angular Component Communication (Input)


이번에는 반대로 자식에서 부모

Output을 통해 데이터를 전달해보겠습니다.


달력 컴포넌트에서 날짜를 선택하면

부모 컴포넌트로 선택한 날짜를 전달할게요.


1. Import Output, EventEmitter


자식에서 부모로 이벤트를 전달하는 형태에요.

Output과 EventEmitter 모듈을 사용합니다.

angular/core 모듈 안에 있습니다. 

import { ... Output, EventEmitter } from '@angular/core';
...
@Component({
  selector: 'app-calendar',
  templateUrl: './calendar.component.html',
  styleUrls: ['./calendar.component.css']
})
export class CalendarComponent implements OnInit {
  ...
}


2. Output 정의 및 emit 함수 생성


Input과 비슷한 형태의 어노테이션을 사용합니다.

괄호 안에 부모로 전달할 이벤트 이름을 적습니다.

그리고 EventEmitter 타입으로 초기화했어요.

마지막으로 날짜 선택 이벤트를 부모로 전달할 함수를 만들었습니다.

참고로 selectDay는 날짜 click과 연결된 메서드입니다.

...
@Component({
  ...
})
export class CalendarComponent implements OnInit {
  ...
  @Output('dateChange') dateChange: EventEmitter = new EventEmitter();
  ...
  selectDay(day){    
    ...
    this.dateChange.emit(new Date(this.selectedYear, this.selectedMonth, day));
  }
  ...
}


3. 부모 템플릿에서 Event Binding


자식에서 전달하는 Event를 부모에서 받도록 해줍니다.

이벤트 바인딩과 동일하게 설정하면 됩니다.

데이터는 $event에 담겨 전달됩니다.

<div class="budget">

    <app-calendar [date]="date" 
         (dateChange)="onDateChange($event)"></app-calendar>
    ...
</div>

이벤트를 부모 컴포넌트의 함수와 연결해주었습니다.

전달되는 $event를 콘솔에 찍도록 했죠.

원했던 데이터가 전달되는 것을 확인할 수 있습니다.


Output 동작화면


전체 소스는 아래 주소에서 확인가능합니다.

https://github.com/jsrho1023/account-book

'IT Tech > Angular' 카테고리의 다른 글

Angular Test Tips (Mock)  (0) 2019.06.01
Angular Dialog(Material Design)  (0) 2019.01.01
Angular Component Communication (Input)  (0) 2018.12.02
Angular Test Headless  (0) 2018.11.18
Angular Pipes  (0) 2018.11.12

TechTrip IT Tech/Angular