[정원사 프로젝트] 5. 테스트와 리팩토링 하기

정원사 프로젝트 회고, 사용자 테스트와 개선, 리팩토링하기

Posted by yoogomja on June 22, 2020

프로젝트 회고 글타래

1. 테스트 하기

1차 완성을 했을때, 첫 커밋으로부터 1달 가량이 지난 뒤였다. 어느정도 처음 기획에서 예상했던 기능들은 전부 마무리가 되었었고, 이제 기능들이 잘 동작하는지 테스트할 차례였다. 테스트 케이스를 만들어서 진행하지는 않았고, 당초에 예상했던 작업 흐름대로 테스트해볼 요량이었다.

1.1. 내부 테스트 하기

이 당시에 테스트는 사실 2번째 테스트가 되었는데, 백엔드 작업을 1차적으로 완료한 후에 이미 모든 API를 예상 작업 순서대로 테스트를 거쳤기 때문이었다. 백엔드 테스트는 다음과 같은 순서였다.

  1. 작업 순서대로 API를 실행
  2. 만약 해당 순서의 API에 파라미터가 필요한 경우 파라미터를 누락시키고 테스트
  3. 만약 해당 순서의 API에 선행 데이터가 필요한 경우 누락시키고 테스트

위와 같은 경우로 예상되는 범위에서 테스트를 거쳤고 오류를 발견하면 1차 수정한 뒤에, 프론트엔드 작업에 들어갔기 때문에 어느정도 방어는 되어있는 상황이었다. 다만, 프론트엔드의 화면 구성이 작업하면서 백엔드 코드도 조금 달라진 부분도 있었기에 양쪽 다 테스트가 필요한 상황이었다.

그래서 위와 같이, 다시 한번 작업 순서대로 화면을 순회하면서 테스트를 거치게 되었다. 화면 테스트에서는 백엔드 테스트와 달리 좀 더 신경써야할 부분이 있어서 까다로웠다. 대부분 비동기 통신과 반응형에 대한 부분이 걸림돌이 되었고, 수정까지 몇 일을 소모한 경우도 더러 발생했던 듯 하다. 테스트와 수정까지 한 주정도 추가로 소모하고 내부 테스트를 1차 적으로 종료하기로 했다.

1.2. 외부 테스트 하기

내부 테스트와 수정을 1차적으로 마친 뒤에는 실제 사용할 동아리원들의 일부에게 테스트를 부탁했었다. 이제 혼자 작업하는데에 익숙해져 놓치는 부분이 많으리라 생각했기 때문이다. 테스트를 마치고나서 몇 가지 오류 사항과 개선 사항에 대한 피드백이 왔었는데, 꽤 작업 시간이 소요되는 피드백이 있었다. 주요한 사항은 다음과 같았다.

  1. 회원을 추가 / 삭제하는 것이 당사자만 가능할 것
  2. 프로젝트를 관리하는 것은 특정 관리자 사용자만 가능할 것
  3. 프로젝트에 등록하는 것이 관리자 인가를 통해 가능하게 하거나, 별도의 인증을 받도록 할 것

다양하고 자잘하게 발생한 개선/수정 사항들은 그냥 작업하면 됐지만 위의 경우들은 조금 달랐다. 기존에 사용자들은 따로 데이터 베이스에서 관리되고 있긴하지만, 로그인 같은 본인을 증명하는 과정이 없었다. 사실 내부에서 사용할 요량으로 굳이 만들어두지 않은 것이 컸는데, 삭제에 관해서는 특히 필요한 기능이라고 비춰졌다. 그래서 이 개선 사항을 기점으로 로그인 기능을 구현할 계획을 세울 예정이었다.

두번째 요구사항도 일리있는 이야기 였다. 프로젝트에 참여할 때에, 동기 부여 혹은 참여하기 위한 강제력이 약간은 필요하다고 판단되어서 동아리 내부적으로는 소정의 보증금과 미출석시 벌금을 받도록 규칙을 정하고 있었다. 적은 돈이지만 그래도 돈이 얽혀있는 만큼 벌금 관리를 위해서는 프로젝트의 일정 관리와 참여 인원 관리에 엄격할 필요가 있었다.

우선 특정 사람들만 프로젝트를 관리할 수 있게 하는 기능은 어렵지 않았다. 기존의 사용자 테이블을 회원 형식으로 변경하게 되었으므로 복잡하게 생각하지 않고 관리자 권한에 대한 정보만 추가하기로 했다.

다만 프로젝트에 등록할 때 관리자의 인가를 거치도록 해야했으므로, 프로젝트 등록을 바로 진행하는 것이 아니라 프로젝트 요청에 대한 컬렉션이 별도로 필요하게 되었다. 이런 몇가지 요구 사항이 생겨서 백엔드에서도 화면에서도 대대적인 수정이 필요하게 되었다.

2. 개선사항 적용과 리팩토링 하기

2.1. 백엔드 개선 사항 적용하기와 리팩토링

화면 레벨에서도 대대적인 공사가 진행 될 예정이었지만, 백엔드에서도 만만찮은 대공사가 예정중이었다. 우선 회원 기능을 구현하는 것이 최우선 과제였다.

기존에는 사용자 추가를 위해서 github 사용자 이름만을 추가하면 되었었는데, 그 과정을 githuboauth 앱을 별도로 만들어 관리하기로 결정했다.

처음에는 그냥 내부 사용자 계정 컬렉션을 별도로 만들어주고 거기에 연결되는 깃허브 계정과 정보를 따로 관리할까 생각도 했었다. 다만 그러기엔 내부 사용자 계정 정보와 github 계정 정보 사이에 겹치는 항목이 많았고 해당 서비스 자체가 github에서 발생하는 이벤트들을 추적하는 서비스이다 보니 분리할 필요가 없다고 생각되었다. 그렇기에 회원 정보도 github에서 가져오고 로그인도 oauth앱에 모두 맡기는 것으로 결정했다.

그렇게 변경된 등록 과정에는 몇 가지 준비가 필요했다. oauth앱을 미리 만들어 두어야했고, 로그인 처리를 위해 passport라는 패키지를 별도로 설치해 두어야했다. 그 과정에서 passport의 작동 과정을 다시 공부해야 했고, 로그인을 구현하기 위해서 express의 세션에 대해서도 공부해둘 필요가 있었다.

생각보다 과정이 오래걸리지는 않았고 passport-github stretegy도 만들어져있었기 때문에, 구현에는 많은 시간이 걸리지 않았다. 그 후 관리자 권한을 추가하는 것도 필드를 하나 추가하기만 해주었기 때문에 데이터베이스와 로그인 기능 구현 자체는 오래 걸리지 않았다.

로그인을 구현하는 일보다 어려웠던 점은, 관리자 권한이 필요한 API들을 일일히 수정하는 일이었다. 그 과정에서 로그인에 대한 추가적인 API도 필요하게 되었고, 사용자의 로그인 여부를 확인하는 등의 추가 작업들이 계속해 추가되게 되었다.

그에 더해, 관리자 권한이 필요한 경우를 분류하고 관리자 권한에 관련된 API들도 만들어야 했다. 이 과정에서 관리자 권한에 대한 별개의 로직과 컬렉션이 추가될 필요가 있었다.

첫번째는 관리자 추가에 관한 부분이었다. 관리자를 처음 추가하는 경우와 지속적으로 관리자를 늘려나가는 과정을 약간 복잡하게 만들어둘 필요가 있다고 생각했다. 그래서 내린 결론은, 관리자에 등록하기 위한 토큰을 발행하자는 것이었다.

토큰은 한번 만들 때 랜덤한 문자열로 만들어두고, 만들면 한 시간정도의 유효시간을 두며, 한 토큰에 한명의 관리자만 등록 가능하도록 했다. 해당 토큰으로 등록된 관리자는 기록으로 남겨두는 기능도 준비해두었었다. 그리고 이 토큰은 관리자만 생성할 수 있도록 설정해두었었다.

최초의 관리자 계정은 서버를 최초 실행 시에 미리 만들어둔 설정파일에 secret 문자열을 토큰으로 삼기로 했다. 기존에 secret 문자열로 만들어진 토큰이 존재하지 않을때만 생성하도록 하고, 유효 기간은 최초 등록에 문제가 없도록 널널하게 1년이나 주어지도록 해두었었다.

이렇게 하니 최초 관리자 등록에도 큰 어려움은 없었고, 추가적인 관리자 등록도 꽤 까다로운 방식을 거치게 되었지만 그래도 관리자 권한으로 할 수 있는 일이 꽤 많았기에 문제 없다고 생각했다.

그 후, 프로젝트마다 사용자가 참가 요청을 할 수 있도록 컬렉션을 별도로 만들어두었고, 관리자만 확인할 수 있는 요청 확인 페이지에 필요한 API를 제작하게 되었다. 이 과정에서도 꽤많은 기능이 추가되게 되었다.

이 과정을 거치면서 route에서 권한 관련 항목들을 수정하다보니 route함수들을 대대적으로 수정하게 되는 일이 잦아져서 겸사겸사 주소를 정리하고 리팩토링하기 시작했다. 통일되지 않은 일부 response들은 형태를 통일시켜주고, 사용하지 않는 함수들을 찾아 삭제하거나 중복된 코드들을 합쳐주었다. 그러고 나니 꽤 시간이 소요되었지만, 코드 자체는 좀 더 깔끔하게 정리할 수 있었다.

2.2. 프론트 엔드 리팩토링 & 개선 사항 적용하기

백엔드 개발을 마치고 나서 프론트엔드에도 대대적인 수정이 예정되었다. 로그인 기능이 필요하게 되었고, 관리자 페이지가 2페이지나 더 필요하게 되었다. 기존 페이지도 대거 수정이 필요하게 되어 손을 대려고 계획을 세우다보니, 개발하면서 아쉬웠던 부분들이 눈에 띄기 시작했다.

특히 flex에 대한 이해가 페이지 작업하면서 비교적 많이 늘어나게 되어서 구조를 변경하고 싶은 마음이 생기게 되었고, 파일 구조도 변경하고 싶은 마음이 좀 컸다. 그래서 리팩토링 아닌 리팩토링을 하기 위해 클라이언트 코드를 새로 생성하기로 결정하기에 이르렀다.

2.2.1. 리팩토링 하기

처음 리팩토링을 할 당시에 내가 생각했던 문제점은 다음 같은 몇가지 였다.

  1. styled componentscss가 산재 되어있다.
  2. interface의 명명이 불확실하다
  3. 컴포넌트화 되어있지 않은, 반복 사용하는 UI 요소들이 있다.

1번 문제점은 개발 초기에 react의 스타일링에 대한 결정을 하지 못한 탓이 크다. react-native에서 사용하던 방법을 사용하다가 애니메이션을 다루는데 어려움을 겪으면서 scss로 전환한 것이 이유였다. 그 이후 scss를 사용한 이후로도 계층 구조 이외에는 사용법에 익숙하지 않았기 때문에, mixin이나 변수, 함수 사용이 자유롭지 못했다.

그래서 이번엔 미디어 태그 등은 모두 믹스인으로 미리 선언해두고 include해 사용하는 방식으로 변경했다. 컬러도 중구난방으로 사용되고 있었기 때문에, 변수 파일을 분리해 불러와 사용하도록 변경했고, 특정 사이즈 등의 변수들도 미리 선언해 상수처럼 사용하도록 했다. 이 작업이 선행된 후에는 꽤 수월하게 작업이 되었다.

2번 문제점은 해결법은 간단했지만, 해결하기 전까지 문제점이 꽤 컸다. interface로 선언해둔 대부분의 데이터 원형들은 나중에 인스턴스를 생성하는 경우가 대다수였다. 그 경우 interface이름을 User라고 지었다면, 인스턴스의 이름도 user가 되는 경우가 종종 발생했다. 대소문자로 구분할 수 있겠으나, 그것으론 코드에서 불확실하게 사용되는 경우가 더러 발생했던 것이다.

그래서 변수명앞에 interface라고 알수있도록 IUser같은 식으로 접두사를 붙이기로 했다. 작업을 할 때 타입을 변수명앞에 붙이는 일은 타입이 구분되지 않는 일반 자바스크립트에서 많이 사용했었는데, typescript를 사용하면서 부터는 별로 사용하지 않고 있었다. interface는 작업중에 혼란이 자주 생겨서 불가피하게 추가하게 되었다. 예외를 둔 것 같아 기분은 좋지 않았지만, 확실히 구분이 되어서 후에 작업하면서 굉장히 편해졌다.

3번 문제점은 코드 전반에 퍼져있는 문제점이었다. UI를 구성하면서 애니메이션 효과가 있는 text input을 만들어서 썼는데, 꽤 괜찮아서 다른 곳에서도 사용하게 되었다. 그 당시에 컴포넌트화 시켜두지 않았더니 같은 기능이 다른 코드나 다른 클래스를 가져, 스타일도 코드도 반복 선언되는 경우가 생겼다. 꽤 큰 문제였기 때문에, UI를 재구성하면서 공통되는 부분을 미리 컴포넌트화하고, 반복될 것으로 예상되면 우선 컴포넌트로 분리하는 과정을 거치도록 했다.

2.2.2. 개선 사항 적용하기

개선 사항의 가장 큰 변화 점은 로그인 기능과 관리자 기능이었다. 두 가지 기능이 추가되면서 많은 로직이 추가되었다. 꽤 많은 페이지에 변경사항이 적용될 예정이었고, 새로 작업될 페이지도 많아 기존 코드를 리팩토링하면서 프로젝트를 새로 시작하는 것으로 결정했다.

우선, 로그인된 사용자의 정보를 표기해줄 메뉴가 별도로 필요하게 되었다. 이 덕분에 navbar가 대폭 수정되었다. 원래는 메뉴만 표기해주던 클라이언트가 로그인 버튼, 로그아웃 버튼을 포함하고, 간단한 사용자 프로필도 표기해주도록 변경되었다. 다만 이 UI는 PC에서는 따로 보여주지 않고 모바일에서만 표기하도록 작업했다. 이외에도 대시보드 페이지에서도 로그인 정보를 표기하는 화면이 필요하게 되었다. 로그인 사용자 정보를 redux로 항상 가지고 있어야 되는 상황이 생긴 것이다.

이 외에도 로그인된 사용자만 대시보드에서 프로젝트 참여 요청을 할 수 있었기 때문에, 화면에서도 로그인 여부를 알고 있어야했다. 이렇듯 몇가지 페이지에서 로그인을 거쳐야 확인할 수 있는 정보들이 포함되어야 했기 때문에, 로그인이 되어있지 않다면 리다이렉트 하는 코드를 공통적으로 사용해주어야 하는 경우가 생기게 되었다.

관리자는 조금 더 일이 많았는데, 우선 관리자 권한을 얻는 페이지가 필요했다. 관리자 권한은 서버에서 자동 생성하거나, 다른 관리자가 생성한 토큰을 입력해 관리자 권한을 얻도록 하는 방식이었는데 이 과정을 위해서는 토큰을 새로 생성하고 삭제하고 토큰의 사용현황을 볼 수 있는 토큰 관리 페이지가 필요하게 되었다.

그 외에도 프로젝트 관리 페이지가 관리자 권한이 있는 회원만 접근할 수 있도록 변경되었고, 프로젝트 참여 요청을 관리할 수 있는 페이지도 별도로 생성하게 되었다. 당초에 생각했던 페이지들 보다 2배 정도가 늘어나게된 셈이라, 작업하면서 조금 당황했던 기억이 난다.

그리고 작업하며 있으면 좋겠다고 생각했던 몇 가지 기능을 추가했었다. 사용자의 활동 내용을 활성화된 하나의 프로젝트에 대해서만 확인할 수 있었던 것을 모든 프로젝트에 대해서 하나하나 확인할 수 있도록 변경한다던지, 기존에는 어떤 커밋을 했는지 같은 정보는 공개하지 않았는데 본인의 커밋 로그까지도 확인할 수 있는 기능을 추가한다던지 하는 식이었다.

정리하기

테스트를 거치고 리팩토링을 진행하면서 개발하는 과정만큼 많은걸 배우게 되었다. 역시 혼자 개발하고 테스트하는 것보다는, 다른 사람들의 테스트를 참고하는 일이 훨씬 더 시야를 넓혀줄 수 있다는 것을 다시 한번 확인하게 되었다. 리팩토링에서도 처음에는 예상하지 못했던 문제들을 맞닥들이게 되면서 해결방안으로 생각만 해두었던 것들을 바로 적용하고 실효성이 있는지 확인 할 수 있었기 때문에 꽤 큰 수확을 얻었다고 생각한다.