작업 동기

트위터를 즐겨 쓴다. 나름 헤비 유저다. 트위터는 옛날부터 키보드 사용자를 배려해왔다. 트위터 화면에서 J,K 키를 입력하면 화면을 아래,위로 스크롤할 수 있다. VIM 사용자 입장에서 아주 자연스럽고 쾌적하다. 그런데 가끔 딱 시야를 방해하는 그 자리에 "새 트윗 보기" 팝업이 뜬다. 일단 팝업이 뜨면 가독성이 현격히 떨어진다. 쾌적하지 못하다.

 

그림 : 문제 현상

 

해결책을 찾기 위해 노력했다. 브라우저 개발자 도구를 열고 범인을 찾았다. 그리고 해당 html 요소를 투명하게 만들면 해결 가능함을 확인했다. 하지만 트위터를 켤 때마다 개발자 도구를 열고 콘솔창에서 "화면 청소 코드"를 실행시키는 것은 사람이 할 짓이 아니었다. 이런 건 분명 기계에게 시켜야 옳은 일이다. 그리고 나만 불편할까? 이 기능을 브라우저 애드온으로 만들어 공개한다면 널리 세상을 이롭게 하는, 단군 할아버지께서 기뻐하실 만한 일이 되지 않을까?

 

그림 : 범인

 

해결책 : 트위터 화면 청소 코드

obj = document.getElementsByClassName('r-dkhcqf'); for (o of obj) { o.style.opacity = 0.1 }

 

참조 코드를 찾자

모방은 창조의 어머니. 가장 먼저 할 일은 참조 코드를 찾는 일이다. 파이어폭스를 주력 브라우저로 쓰는 입장에서 아주 그럴듯한 참조 코드를 찾았다. webextensions-examples. 이름처럼 다양한 애드온 샘플로 구성된 프로젝트다. 제시된 애드온 샘플 중에서 borderify 샘플이 내게 잘 맞는다고 생각했다. borderify 애드온은 *.mozilla.org 페이지를 표시할 때마다 붉은색 테두리를 덧붙여 표시하는 애드온이다. 특정 url에 반응한다는 점(즉 트위터 url에 반응하는 애드온을 만들 수 있다는 점)과 브라우저 컨텐트를 대상으로 스크립트를 실행한다는 점(즉 트위터 화면 청소 코드를 실행시키는 애드온을 만들 수 있다는 점)이 내가 원하던 바였다.

 

몇 차례 시행착오 끝에 애드온 소스 코드를 완성했다.

애드온 GitHub 소스 레포

 

파이어폭스 주소창에서 about:debugging을 입력하고, "임시 부가 기능 로드..." 버튼을 선택해서 manifest.json 파일을 선택하면, 브라우저에서 애드온을 실행시켜 볼 수 있다. 그렇게 애드온이 정상 동작함을 확인했다.

 

그림 : 애드온 개발 설정

 

이제 개발한 애드온을 정식 등록할 차례다. 그러면 브라우저를 실행시킬 때마다 "임시 부가 기능 로드..." 버튼을 클릭하지 않아도 된다. 그리고 집에 있는 컴퓨터 뿐 아니라 회사에 있는 컴퓨터에서도 이 애드온을 사용할 수 있게 된다. 절차는 간단했다. AMO 개발자 허브에 등록하면 된다. 소스 코드를 zip 파일로 압축해서 클릭 몇 번만 하면 등록이 완료된다. 그러면 24 시간 이내에 처리 결과를 알려주겠다는 친절한 메일이 온다. 그리고 정말 그 다음날 애드온이 등록됐다.

 

그림 : AMO에 정식 등록된 애드온

 

그림 : 파이어폭스에 정식 설치된 애드온

 

브라우저 애드온은 나름 표준 웹기술이어서 파이어폭스 애드온을 조금만 다듬으면 크롬 브라우저에서도 사용 가능하다. 크롬 브라우저를 위한 나머지 일은 다른 훌륭한 사람에게 미룬다. 브라우저로 할 수 있는 재미난 일이 더욱 많아지기를 희망한다. 웹3 세상의 주력 플랫폼은 브라우저일 것이다.

 

 

Posted by ingeeC
,

성능테스트 도구 탐색

  • JavaScript로 테스트 시나리오를 짤 수 있는 도구를 탐색
  • 몇 년 전 사용했던 Artillery와 새로 알게 된 k6를 놓고 고민
  • 미미하게 구글링 건수가 많고 (37,000건 vs 1,800건), grafana 대시보드가 멋진 k6를 선택
  • k6 프로젝트의 오너가 grafana-labs라서 grafana와의 연계가 좋을 수 밖에 없음

이런 멋진 대시보드를 실시간으로 볼 수 있음

 

사용법

  • k6를 실행하려면 influxDB와 grafana가 있어야 함
  • k6 + influxDB + grafana를 컨테이너로 실행하는 것이 가장 간편
  • k6 소스레포에서 docker-compose.yml 파일을 제공함  
git clone https://github.com/grafana/k6 && cd k6 
git submodule update --init 
docker-compose up -d influxdb grafana
docker-compose run -v $PWD:/scripts k6 run /scripts/myscript.js

 

테스트 스크립트 작성

  • k6 자체는 go 언어로 작성됨
  • k6에서 실행되는 테스트 스크립트는 JavaScript로 작성함
  • 테스트 스크립트는 반드시 default function을 export 해야 함
  • 해당 function을 k6가 생성하는 VU(virtual user)들이 실행함
import http from "k6/http";

export default function() {
    let response = http.get("https://test-api.k6.io");
};

 

실행 팁

  • grafana 커뮤니티에서 만든 대시보드들 중 4411 추천
  • k6 성능테스트 도중 "The flush operation took higher than the expected set push interval" 에러를 만남
    ==> influxDB에 테스트 지표를 write 하는 시간이 지연되어 발생하는 에러
    ==> 테스트 결과 분석에 필요한 지표만 SystemTags로 지정해서 influxDB의 지표 수집 부담을 줄여준다
export let options = { 
   vus: 4, 
   stages: [ 
     { duration: "30s", target: 32 }, 
     { duration: "60s", target: 32 }, 
     { duration: "30s", target: 4 }, 
   ], 
   systemTags: ['status', 'http_req_duration'], // <== 이거!
};

 

Ref

https://k6.io/blog/k6-loves-grafana/

  • k6 실행 방법과 대시보드 설치 방법을 간결하게 설명

https://github.com/grafana/k6

  • k6 소스레포 (README 내용 좋음)

https://k6.io/docs/

  • k6 공식 문서

 

Posted by ingeeC
,

웹 프론트엔드 TDD?

Dev 2022. 3. 14. 09:06

2020.10.15.

어찌어찌 프로젝트가 살아남았고 간단한 Admin 포털을 또 만들 기회가 있었다.

지난번에 이어 이번에도 개발 소감을 요약해본다 (2020.10.15. 기준).

 

개발환경: win10 좋다
- OS: win10 + wsl + windows terminal
- tool: vim, tmux, nodejs, vue-cli
- framework/lib: vue, vue-router, vuetify, vuex, axios
- runtime: firefox + vue dev-tools

 

프론트엔드 프레임워크: Vue 좋다

- 컴포넌트
  . 통상 웹UI 컴포넌트 하나를 구현하려면 html, css, js 3개 파일이 필요
  . Vue는 UI 컴포넌트 하나를 하나의 파일로 정의 (SFC: Single File Component)
  . 개발/관리 측면에서 좋았음
- 급격하지 않은 변화
  . 개발 진행중에 Vuetify 문서가 버전업됨
  . 하지만 변화 폭이 크지 않아서 쉽게 적응할 수 있었음
  . Vue 프레임워크 자체도 곧 3.0으로 버전업될 예정. 하지만 Vue 2.0과 크게 다르지 않을 예정
  . "변화 폭이 크지 않고, 변화 방향이 합리적"인 것이 프레임워크의 중요한 장점이라 생각함

 

디버깅툴: Firefox + Vue Dev-tools 좋다

- Vue dev-tools의 vuex 히스토리 기능이 큰 도움 됨
  어플리케이션의 상태 정보를 확인해서 해결되는 문제가 (생각보다) 많았음
- vuex의 mutation은 존재 의미를 불신하던 기능 (필요 없다 생각했음)
  Vue dev-tools 활용만으로도 vuex mutation의 가치를 느낌

 

프론트엔드 TDD: 정말 유용한가?

- 백엔드 tool을 개발하면서 TDD의 유용성을 체감함
- 그래서 프론트엔드 개발에도 TDD를 적용하는 것이 도리일 것이라고 생각,
  이번 작업에서 프론트엔드 TDD를 시도해봄
- 구현 코드보다 테스트 코드를 먼저 작성하면서 개발 요구사항을 정리해봄
  생각을 정리한다는 측면에서 나름 의미는 있었지만,
- 프론트엔드 테스트 코드는 구현 코드와 밀결합될 수 밖에 없음을 느낌
  그리고 프론트엔드의 문제점은 테스트 코드보다 눈과 손으로 먼저 체크하게 됨을 느낌
- 테스트 코드를 작성하는 번거로움 대비 실익을 느낄 수 없었음
- 단기간(3달) 동안 거의 혼자 하는 개발이어서 그랬을지도 모름. 베스트프랙틱스에 대한 조언을 구함

 

(이상)

 

 


 

2021-04-25.

HTML 태그의 data- 속성을 이용해서 실제 구현 코드와 테스트 코드의 의존성을 분리할 수 있다는 조언을 들었다.

예를 들어 화면에 표시되는 메시지 문자열을 검증하는 테스트 코드를 만들 경우, 특별한 data- 속성 (예를 들어 data-test-id="message")을 가진 HTML 요소를 찾아 그 문자열을 검증하면 된다. 이렇게 하면 개발자가 해당 문자열을 표현하기 위해 어떤 HTML 태그를 쓰는지, 어떤 id를 쓰는지 같은 세세한 구현 디테일과 분리된 테스트 코드를 작성할 수 있다. 그러면 차후 HTML 구조가 바뀌거나 엘리먼트 id가 바뀌어도 테스트 코드는 변경 없이 유지할 수 있다.

 


 

2022-03-14.

프론트엔드 TDD에 관한 좋은 책을 발견해서 많이 배웠다.

 

Testing Vue.js Applications

-- Edd Yerburgh 지음

-- Manning 펴냄

-- https://www.manning.com/books/testing-vue-js-applications

 

Testing Vue.js Applications

Testing Vue.js Applications</i> is a comprehensive guide to testing Vue components, methods, events, and output. Author Edd Yerburgh, creator of the Vue testing utility, explains the best testing practices in Vue along with an evergreen methodology that ap

www.manning.com

 

책 구석구석에서 Vue.js와 TDD에 대한 저자의 풍부한 경험을 배울 수 있었다.

무엇보다 TDD에 관해 "하면 안되는 것들" 을 분명히 일러주는 것이 좋았다.

  • 무엇을 테스트할지 결정하는 것이 핵심이다 - 가능한 적게 테스트하라
    • 개발환경/실행환경 설정에 관한 유닛 테스트를 하지 마라
    • 화면 스타일에 관한 유닛 테스트를 하지 마라
  • 유닛 테스트, 스냅샷 테스트, e2e 테스트가 모두 필요하다
  • 유닛 테스트를 많이, 스냅샷 테스트는 조금만, e2e 테스트는 더 조금만 하라

프론트엔드 테스트 피라미드 (The frontend testing pyramid)

 

TDD를 시작하면서 잘 해보려는 의욕 때문에 테스트 케이스를 가능한 많이 작성하려 했다. 특히 HTML 요소들이 화면에 제대로 표시되는지까지 유닛 테스트로 확인하려 했다. 이 책 덕분에 그러면 안된다는 것을 알게 됐다 (테스트 케이스는 가능한 적게 작성해야 하고, 화면 출력에 관한 테스트는 스냅샷 테스트로 커버해야 한다는 것을 알게 됐다).

 

Posted by ingeeC
,

Golang 다형성 메모

Dev 2021. 3. 14. 17:25

컴파일되는 JavaScript

개인적으로는 golang(고랭, 고언어)을 컴파일되는 JavaScript라고 생각한다.
golang에는 드러나지 않는 곳에서 많은 것을 처리하는 golang 런타임(JavaScript 인터프리터에서 파생된 무엇?)이 숨어있다. 그리고 golang 컴파일러는 golang 런타임을 뜯어서 큰 힘 들이지 않고 쉽게 만든 것 같다 (이건 칭찬이다). golang은 아름다움보다는 실용성을 추구한 언어다. 그게 golang의 매력이다.

 

같은듯 다른 '객체 (Object)'

c++ 같은 OOP 언어에서 객체는 변수와 메소드의 덩어리다. 그리고 type이다. c++로 객체지향 프로그래밍을 한다는 것은 달리 말하면 type을 정의하는 일이다.
반면, JavaScript에서 객체는 key-value 테이블이다. 그리고 instance다. JS Object를 딱히 type이라고 부르기 어려운 것이 JavaScript에서는 JS Object 아닌 것이 없기 때문이다. int도 JS Object이고, string도 JS Object이고, 심지어 function도 JS Object다.

 

다형성을 책임지는 interface 타입

golang은 type을 철저하게 체크한다. 하지만 JavaScript보다 조금 더 엄격한 정도다.
golang 코드의 interface 타입은 컴파일 시점에 결정되지 않는다. 실행 시점에 golang 런타임이 interface 타입을 체크한다 (즉, interface 타입 변수가 interface로서 갖춰야할 method 들을 구비하고 있는지 체크한다).

 

"Essential Go" 책의 설명을 참조하자.
https://essential-go.programming-books.io/reflection-c7fea6b176b74c54ab35f2d8fdd56f13

 

Reflection

Reflection

essential-go.programming-books.io

Go는 정적 타입 랭귀지다. 대부분의 경우 변수의 타입은 컴파일 시점에 알 수 있다. 하지만 interface 타입은 예외다. interface 타입 뒤에 있는 값이 실제 무슨 타입인지 컴파일 시점에는 알 수 없다.

 

요약하면 다음과 같다.

  • interface 타입으로 어떤 method가 필요한지 규격을 정의할 수 있다.
  • struct 타입으로 필요한 method를 구현할 수 있다.
  • 어떤 struct가 어떤 interface 규격을 만족시키는지 언어적으로는 명시하지 않는다 (명시할 수 없다). golang 런타임이 실행 시점에 체크한다.

 

샘플코드 - interface 타입을 이용한 다형성 구현

상이한 타입의 변수들을 단일한 interface로 일관성있게 다루는 것이 다형성의 매력이다.

package main

import (  
  "fmt"  
)

type writer interface {  
  write()  
}

type koreanWriter struct{}

func (k koreanWriter) write() {  
  fmt.Println("안녕하세요")  
}

type englishWriter struct{}

func (e englishWriter) write() {  
  fmt.Println("Hello")  
}

func main() {  
  kw := koreanWriter{}
  ew := englishWriter{}
  wa := []writer{kw, ew} 
  
  for _, iw := range wa {  
    iw.write()  
    //  
    // 상이한 타입의 변수들을 단일한 interface로  
    // 일관성있게 다루는 것이 다형성의 매력 
    //  
  }  
}

Posted by ingeeC
,

시작하며

터미널 작업자에게 TMUX는 축복 같은 도구다. TMUX를 쓰면 터미널 작업의 효율성이 극적으로 높아진다.

  1. 우선 어떤 작업이 오래 걸릴 경우 그 작업이 끝날 때까지 멍하니 기다릴 필요가 없다. 즉시 다른 Window나 Pane을 열고 다른 작업을 시작할 수 있다.
  2. 또 어떤 작업을 하다 사정이 생겨 터미널 접속을 끊어야 할 경우 기존 작업이 중단되는 것을 걱정하지 않아도 된다. 터미널을 끊어도 하던 작업이 중단되지 않는다 (다시 말해 Session이 유지된다). 다음에 다시 접속해서 하던 작업을 이어 할 수 있다.

 

설치방법

설치 방법도 쉽다. 리눅스 사용자라면 표준 패키지 매니저를 이용해서 설치하면 된다.

  • (우분투라면) sudo apt-get install tmux
  • (CentOS라면) sudo yum install tmux

 

사용방법

CTRL-b 키가 TMUX의 기능을 부르는 핵심 키다.

 

0. TMUX 실행

$ tmux

 

1. Window 만들기, 이동하기

  • window 만들기 (create window) : CTRL-b, c
  • window 이동하기 (next window) : CTRL-b, n

 

2. Pane 나누기, 이동하기

  • 가로 pane 나누기: CTRL-b, "
  • 세로 pane 나누기: CTRL-b, %
  • pane 이동하기: CTRL-b, 화살표

 

3. 세션 끊기, 이어하기

  • 세션 끊기 (detach) : CTRL-b, d
  • 세션 이어하기 (attach) : tmux a

 

터미널 접속만 가능한 소박한 환경에서도 TMUX와 VIM만 있으면 충분히 많은 일을 할 수 있다.

터미널 만세!

 

Posted by ingeeC
,