210404 Vanilla JavaScript TDD Practice

Vanilla JavaScript TDD

210405 Update

이번 포스팅에서는 TDD방식으로 Vanilla JavaScript를 사용해서 개발을 하는 방법에 대해서 실습한 내용을 기반으로 블로그 포스팅을 해보려고 한다.

처음에는 이 TDD방식이 익숙하지 않아서 느릴지 모르지만 이런 과정이 견고한 Logic을 만들게 되고, 결국에는 개발속도가 빨라지는 결과를 낳게 된다고 한다.
여기서 포인트는 익숙해지는 것! 개발자 커뮤니티에서 어떤 개발자 분이 말씀하셨는데 "개발의 가장 좋은 실력향상 방법은 반복"이라고 하셨다. 누군가로부터 무언가 새로운 것을 배웠을 당시에 이해를 한 것처럼 착각하고 마치 내 것이 된거마냥 생각하는 사람들이 많은 것 같다. 이러한 개인적인 반복학습 없이 한 두 번 더 본다고 절대 내 것이 되었다고 볼 수 없다.

내가 이렇게 블로그에 배웠던 내용을 정리하고, 필기했던 노트를 첨부하는 이유는 반복학습을 위해서다.
이 TDD 방식 또한 처음에 적용할때 시간이 오래 걸린다고 생각하지 말고 스스로 생각하고 반복을 하면서 내 것으로 만들도록 노력을 해야겠다.

본론

개선전 코드
아래의 코드에는 문제가 많다. Increase button에는 여러 관심사들이 혼재되어 있다. 단순히 화면에 버튼을 출력하지 않고, click event가 binding되어있다.
또한 JavaScript 코드를 보면 count라는 변수를 전역 스코프에 작성을 하였다. 이는 변수이름이 충돌할 위험을 증가시킨다.
그리고 카운트 수를 출력할 span 태그의 id를 hard coded한 방식으로 작성을 해서 DOM element를 가져오고 있다. 만약에 markup이 변경된다면 변경된 id에 맞춰서 작성한 id를 JavaScript 코드에서 수정해줘야 한다.

아래의 간단해보이는 코드에는 위와같은 복합적인 문제들이 혼재되어있다.

Read More

210404 JavaScript module pattern


이번 포스팅에서는 JavaScript에서 문제해결 패턴으로 가장 많이 사용되는 module pattern에 대해서 포스팅을 하려고 한다.
이 module pattern은 JavaScript의 코드 관리 기법 중 하나로 함수로 데이터를 감추고, 모듈 API를 담고 있는 객체를 반환하는 형태로 코드를 작성하며, JavaScript의 특성상 객체를 핸들링하기 위한 방법론 중 하나이다.
JavaScript의 모듈 패턴은 유효범위를 지정하는 언어와 같이 private, public 등의 캡슐화를 사용하는 방법이라고 볼 수 있다.
그리고 module pattern에는 두 가지 패턴이 있는데 임의 모듈 패턴즉시 실행 함수(IIFE) 모듈 패턴(Singleton instance)이 있다.

아래 임의 모듈 패턴과 즉시 실행함수 모듈 패턴(IIFE)를 보면 가장 첫 줄에 namespace pattern이 사용이 되었는데 이는 자바스크립트에서 함수 또는 변수 객체를 다룰때 중복된 이름의 사용으로 인한 문제를 방지하기 위한 것이다.
global영역에 객체 고유의 영역을 지정하고 변수와 함수의 할당을 해당 namespace의 하위로 두게 해서 중복된 이름으로 인한 오류를 예방하는 방법이다.
(즉 모듈패턴이란 이 namespace pattern에 언어적 유효범위를 추가해놓은 것이라고 이해하면 된다)

namespace 패턴

1
2
3
4
5
6
7
var App = App || {}; // declare namespace
App.getName = function () {
return 'hyungilee';
};
App.hello = function () {
return 'hello';
};

임의 모듈 패턴 : 임의 함수를 호출하여 생성하는 모듈

여러 객체가 필요한 경우에 사용되는 패턴 방식이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// namespace 만들기
var App = App || {};
// namespace에 함수를 추가. 의존성있는 God function을 주입
// Person이라는 module(함수)를 넣어준다.
App.Person = function (God) {
// God module이 name을 생성하는 역할을 한다.
// God module을 통해 생성한 name값을 변수에 초기화한다.
var name = God.makeName();

// API 노출 (getter, setter 함수를 가지는 객체를 반환)
return {
getName: function () {
return name;
},
setName: function (newName) {
name = newName;
}
};
};

const person = App.Person(God);
person.getName();

Read More

210404 Sliding window + Map + Two pointer algorithm 문제풀이

Anagram

이번 포스팅에서는 Sliding window, Map, Two pointer algorithm을 복합적으로 사용하여 풀이한 알고리즘 문제에 대해서 정리를 해보려고 한다.

효율성을 전혀 고려하지 않은 이중 for문의 사용을 자제하고 앞의 세 가지 개념을 활용하여 코드를 구현한다면 효율성을 극대화시켜서 코드를 작성할 수 있을 것이라고 생각한다.

우선 하나의 문제를 예시로 내가 처음에 구현한 코드와 다른 사람이 구현한 코드 두 가지를 비교분석해보자.

문제는 문자열 S와 T가 주어졌을때 문자열 S에서 T문자열과 아나그램이 되는 부분 문자열의 갯수를 출력하는 문제이다.

이 문제를 처음 보았을때 Sliding window, Map, Slice method를 사용하여 문제를 풀이해야 겠다고 생각했고 아래와 같이 코드를 작성했다.

우선, 아나그램인지 아닌지 판별하기 위한 개별함수를 선언(checkAnagram() function)한다.
그 다음에 초기에는 입력받은 문자열(is)를 검색 문자열(ss)의 길이만큼 slice해서 확인용 문자열 변수에 별도로 저장을 해준다.

Read More

210404 Self Development TIL

Thought of the day

게으른 행동에 대해 하늘이 주는 벌은 두가지다.
하나는 자신의 실패이고 또 다른 하나는 내가 하지 않은 일을 해낸 옆사람의 성공이다.


오늘은 06시 34분에 공부를 시작했다. 알고리즘으로 하루를 상쾌하게 시작하자. :)

TO DO LIST

  • 블로그 포스팅

    • Sliding window + Map + Two pointer algorithm 문제풀이에 대해서 블로그 포스팅하기 (완료)
    • JavaScript module pattern에 대해서 블로그 포스팅하기 (완료)
    • 진행중인 Vanilla JavaScript TDD Practice 관련 블로그 포스팅하기 (작성중)
    • 동기/비동기에 대해서 블로그 포스팅하기 (예정)
    • Closure 에 대해서 공부하고 블로그 포스팅하기 (예정)

  • 팀 프로젝트 준비(다음주 화요일 회의 예정 - 04/06(화))

    • Front-end (3명 - 실제 참여인원 2명) / Back-end (2명)
    • 주제선정 (완료)
    • 저장소 만들기(GitHub Repository) (완료)
    • 설계서 확인 후에 구체적으로 어떤 식으로 진행할지 구상하기 (예정)
    • Vanilla JS로 개발시에 필요한 Test code 작성 패턴 익히기 (Front-end) (진행중)

  • 백준 알고리즘 문제풀기

    • 기본 알고리즘 문제 10문제 풀이 (/10 완료)
      Efficiency(Two pointer algorithm, Sliding window, Hash) ~

  • TDD Practice with NodeJS

    • #Issue 10 ~ (부분 완료 - 진행중...)

    Read More

210403 Algorithm Consecutive number subsequence와 Number subsequence에 대한 이야기

Consecutive subsequence

Consecutive number subsequence(연속 부분수열)과 Number subsequence(부분수열)

이번 포스팅에서는 연속 부분수열과 부분수열에 대해서 이야기해보려고 한다.

위 두 개념에 대해서는 알고리즘 문제풀이를 하면서 접하게 되었는데, 그 풀이방법에 대해서 왠지 정리해두면 나중에 유용할 듯 싶어 블로그 포스팅하기로 했다.

우선 연속 부분수열에 대한 문제풀이에서 사용한 코드 패턴을 살펴보자.
이름에서 예상할 수 있듯이 연속된 수들의 부분집합으로 이해할 수 있다. 만약에 N개의 숫자가 주어졌을때 수들의 합이 주어진 값인 S와 같은 연속 부분수열의 갯수를 구해야 한다면 어떻게 코드 구현을 해야할까?
바로 아래와 같이 코드를 구현할 수 있다.

Read More

210403 Self Development TIL

Thought of the day

게으른 행동에 대해 하늘이 주는 벌은 두가지다.
하나는 자신의 실패이고 또 다른 하나는 내가 하지 않은 일을 해낸 옆사람의 성공이다.


오늘은 11시 50분에 운동을 하고 13시 20분부터 공부를 시작했다.
오늘은 연속 부분수열과 부분수열에 대한 문제로 하루를 시작해보려고 한다.:) 오늘 하루도 화이팅해보자.

TO DO LIST

  • 백준 알고리즘 문제풀기

    • 기본 알고리즘 문제 10문제 풀이 (5/10 완료)
      Efficiency(Two pointer algorithm, Sliding window, Hash) ~
  • TDD Practice with NodeJS

    • #Issue 10 ~ (부분 완료 - 진행중...)
  • 블로그 포스팅

    • 순차 부분 수열과 부분 수열에 대해서 블로그 포스팅하기 (완료)
    • 알고리즘 효율성에 대해서 블로그 포스팅하기(Sliding window 부분, Map은 이전 포스팅으로 대체) (완료)
    • 동기/비동기에 대해서 블로그 포스팅하기 (예정)
    • Closure 에 대해서 공부하고 블로그 포스팅하기 (예정)

    Read More

210402 Node.js TDD Practice 세 번째 이야기

beforeEach, response status code and value, mockReturnValue(), _isEndCalled(), _getJSONData()

Nodejs Mocking Http Request

beforeEach() 활용해서 공통 코드 처리하기

여러개의 테스트 코드를 작성하면서 공통된 코드가 있다면 beforeEach 안에 작성을 해서 불필요한 코드의 반복을 줄여줄 수 있다.
beforeEach의 위치는 describe의 내부와 외부 모두 가능하다. describe 단위로 공통된 코드는 describe 내부에 beforeEach를 작성해서 공통된 코드를 처리해주고, 모든 describe에 공통적으로 참조해야하는 공통 코드가 있다면 이는 describe 외부에 작성을 해서 작성한 모든 테스트 케이스에서 공통 코드를 참조할 수 있도록 해야한다.
(아래 첨부한 첫 번째 노트를 참고)

response 객체를 통해 상태값 전달하기

request 객체의 body 속성으로부터 저장할 데이터에 대한 정보를 받아 데이터베이스에 저장을 했다면 이제 제대로 저장이 되었는지, 제대로 저장이 되었다면 상태값에 대한 정보를 보내줘야 한다.
상태값은 res.status(201)과 같이 response 객체의 status로 상태코드를 인수로 넘겨준다.

테스트 코드에서는 mock response 객체의 statusCode 속성을 참고해서 전달된 상태값을 확인할 수 있다.
expect(res.statusCode).toBe(201)

response 객체를 통해 결과값 전달하기

앞서 response 객체의 status로 상태코드를 인수로 넘겨서 상태값을 전달하였다.
그렇다면 추가적으로 결과값을 전달해야될 때에는 어떻게 해야할까?
(아래 첨부한 세 번째 노트 필기 참고)

Read More

210402 Algorithm Efficiency (Two pointer algorithm, Sliding window, Hash)에 대한 이야기

알고리즘 효율성 (Two pointer algorithm, Sliding window, Hash)

Algorithm basic efficiency classes

이번 포스팅에서는 알고리즘의 효율성에 대해서 이야기해보려고 한다.

아래의 코드는 주어진 두 배열을 합쳐서 합쳐진 배열을 오름차순으로 정렬하는 문제를 구현한 코드이다.
처음에 이 문제를 보았을때 들었던 생각은 spread 문법을 사용해서 주어진 두 배열을 하나의 배열로써 unpacking한 다음에 sort() 함수를 사용해서 오름차순 정렬하는 방법을 생각했다. (solution 1)

그런데 sort()함수를 사용해서 N개의 숫자를 정렬하는 경우에는 시간복잡도 O(NlogN)만큼의 시간 복잡도를 갖는다.

그렇다면 좀 더 시간복잡도상 효율적인 코드를 작성할 수는 없을까?

단순히 결과값이 나왔다고 좋아하지 말고 좀 더 효율적인 코드를 작성할 수 있도록 생각하고 또 생각해야 한다.

Read More

210402 Self Development TIL

Thought of the day

좋아하는 직업을 택하면 평생 하루도 일하지 않아도 될 것이다.
(Choose a job you love, and you will never have to work a day in your life)

- 공자


오늘 아침도 5시 50분에 운동을 하고 07시 18분부터 공부를 시작했다.
오늘도 알고리즘 문제와 함께 하루를 시작해보려고 한다.:) 오늘 하루도 화이팅해보자.

TO DO LIST

  • 백준 알고리즘 문제풀기

    • 기본 알고리즘 문제 10문제 풀이 (3/10 완료)
      Efficiency(Two pointer algorithm, Sliding window, Hash) ~
  • TDD Practice with NodeJS

    • #Issue 9 ~ (부분 완료 - 진행중...)
  • 블로그 포스팅

    • Node.js TDD Practice 세 번째 이야기 블로그 포스팅하기 (완료)
    • 알고리즘 효율성에 대해서 블로그 포스팅하기 (부분완료)
    • 동기/비동기에 대해서 블로그 포스팅하기 (예정)
    • Closure 에 대해서 공부하고 블로그 포스팅하기 (예정)

    Read More

210401 Node.js TDD Practice 두 번째 이야기 - jest.fn() and node-mocks-http

jest.fn() Mock function

expressjs mongodb image

jest.fn()

이번 포스팅에서는 jest에서 제공해주는 Mock 함수(jest.fn())에 대해서 정리를 해보려고 한다.
mock은 한글로 직역하면 ‘모의’라는 의미를 가지며 가짜, 흉내내는 이라는 뜻을 가지고 있다.

Mock 함수는 단위 테스트를 작성할 때에 테스트하려는 코드가 의존하고 있는 부분을 가짜로 대체하는 일을 해준다.

여기서 의존하는 부분을 가짜로 대체하는 이유는 무엇일까?

의존하는 부분을 가짜로 대체하는 이유는 우선 첫 번째, 의존적인 부분을 개별적으로 구현하기 까다로운 경우가 있다. 그리고 두 번째, 의존적인 부분의 상태에 따라 테스트 결과가 다르게 나온다면 안되기 때문에 의존적인 부분에 의해 테스트 결과가 영향을 받지 않도록 해야한다.

데이터베이스의 데이터 조작을 테스트

데이터베이스의 데이터를 추가하는 부분을 테스트한다고 가정했을때, 실제 데이터베이스를 가지고 테스트를 한다면 Network, I/O task, Transaction creation, Query transmission etc...의 다양한 작업과 데이터 베이스에서 변경된 데이터를 직접 원상복귀하거나 Transaction rollback 해야하는 경우에 데이터 베이스에 데이터를 저장하는 부분 테스트에 고려해야 되는 작업이 많아 비효율적인 방법이 될 것이다.
혹여나 테스트 도중에 실 데이터베이스가 죽어버린다면 테스트 결과에 영향을 미치게 될 것은 뻔하디 뻔한 상황일 것이다.

그래서 이러한 의존적인 부분을 jest.fn()을 이용해서 가짜 함수를 생성함으로써 해결할 수 있다.

이 jest.fn() 함수는 매우 유용하게 사용될 수 있는데, 생성한 가짜 함수에 어떤 일들이 발생했는지, 다른 코드들에 의해서 어떻게 호출이 되는지 기억해주는 역할을 해주기 때문이다.

함수가 내부적으로 어떻게 사용되는지 검증할 수 있다.

구체적인 mock 함수 사용은 아래 첨부한 노트 1~2을 참고하도록 하자.

Read More