오늘 회사 채팅창에 데이터 바인딩 라이브러리 이야기가 잠깐 나와서 살펴봄..

(도대체.. 이게 소개된 게 Android Plugin for Gradle 1.5.0-alpha1 이후 부터인데 이제야..)


사내 프로젝트에서는 버터나이프조차도 쓰는 일이 없어서, 어떤 것인가 살짝 맛만 봄...


(참고 사이트)

구글 개발자 문서

https://developer.android.com/topic/libraries/data-binding/index.html#build_environment


박상권님의 블로그 - basic, butterknife, data binding 3개의 코드를 비교해 놓은 샘플이 보기 좋음

http://gun0912.tistory.com/71



(결론)

findViewById() 없이 xml의 View를 자동으로 Binding 해 준다.

그래서 실제 로직과 관계없는 바인딩 코드를 없애줘서 소스의 가독성이 높아진다.

반응형

설정

트랙백

댓글

[PKI] 보안에서 말하는 PKI의 기본 개념 간단 설명


PKI 에 대해서 간단히 잘 설명해 놓은 글이 있어 기억해 둠...


반응형
pki

설정

트랙백

댓글

(블로그 이전)

http://ommokazza.blogspot.com/2017/07/synergy_19.html



반응형

설정

트랙백

댓글

  • BlogIcon 강철호 2017.04.13 14:01 신고 답글 | 수정/삭제 | ADDR

    그동안 수고많으셨습니다.
    한가지 질문드리고 싶은게 있는데요
    github에 있는 소스로 mac 에서 우여곡절끝에 빌드를 하였습니다.
    그런데 막상 실행을 시키니 빈화면으로 아무글자도 표시가 되지않습니다.
    혹시 이런 문제를 겪어보신적은 없으신지요...?

    • BlogIcon 아자 2017.04.14 10:07 신고 수정/삭제

      제가 맥에서 빌드를 해 본적이 없어서 뭐라 말씀드리기 힘드네요.
      맥에서는 어떤 빌드 커멘트를 사용하는지 모르겠습니다만... (아마 hm.py 일꺼 같은데...), 디버그 옵션을 줘서 실행하셔서 어디서 문제가 발생했는지 확인해 보시는 건 어떨까요?

  • breeze 2018.01.03 19:30 답글 | 수정/삭제 | ADDR

    포스팅 감사합니다.
    저는 라즈베리파이에서 사용중인데 잘 되네요 ㅎㅎ
    다만.. 로그인화면까진 잘 동작하나, 시작프로그램에서 실행이 안되네요.
    startup application이 없어 /etc/rc.local 을 수정하여
    synergyc 192.~~ 를 해줬는데도 똑같네요
    해결방법있을까요?

    • BlogIcon 아자 2018.01.03 22:23 신고 수정/삭제

      라즈베리파이에서 시너지를 이용하는 분이 있었군요... 놀랐네요..ㅎㅎ

      제가 리눅스의 세세한 설정까지는 알지 못해서 정확한 해결책은 말씀드리지 못할 거 같네요.
      다만 /etc/rc.local 의 경우 Desktop Environment 의 Startup Application 과는 다를 것으로 예상됩니다. GUI 환경이 필요한 시너지를 저기에서 실행할 경우 제대로 동작이 안될거 같다는 생각은 드는군요.

      라즈베리파이의 Desktop Environment 를 어떤것을 사용하시는지 모르겠습니다만, 해당 DE 에서 Startup Application 을 등록하는 방법을 찾아 해당 위치에 시너지를 실행하는 명령을 추가하면 어떨까 싶네요.

시너지팀에서 한글패치 적용된 버전에 대해 테스트 요청이 왔네요.


http://symless.com/nightly?filter=4b913b5


위 링크가 언제까지 유효할 지는 모르겠습니다만,


이 글을 보시는 분들 중에 Synergy v1.8.8-rc1 버전 같이 테스트 해 주실 분이 있다면,

저 링크에서 받아서 테스트 부탁드립니다.


이슈가 있다면, github 쪽에 직접 등록하시거나,

제 블로그에 코멘트 달아주시면 되겠습니다.


반응형

설정

트랙백

댓글

  • 피타가우스 2017.02.02 19:44 답글 | 수정/삭제 | ADDR

    소중한 자료 감사합니다. 테스트해본 결과
    윈 10 <-> 우분투 16.04 에서 정상적으로 잘 작동합니다(한글포함)
    근데 혹시 클라이언트 쪽 마우스 감도(딜레이, 속도 등)가 너무 안좋은데 향상시킬 방법이 있을까요??

    • BlogIcon 아자 2017.02.02 20:14 신고 수정/삭제

      거기에 대한 해결 방법은 저도 잘 모르겠네요.

      Synergy 서버 설정쪽에서 옵션의 "상대적인 마우스 이동 사용"을 한 번 체크해 보시거나,
      윈도우/리눅스쪽 마우스 감도 설정을 조절해 보시는게 좋을것 같습니다.

  • 나무꾼 2017.02.15 09:38 답글 | 수정/삭제 | ADDR

    시너지에 대해서 찾아보다 방문하게 되어서 테스트 해보았습니다.
    윈도우10 <-> 윈도우7
    윈도우10 <-> 윈도우10 사용해 보니
    쉬프트키와 한영전환 잘 되네요
    리눅스 pc는 없어서 테스트를 못해 보았네요

  • 나무꾼 2017.02.17 14:59 답글 | 수정/삭제 | ADDR

    몇일간은 잘 되더만 마우스 움직임은 이상이 없는데
    현재는 client 쪽으로 마우스가 넘어가면 키보드 사용은 이상이 없는데
    클릭이 되지 않는 현상이 생기네요.
    시너지 서버 프로그램 종료후 재실행시 다시 정상으로 돌아오기는 합니다.

    현재 사용 환경은 다음과 같으며 양쪽 모두 마우스가 먹통 되는 현상이 발생하네요
    클라이언트(윈도우7) <->서버(윈도우10)<->클라이언트(윈도우10)

    • BlogIcon 아자 2017.02.17 17:17 신고 수정/삭제

      저는 아직 그런 현상을 본 적이 없는데,
      시너지 github 쪽에 그런 이슈가 리포팅 되어 있는 듯 합니다. 아직 해결은 안 된듯 한데요...
      리포팅된 버전이 1.8.4 이후 버전들인데 사용에 문제가 있다면
      1.8.3 이나 그 이전 버전을 한 번 이용해 보시는 건 어떠신가요?

  • 10032_MISAKA 2017.02.25 19:51 답글 | 수정/삭제 | ADDR

    와 대만족입니다. 무료버전 다운받아 쓰는데 참 짜증났는데 정식 릴리즈 되면 사야겠네요

  • 10032_MISAKA 2017.02.27 16:42 답글 | 수정/삭제 | ADDR

    리눅스 민트에서 설치하고나서 시스템을 부팅하면 세션이 10초안에 종료되었습니다.(생략)이 뜨면서 정상적인 부팅이 안됩니다. OS재설치를 몇번이나 했네요ㅠㅠ

    • BlogIcon 아자 2017.02.27 19:30 신고 수정/삭제

      음... 제일 의심스러운 부분은 DM(?)이라고 해야 하나요,
      로그인 세션쪽에 시너지를 실행시키는 부분에서 오류가 있으면 그럴 가능성이 있을 것 같습니다.

      시너지 설치 후, 자동 실행을 어떤 식으로 시작하도록 하셨는지 알 수 있을까요?

드디어!!!

Synergy 한글키 패치 Pull Request가 머지 되었네요. 1.8.8 브랜치에 적용되었습니다.


한글키 패치 + 멀티 IME 이슈 패치 두 개 모두 적용되었습니다.

https://github.com/symless/synergy/commit/180d3e57d25025252c04d4e87819bb6b4fd370d3

https://github.com/symless/synergy/commit/f35e3e5e06bbe14ec54be4e5d66585b4cef4a47a



1.8.8 공식 버전이 릴리즈 되면 블로그에 올려놓겠습니다만,

이후로는 문제가 없다면 제가 직접 빌드해서 배포할 일은 없을 듯 합니다.


그동안 테스트 해주신 분들께 감사드립니다. (__)

새해 복 많이 많이 받으세요~

반응형

설정

트랙백

댓글

  • BRK 2017.02.10 14:36 답글 | 수정/삭제 | ADDR

    수고 많으셨습니다. 감사합니다! 리플은 달리지 않아도 많은 이들이 감사하고 있을겁니다.

  • 노마 2017.02.21 10:10 답글 | 수정/삭제 | ADDR

    PRO버전을 구매후 그동안 여기와서 올려주신 패치버전을 항상 이용했는데, 공식 소스에 적용되었다니 축하드립니다.

    그동안 너무너무 수고 많으셨습니다.. ( _ _ )

  • 이준규 2017.03.06 10:34 답글 | 수정/삭제 | ADDR

    안녕하세요. 늘 감사히 쓰고 있었습니다. 공식버전에 적용된 것 확인하고 다운받아 설치하다가 아무래도 감사의 말씀을 드려야할것 같아서 다시 찾아왔습니다. 감사합니다.

잊고 있었던 시너지 한글키 패치 pull request에 응답이 달렸습니다.

1.8.6-rc2 버전 기반으로 nightly 버전을 빌드했다고 테스트 해달라는 요청과 함께

문제가 없느냐고 묻길래... Shift-Space키에 대해서 좀 더 살펴 보았습니다.


윈도우에서 드라이버 변경이나 레지스트리 수정을 통해 Shift-Space키를 한영전환키로

이용할 때의 결정적인 문제는, 해당 키가 순수하게 시너지 클라이언트쪽으로 넘어가지 않는

것입니다.


윈도우 서버 - 리눅스 클라이언트 쪽에서 확인을 해 보면, 

Shift-Space를 누를 경우 그냥 Left-Shift로 인식을 합니다.

(Shift-Space키를 한영전환키로 이용할 때 말이죠)

물론 윈도우에서 Shift-Space키를 한영전환키로 이용하지 않는 경우라면

그대로 넘어가기에 리눅스 클라이언트 쪽에서 Shift-Space키를 한영전환키로 이용하도록

설정되어 있는 경우라면 동작할 것으로 예상합니다.

(이 부분은 다시 한번 테스트를 해보고 포스팅 업데이트 하도록 하겠습니다.

 레지스트리를 바꾸면 재부팅해야 해서 말이죠..;)


그래서 결국 택한 방법은 한영키를 누르던 Shift-Space키를 누르던 리눅스 쪽에

한영전환키 값을 넘기도록 하고 리눅스 쪽에서 좀 더 설정해 주는 방법을 택하였습니다.

리눅스 클라이언트 쪽에서 한영전환키를 Shfit-Space, 한영키 모두 매핑해 두는 것입니다.

물론 리눅스 클라이언트 쪽에 한영키만 매핑해도 동작은 합니다만,

사실 Shift-Space키를 이용하는 분이라면 시너지가 아닌 직접 리눅스를 이용할 때도

Shift-Space키를 이용할 것이기 때문에 두 키 모두 매핑해 두는 방법을 권하는 것이죠.


제가 개발용으로 사용하는 Ubuntu 14.04의 ibus에서는 어떻게 설정하는지 보여드리겠습니다.


System Settings를 실행하시고요, Text Entry를 엽니다.

Korean (Hangul)을 선택하면 아래 그림과 같이 보여집니다.

(없다면 아래의 '+'눌러서 추가하시면 될 것입니다. 자세한 설명은 생략합니다)



오른쪽에 보시면 'Switch to next source using:'에는 'Shift-Space'가 할당되어 있습니다.

다른 키로 되어 있다면 마우스로 클릭하셔서 Shift-Space 입력하시면 됩니다.

이때는 synergy가 아닌 직접 리눅스 머신에서 입력해 주셔야 합니다.


다음 previous source에는 Hangul이라고 되어있는데, 한글키를 설정해 주려면 설정이

안된다고 나옵니다. 그래서 저는 아래와 같이 터미널을 열어 강제로 지정해 주었습니다.


gsettings set org.gnome.desktop.wm.keybindings switch-input-source-backward "['Hangul']"


이렇게 설정해 두면 설정이 완료된 것입니다.

다른 리눅스 배포본이나 입력기를 이용하신다면 거기에 맞게 설정을 해 주시기 바랍니다.


맥 클라이언트에 대한 것은 저도 잘 모르겠습니다.

저는 애플 기기들과 친분이 전혀 없기에... 심지어 시너지 빌드를 위해 필요한 라이브러리 중,

Apple 사이트에서 받아야 하는 라이브러리가 있는데, 이것도 친구에게 부탁해서 받았습니다.


어쨋뜬 간만에 시너지 관련해서 긴 글을 썼네요.

마지막으로 한글키 패치된 시너지 1.8.5 버전 첨부합니다.


synergy-v1.8.5_hangul_patch-stable-64e07e0-Windows-x86.msi

synergy-v1.8.5_hangul_patch-stable-9f99592-Windows-x64.msi


-x86이 32bit, -x64가 64bit 버전입니다.


쓰다가 문제가 발생하면 리포팅 부탁드립니다.


(2016.12.13 추가)

한글키 패치 + Multi IMEs 패치 적용된 바이너리도 공유합니다.

윈도우 서버쪽에서 여러 입력기를 사용하시는 경우,

클라이언트에서 Alt 키가 눌러진 것으로 인식되는 현상 수정한 바이너리 입니다.


synergy-v1.8.5_multi_imes_patch-stable-25c884c-Windows-x86.msi

synergy-v1.8.5_multi_imes_patch-stable-880c80d-Windows-x64.msi




추가링크:

2014/10/08 - Synergy 1.5.1 한글키 패치 & 빌드 방법 (2016.11.24 수정)

반응형

설정

트랙백

댓글

  • 테스트 2016.12.12 10:51 답글 | 수정/삭제 | ADDR

    서버: 우분투 16.04
    클라이언트: 윈도우 10
    정상작동합니다. 감사합니다!

  • BlogIcon 인생여전 2016.12.12 17:19 신고 답글 | 수정/삭제 | ADDR

    서버 : 윈도우10
    크라이언트 : 윈도우10, 우분투 14.04
    한/영 키를 누르고 나면 클라이언트에서 ALT 키가 눌러진 것으로 되어 정상적인 입력이 되지 않습니다. 감사합니다. ^^

    • BlogIcon 아자 2016.12.12 19:30 신고 수정/삭제

      안녕하세요?
      윈도우 서버쪽에서 입력기 여러개를 사용하는 경우 이와 같은 현상이 있습니다.
      혹시 그런 상황이시라면, 조금만 기다려 주세요.
      관련 수정사항 적용한 바이너리를 추가하도록 하겠습니다.

      해당 수정사항이 시너지쪽에 반영되려면 먼저 한글키 패치가 적용된 이후에나 pull request를 만들 수 있을 것 같습니다.
      원래의 시너지에서는 한영키 자체가 무시되면서 alt 키 눌리는 현상 자체가 재현이 안됩니다..

  • BlogIcon 인생여전 2016.12.12 20:20 신고 답글 | 수정/삭제 | ADDR

    감사합니다. 수정 바이너리 기다리고 있겠습니다. ^^

    • BlogIcon 아자 2016.12.13 10:06 신고 수정/삭제

      어제 저녁에는 일이 있어서 빌드를 못 했네요.
      방금 블로그 글 업데이트 하였습니다.

      추가로 첨부된 multi-imes-patch 버전을 이용해 보세요.

  • BlogIcon 인생여전 2016.12.13 15:16 신고 답글 | 수정/삭제 | ADDR

    잘 동작합니다. 앓던 이 빠진 기분입니다. 감사합니다. ^^

  • ygkim 2016.12.20 12:59 답글 | 수정/삭제 | ADDR

    정말 감사합니다. 이번 버전도 잘 작동합니다! (윈도10 x64버전. XPS 9550 서버, 서피스프로4 클라이언트)

  • 피타가우스 2017.02.01 16:01 답글 | 수정/삭제 | ADDR

    우와 이렇게 오랫동안 꾸준히 좋은 정보를 공유해주심에 감사드립니다.

    오래전에 synergy를 쓰다가 오랜만에 복귀하여 사용하려고하는데, 유료로 바뀌어있군요.
    그런점에서 약간의 햇갈리는점이 있어 여쭤봅니다.

    공식 사이트는 donation을 해야만 사용이 가능하게끔 되어잇는데,
    github에서는 여전히 소스코드를 공유하고있고, 설명에서도 free 라고 나와있습니다.

    1. 본 포스트에서 링크해주신 빌드된 .msi 로 설치해서 사용해도 serial 키를 요구하던데, donation을 해야만 사용가능한건가요?
    2. 우분투 쪽은 github 소스로 제가 직접 빌드해서 사용하면 되는건가요?
    3. win / ubuntu 에서 server/client 구분은 어느쪽으로 해도 상관없는건가요?

    • BlogIcon 아자 2017.02.01 16:35 신고 수정/삭제

      일단 답변 먼저 드리면요..

      1. serial key 를 입력하지 않아도 이용 가능 합니다. 다만 UNREGISTER 라고 뜹니다.

      2. 우분투에 기본적으로 포함된 synergy 버전이 있긴 합니다만, Copy&Paste에 문제가 있는듯 합니다. 직접 빌드해서 사용하셔도 되고 유료 등록하여 최신버전을 편하게 받아서 사용하셔도 됩니다.

      3. 특별히 문제는 없는 듯 합니다. 다만 저는 Window쪽을 서버로 이용하고 있어 반대 상황에서는 충분한 테스트를 해본적이 없네요.


      위에서도 말씀드렸듯이 등록을 한다면 편하게 이미 빌드된 버전을 다운로드할 수 있습니다.
      귀찮음을 감수한다면 SSL 을 지원하는 Pro 버전까지 직접 빌드할 수도 있는 듯합니다.

    • 피타가우스 2017.02.01 23:48 수정/삭제

      답변 정말 감사드립니다!
      글을 읽을수록 정말 내공자이신것같아 너무 부럽습니다!
      덕분에 궁금한 점들이 해결되었습니다 감사합니다

      추가적인 질문이 있는데요
      2번같은 경우라면, 아자님의 깃허브 소스를 빌드해서 쓴다면 ubuntu 에서 copy paste 도 문제없이 사용할 수 있는걸까요??

      그리고 여담으로 말해주신 SSL 기능도 사용하고자 할때 어느 소스를 참고해서 빌드하면 될까요?
      아직은 초년생이지만 프로그래머라 그런지 수고를 감안해서라도 괜히 도전해보고싶네요 ㅎㅎ

    • BlogIcon 아자 2017.02.02 17:07 신고 수정/삭제

      리눅스에서 직접 빌드를 해보시려면 저의 소스보다는
      공식 synergy github 소스의 v1.8.8 브랜치를 이용하시거나
      v1.8.7 tag를 이용하시면 될 것 같습니다.
      저의 한글 패치는 Windows 쪽에만 영향을 미치는 것이라
      리눅스에서는 굳이 해당 패치가 굳이 포함되어 있지 않아도 됩니다.

      음.. SSL 기능 쪽 추가하는 것은 저도 한 번도 해본적이 없어서 잘 모르겠네요
      구글링 해보면 찾을 수 있을것 같긴 합니다^^;

      그리고 굳이 정식버전이 아니라 베타버전이라도 감수하고 사용하실 생각이 있다면,
      http://symless.com/nightly
      에서 nightly 빌드 버전을 이용해 보는 것도 방법이기도 합니다.

아니다. 단지 GC의 성능을 나쁘게 만들 뿐이다.


아래의 예를 보자.


Main.java

public class Main {

    Outer outer;


void alloc() { outer = new Outer(); }

void free() { outer = null; }

}


Outer.java

public class Outer {

    Inner inner = new Inner();


public class Inner {

}

}



non-static inner 클래스는 outer 클래스에 대한 암묵적인 레퍼렌스를 가진다.

Main 클래스의 alloc() 메소드와 free() 메소드를 차례대로 실행시키면

객체들은 아래와 같은 레퍼런스를 가지게 될 것이다.




먼 옛날(?) Inner Class가 처음 소개되던 JDK 1.1 시절에 쓰여진 글들을 보면

메모리 릭을 발생시킬 수 있다는 글들이 있다.

outer와 inner가 서로의 레퍼런스를 가지고 있어 레퍼런스 카운트가 0이 되지 않아

GC가 메모리를 해제할 수 없다는 생각이 었던 것 같다.

(JDK 1.1 초기에는 실제로 그렇게 동작했을지도 모르지만,

 JDK 1.1을 설치해서 확인하고 싶은 생각까지는 없는 관계로... Pass)


하지만 Garbage Collector는 Unreachable object에 대해서 메모리를 해제한다.

메모리가 할당된 object들의 연관 관계를 그래프로 표현한다고 생각해보자.


레퍼런스 카운트가 0인 object는 쉽게 찾을 수 있지만,

레퍼런스 카운트가 0보다 큰 object인 경우는,

그래프의 시작 노드에서 모든 노드를 방문했을 때 방문하지 않은 노드를 찾아서

메모리를 해제해야 하기 때문에 Grabage Collector의 성능이 떨어질 수 밖에 없다.


이것을 보여주는 적절한 예제를 작성하려 했는데 시간 관계상 패스.

http://stackoverflow.com/questions/20380600/gc-performance-hit-for-inner-class-vs-static-nested-class

위 링크를 참고해 보시라.



결론:

inner 클래스를 가지는 객체가 빈번하게 만들어지도 버려진다면, (만들어진 객체에

대한 레퍼런스를 유지하지 않는다는 의미. 로컬 메소드에서만 사용되는 것 처럼)

non-static으로 inner 클래스를 구현하는 것이 어플리케이션 성능을 좋게 만들 것이다.


추가로 outer 클래스에 대한 암묵적인 레퍼런스를 없앨 수 있으므로 메모리 절약에도

약간 도움을 줄 수 있을 것이다. (물론 실제로는 아닐 가능성이 더 클것 같다. 

WeakReference를 사용해야 할 경우가 있을 수도 있고, outer 클래스에 직접 접근이

불가능 하므로 필요한 멤버 변수를 추가로 가지고 있어야 할 수도 있다)




다음 글은 이 글을 쓰게 된 동기인 Android의 lint 이슈인 HandlerLeak에 대해서 알아보겠다.

반응형

설정

트랙백

댓글

안드로이드 프로젝트에서 유닛 테스트에 사용할 만한 Test Frame은 Mockito, PowerMock, Roboletric 정도가 있다. 여기에서는 이 셋의 차이점을 알아보고 언제 무엇을 사용할 것인가를 제안하려 한다.


결론부터 말하면 기본적으로 Mockito를 이용하자.

그리고 Mockito의 제한으로 인해 static method 혹은 private method를 테스트 해야 한다면 PowerMock을 이용하자.

가능하다면 Roboletric은 이용하지 말자.

아래에는 각 툴에 대해 살펴보고 이렇게 결론을 내린 이유를 적어본다.



Mockito


mock 객체를 쉽게 만들 수 있게 해주는 도구들 중에는 EasyMock, jMock, Mockito 등이 있으나 현재는 Mockito가 대세이다. 이것은 구글 트렌드에서 확인할 수 있다.



 

http://kwon37xi.egloos.com/4126439 블로그 링크를 보면,  jMock 과 EasyMock을 비교하는데 결론은 엉뚱하게도 Mockito 였다. 글이 2009년에 작성된 글이라 지금은 크게 의미가 없는 내용이긴 하지만 글 마지막에 왜 Mockito로 트렌드가 바뀌었는지에 대한 힌트를 얻을 수 있다. 


그 이유가 Mockito가 마틴 파울러가 이야기한 Mocks aren't Stubs의 원칙을 지키는 프레임워크이기 때문이라고 한다.

(원문글: http://martinfowler.com/articles/mocksArentStubs.html
번역글: http://so-blog.net/2016/05/09/mock_stub/
http://testing.jabberstory.net/)


그리고 여기에 대해 추가로 '왜 Mockito가 좋은가'에 대해 작성한 글이 있는데
http://kwon37xi.egloos.com/4165915 도 참고하면 좋을 것 같다.


Mockto 사용법에 대해서는
공식문서(영문): http://static.javadoc.io/org.mockito/mockito-core/2.2.7/org/mockito/Mockito.html
혹은 누군가 한글로 정리해 둔 아래 링크를 참고하자.
http://bestalign.github.io/2016/07/08/intro-mockito-1/
http://bestalign.github.io/2016/07/10/intro-mockito-2/


하지만 Mockito에는 몇 가지 제약이 있다. 

(https://github.com/mockito/mockito/wiki/FAQ 의 limitation 항목 참고)

그 중 테스트 케이스를 작성하는 데 가장 문제가 되는 부분이 private method와 static method에 대한 mock 을 만들 수 없는 것이다.


static method에 대한 mock을 제공하지 않는 이유에 대해 Mockito팀은 static method는 object orient 와 dependency injection을 사용하는 것이 좋다는 입장이라 구현하지 않는다고 한다. 만약 레거시 코드의 테스트 케이스 작성에 이용하고 싶다면 PowerMock 같은 툴을 이용하라고 한다. 

(static method 관련해서는 Mockito에도 작업중이라는 메일링 리스트의 답글이 있긴 하다)


private method에 대한 mock을 제공하지 않는 이유에 대해서는 아래와 같이 이야기 한다.
1. 기술적으로 추가 작업이 필요하고
2. protected나 package로 메소드의 접근자를 변경하는 간단한 work-around도 있고
3. 담당할 사람도 부족하고 이미 그것을 구현한 PowerMock이라는 툴도 있다.
4. 마지막으로 private method를 mock으로 만들어야 한다면 그것은 OO 측면에서 뭔가 잘못되어 간다는 신호라는 뜻이다.

(https://github.com/mockito/mockito/wiki/Mockito-And-Private-Methods 참고)

 

 

PowerMock

일반적으로 Mockito의 제약을 해결하기 위해 PowerMock을 이용한다.

다만!!! PowerMock 설명에 따르면 PowerMock은 unit testing 에 대해 전문적인 지식을 가진 사람을 위한 것이고, 익숙하지 않는 개발자에게는 좋은 점보다 나쁜 점이 더 많을 수 있다고 한다. (https://github.com/jayway/powermock)

아마도 객체 지향 원칙을 지키지 않아도 되도록 만든다는 측면이 있어서 그렇다고 생각된다.


그럼에도 불구하고 레거시 코드에 대한 테스트 코드를 작성해야 한다거나, 일정상 OO 측면을 조금 무시하고 작성한 코드에 대한 테스트 코드를 작성하려 할 때 PowerMock을 이용하면 되겠다.


정확하게는 우리가 이용할 클래스는 PowerMockito 클래스이다.
PowerMock은 EasyMock과 Mockito에 새로운 feature를 추가한 것이라 생각하면 되고, 

PowerMock 클래스는 EasyMock 을 기반으로 한 것이고,
PowerMockito 클래스는 Mockito 을 기반으로 한 것이다.

현재의 대새는 Mockito라고 하니 PowerMockito를 주로 이용하면 될 것으로 생각된다.


PowerMockito는 아직 Mockito 2.0 베타버전 기반이기에 Mockito 최신 버전의 기능과 혼용해서 사용할 경우 문제가 발생할 수 있다. (PowerMockito에 Mockito의 새로운 버전을 통합하는 작업이 쉽지는 않은 듯 하여 PowerMockito가 기반으로 삼은 Mockito 버전은 최신 Mockito버전과 다를 수 있으니 Mockito 최신 기능 사용시 주의가 필요하다.)


실제 사용 방법은 아래의 링크에서 확인해 볼 수 있다.


static method mocking 예제 파일:
https://github.com/jayway/powermock/tree/master/modules/module-test/mockito/testng/src/test/java/samples/powermockito/testng/staticmocking


Using PowerMock with Mockick:
https://github.com/jayway/powermock/wiki/mockitousage#a-full-example-of-partial-mocking-of-a-private-method



 

Roboletric

Mockto가 익숙하지 않다면 가능하면 이용하지 말자.
Roboletric을 잘못 이용하여 작성한 테스트 케이스는 실제 테스트 결과를 assertion 하지 않는 Code coverage만 늘어날 것이다.


Roboletric의 기본적인 컨셉은 실제 디바이스에서 해야하는 테스트를 JVM 상에서 테스트 할 수 있도록 해 주는 것이다. 실제 디바이스에서 실행하는 것 보다는 시간적으로 물리적으로 이점이 많지만, 비지니스 로직을 테스트 하기 위해서라면 테스트에 걸리는 시간이  많이 소요되고 결국 Mockito 등의 도움이 없으면 assertion하기 힘들다. 

그리고 테스트 케이스 코드 리뷰를 하다보면 Roboletric으로 테스트를 작성한 테스트 케이스는 타겟 메소드가 아닌 Roboletric 코드에 의존적인 assertion을 하는 경우가 많았다. 비지니스 로직은 가능한 Mockito 만으로 작성하도록 노력하자.


Roboletric을 이용하기에 적절한 테스트는 UI 동작을 테스트 하는데 이용하는 것이다.
http://robolectric.org/ 에서 보여주는 예제를 보고 생각해 보자. 

(http://robolectric.org/writing-a-test/ 도 UI 동작 테스트 예제이다)


하지만 Roboletric 만으로 UI 동작을 테스트 하는 코드를 작성하기에는 Roboletric에 대한 신뢰가 아직 부족한 듯 한다. 즉, 테스트가 실패 했을 때, 테스트 케이스가 문제인지,  나의 코드가 문제인지 Roboletric이 문제인지에 대해 확인이 어렵다는 것이다. 그리고 만들더라도 실제 디바이스와 Roboletric의 동작이 다를 가능성도 있다.


그리고 Android Framework 버전의 업데이트 속도를 바로 따라가지 못한다. 얼마전 까지만 해도 현재 sdk version 21까지만 지원하고 있었다. 그리고 최신 버전의 android support 라이브러리류 또한 문제가 있을 가능성이 높다.


단점만 쭉 적어 놓긴 했는데, Roboletric을 이용하는게 좋을 때도 있다.
특히 단위 테스트가 아닌 UI 동작 테스트 라던가, 멀티쓰레드 코드를 테스트 할 때는 도움이 된다고 하는 듯 하다.


반응형

설정

트랙백

댓글

  • 메모리 2016.11.17 12:00 답글 | 수정/삭제 | ADDR

    안녕하세요 궁금한 정보가 있어서 찾아다니다가 들어오게되었습니다.
    Mockito 를 가지고 unit test 항목들을 구현하는 중인데요.
    기존에 class 자체가 특정 class 를 extends 하는 경우에.. 그걸 어떻게 연결시켜주는지 혹시 아시나요?
    test class 는 무조건 extends TestCase 하고 있는데.. ㅠㅠ;; 자꾸 에러가 나서요.. 뭔가 회피방법이 있는지.. super 쪽에 api를 사용하는건 아니고 그냥 extends 만 되어있는 상황인데 혹시 방법이 있을까요?

    • BlogIcon 아자 2016.11.17 19:29 신고 수정/삭제

      설명을 좀 더 해주실 수 있나요?

      일단 어떤 환경에서 테스트를 실행하는지요?
      그리고 어떤 에러 메시지가 발생하나요?

      또 가능하다면 문제가 발생한 테스트 케이스 소스를 붙여주실 수 있나요?

참, 제목을 고르기 힘든데...

잠깐 상황을 설명하자면 Singleton (Utility class)에서 파라메터로 Context를 요구하는 메소드가 여럿 있는데, 이것 때문에 콜 스택에서 이것을 위해 몇 번이고 Context를 계속 넘겨줘야 하는 한다. 여기서 고민이 시작된다. 웬만하면 굳이 activity의 context가 없어도 application context만으로도 충분하니깐, application context를 어디에 저장해 두고 static method를 통해 가져오면 어떨까?


그래서 일반적으로 떠 올릴 수 있는 방법이 다음과 같다.


--- in AndroidManifest.xml ---

<application

android:name="MyApplication"

.

.

.



--- MyApplication.java ---

// The class name must be same to the name of application declared in AndroidManifest.xml

public class MyApplication extends Application {

private static Context sContext;


@Override

public void onCreate() {

super.onCreate();

sContext = getApplicationContext();

}


public static Context getAppContext() {

return sContext;

}

}


위와 같이 AndroidManifest.xml 파일의 <application> 에 android:name를 선언해 준다. 그리고 그와 같은 이름으로 Applciation을 상속받은 클래스를 만들고 onCreate()에서 Application Context를 static 변수에 저장을 한다. 이렇게 하면 Application이 시작될 때(다른 모든 컴포넌트들이 초기화 되는 것보다 빨리) Application Context가 초기화 되기 때문에 이 Context를 이용하여 Singleton을 초기화 하거나 혹은 다른 컴포넌트에서 Singleton을 이용할 때 Context에 대한 고민없이 이용할 수 도 있다.


그럴듯 해 보이지 않은가?

그런데 이렇게 작성하면 Static Field Leaks라는 android lint이슈가 발생한다.


말 그대로 Context 클래스를 static 필드에 저장하면 leak이 발생할 수 있다는 이야기다. 일반적으로 activity context를 어느 Singleton에 static으로 잡아 두었다고 생각해 보자. activity가 종료되어도 Singleton에 남아있는 activity에 대한 static reference 때문에 Application이 종료될 때 까지 activity가 Garbage Collection이 되지 않고 메모리에 남아 leak을 발생시킨다.


그런데 application context도 같을까? 안드로이드 팀에서 공식적으로 여기에 대해서 언급한 것은 없다. 다만 Application 클래스의 레퍼런스 문서를 보면 아래와 같은 내용이 나온다.


Note: There is normally no need to subclass Application. In most situations, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), include Context.getApplicationContext() as a Context argument when invoking your singleton's getInstance() method.


Application을 상속받아 global context를 이용해도 되는데, 그것 보다는 Context argument를 이용하는게 singleton을 더 모듈화할 수 있다고 적혀있다. 이걸로 유추했을 때, 위와 같이 이용해도 문제는 없으리라 생각된다.


또한, stackoverflow를 보면 저렇게 해도 문제가 없다는 의견이 많은 듯 하다. 다만 android core쪽에서 언제든 변경될 수 있기 때문에 지금은 문제가 없다 하더라도 미래를 생각하면 이용하지 않는 게 좋다는 것 같다.


회사의 다른 팀의 이야기를 들어봐도 위와 같이 이용했을 때, leak은 없었다는 이야기를 들었다.


결론적으로 나도 이 방법은 사용하지 않기로 하였다. 미래를 생각했을 때 공식적으로 인정받지 않은 로직을 피하고 싶기도 하고, Testability측면에서 모듈화 되어 있는 것이 더 낫다고 판단했다.



P.S

Application과 Activity의 생명주기에 대한 이해 없이 저 Context를 막 같다 쓸까봐 걱정되기도 했다.


반응형

설정

트랙백

댓글

  • 575 2016.12.21 14:21 답글 | 수정/삭제 | ADDR

    android:process 라는 tag를 써서 service를 별도의 process에서 수행한다거나 하면, 해당 service로 인해서 별도 process가 수행될 때, application 객체가 하나 더 만들어집니다.

    그래서 application context가 반드시 하나로만 유지되지는 않습니다. :)

    • BlogIcon 아자 2016.12.21 15:09 신고 수정/삭제

      그런 경우도 있을 수 있겠군요!
      멀티 프로세스인 경우가 그리 많지 않을 것 같긴 합니다만, 그 상황에서는 Application Context를 다룰 때는 주의해야 겠네요.

  • good 2020.02.14 12:14 답글 | 수정/삭제 | ADDR

    좋은 글 잘 봤습니다.
    같은 고민하고 있었는데 글이랑 댓글 보고 해결 됐습니다. good

 고전 IBM-PC게임에 관심이 있으신 분들은 두기의 고전게임이라는 블로그를 모두들 아시리라 생각합니다. 두기님이 만드신 도스게임런처는 정말 대단한 런처입니다. 하지만 한 차례의 블로그 폐쇄, 그리고 또 한번의 블로그 중단을 겪으면서 불만이 생겼습니다. (방금 들어가 보니 지금은 다시 운영을 하시는 것 같네요)


 두기님의 블로그에서는 게임에 맞는 설정 파일도 함께 제공했었는데요, 이 설정 파일은 다른 사람들은 알 수 없는 포맷으로 되어 있어서 다른 곳에서는 활용할 수 없다는 단점이 있었습니다. 또 다른 불만은 도스게임런처 자체가 비주얼 베이직으로 만든 것이다 보니 특정 라이브러리를 설치하지 않으면 실행할 수가 없었는데, 블로그에서 제공하던 ErrorFix.exe 파일도 구할 길이 없어서 난감했던 기억이 납니다.


그래서 결국 대안을 찾다가 발견한 것이 바로 DGBL: DOSBox Game Launcher입니다. 널리 쓰이고 있는 자바로 작성된 도스박스용 멀티 플랫폼 오픈소스 런처죠. 이 글에서는 런처의 간단한 이용법과 게임 추가 방법을 소개합니다. 이후에는 dosbox daum 버전을 추가하는 방법이던지 그외 DBGL 관련 내용들을 적어볼 생각합니다.


그럼 시작 하겠습니다.


1. DOSBox Game Launcher 다운로드 및 설치

http://members.quicknet.nl/blankendaalr/dbgl/#download

위 링크에 가시면 운영체제에 맞는 바이너리를 다운로드 할 수 있습니다.

대부분 윈도우를 사용하실 테니 Windows 쪽에 있는 바이너리를 받으시면 됩니다.

(이후에도 Windows 기준으로 설명하도록 하겠습니다)



Windows 박스 하단을 보면 작게 'Extract and run launch.exe' 라고 되어 있죠?

네, 그냥 받아서 압축을 풀고 launch.exe를 실행하시면 됩니다.

혹시 Java 설치가 안되어 있다고 나오는 분은 Oracle사의 Java홈페이지에서 다운로드 받으실 수 있습니다.

http://www.oracle.com/technetwork/java/javase/downloads/index.html







2. 실행 후 설정 할 것들

DGBL을 실행하고 나면 아래와 같은 화면이 보일 것입니다.



먼저 해야 할 것은 설정을 손보는 것입니다. File - Preferences를 선택하면 Settings창이 뜹니다.



Hide DOSBox Status Window 항목을 체크해 주세요. 도스박스 화면이 뜰 때 추가로 도스창이 하나 떠서 도스박스 상태를 보여주는데, 일반적으로는 귀찮기만 하죠. 나중에 문제가 생겼을 때 확인용으로 사용하면 됩니다.

다음은 Filename by profile title입니다. 기본값은 Unique ID인데요, 이게 숫자 1부터 증가되면서 올라갑니다. 직접 디렉토리를 손댈 일은 없습니다만 저는 별로더라고요. 어쨌거나 이건 권장 수준? 참고로 프로파일 디렉토리 이름만 바뀝니다. 버그인지 캡쳐 쪽 디렉토리 이름은 안바뀝니다.

마지막으로 Language는 당연히 한국어가 편하겠지요?



추가로 설정해야 할 항목이 있습니다. DBGL은 웹에서 게임 정보를 가져오는 기능이 있는데, 스크린샷 정보는 기본적으로 안 가져옵니다. 위와 같이 'Choose screenshots'를 체크해 두시면 게임 검색 시 텍스트 정보 뿐만 아니라 스크린샷도 가져올 수 있습니다. 커버 아트에 관심이 있으신 분은 커버 아트쪽도 체크해 주시면 좋겠네요.


설정을 마치고 나면 런처를 종료하고 다시 실행합니다. 그래야 한국어로 보이거든요.



한글화가 잘 되어 있죠? 사실 좀 이상하게 보이는 번역도 있어서..(대표적으로 개발자...) 기회가 된다면 이것도 업데이트 해서 DBGL 프로젝트쪽으로 리포팅할 예정입니다.


3. 게임을 추가해 봅시다

이제 게임을 추가해 볼까요? 여기서는 Master of Orion으로 추가하는 과정을 보여드리겠습니다. 왜냐하면 Master of Orion은 제가 gog.com에서 구입한 것이므로 부담없이...



위와 같이 DBGL압축을 풀면 여러 디렉토리가 생기는데요, 그 중 dosroot 디렉토리에 게임을 복사합니다. 다른 디렉토리에 있어도 상관은 없습니다만, 게임을 추가해 보면 저 디렉토리를 기본 디렉토리로 사용하고 있습니다. 그 말은 저 디렉토리안에 있으면 상대 주소를 사용할 수 있어서 이동성, 즉 dbgl80 디렉토리를 다른 곳으로 옮기거나 이름을 바꾸어도 상관이 없다는 뜻입니다.


게임을 원하는 위치에 복사를 하였으면 아래와 같이 게임 추가를 시작합니다.



그림의 'M' 이라는 아이콘을 클릭하면 해당 제목으로 MobyGames라는 사이트에서 게임을 검색하여 관련 게임 목록을 보여 줍니다. 정확한 게임을 선택하면 아래와 같이 게임 정보가 채워지고 다운로드 할 스크린샷을 선택하는 화면이 나옵니다.



게임 정보는 영어밖에 제공되지 않는 듯 합니다. DBGL관련해서 개인 목표 중 하나가 게임의 한글정보 데이터베이스를 구축하고 구축하고 해당 사이트를 저기에 추가하는 커스텀 버전을 만드는 것입니다. (하지만 언제?)


다운로드 할 스크린샷 이미지까지 선택하였다면 프로파일의 다른 항목들도 변경/추가해야 합니다. 개인적으로는 '기기'항목의 사이클을 max로 두는 것이 좋았습니다. 이것 때문에 게임이 너무 빨라져 못할 것 같다면 그 때 조정하면 되고요.


이제 필수 항목인 게임 디렉토리 설정을 해야겠지요?



'마운트' 탭으로 가서 마운트 기본 설정의 '추가'를 누르시고 마운트 디렉토리를 찾거나 직접 적어 주세요. 마운트의 의미는 C 드라이브를 저 디렉토리로 연결한다 정도로 생각하시면 됩니다. 보시면 디렉토리가 이름만 있지요? dosroot가 아닌 다른 디렉토리인 경우 전체 경로가 저기에 적히게 됩니다. 'D:\dbgl\games\Master_of_Orion' 이런식으로 말이죠. 전체 경로가 다 적히면 프로파일 설정의 이동성이 떨어지겠죠? 어쨌거나 다 되었으면 '확인'를 눌러 주세요.


이번에는 실행파일을 설정합니다.



위와 같이 기본에는 게임 실행 파일을 선택하시고, 설정에는 게임 설정 파일을 선택하시면 됩니다. Master of Orion의 경우 INSTALL.EXE가 게임 설치 및 환경 설정 기능까지 겸하고 있어 INSTALL.EXE를 설정 파일로 선택하였습니다. 설정은 필수가 아니니 해당 실행 파일이 없거나 모르면 비워 두셔도 상관은 없습니다. 다시 '확인'을 눌러주시면 게임이 추가됩니다.



자 이제 실행해 볼까요? 게임을 선택하여 Enter를 누르시거나 '프로파일 실행' 혹은 더블클릭을 하시면 됩니다. 게임이 잘 실행되는군요.



간단한 단축키를 말씀드리면 Ctrl + F5는 화면 캡쳐, Ctrl + F10은 마우스 Lock 해재, Ctrl + F9는 도스박스를 종료하는 단축키 입니다.



4. 프로파일 테이블 설정

추가로 프로파일 테이블 설정을 바꾸면 아래와 같이 볼 수도 있습니다. 아래와 같이 Large titles를 선택하면 보시는 것 처럼 큰 아이콘으로 보입니다. 그런데 게임DB에서 스크린샷을 선택하지 않으면 아래와 같이 게임 프로파일이 텅 비어 보입니다. 어떻게 해야 할까요?



당황하지 말고 다시 게임을 실행합니다. 그리고 원하는 화면에서 Ctrl + F5 단축키를 누릅니다. 도스박스 게임화면을 캡춰하는 단축키입니다. 그리고 다시 DBGL로 돌아와 보면 짜잔...



이렇게 프로파일에 이미지가 보여집니다.




5. 마치며...

사실 두기님의 도스게임런처를 이용하면 참 쉽습니다. 하지만 자의든 타의든 블로그가 페쇄가 되면 좀 난감해집니다.  그리고 고전게임사랑 카페와 고전게임소장 가페 사태를 기억하시나요? 저는 게임 자체는 별로 아쉽지 않았습니다. 제가 제일 아쉬웠던 점은 수많은 사람들이 자신의 추억을 기억하며 달아 둔 댓글들, 사람들이 올려 둔 자그마한 팁들 공략들이 다 사라진 것입니다. (쓰다보니 구글 그룹스에 고전게임 관련 그룹을 하나 만드는 것도 나쁘지 않은것 같네요.)


한 사람에게 집중된 시스템이 아닌 참여하고 발전시킬 수 있는 오픈소스 DBGL 한 번 이용해 보시지 않으렵니까?



P.S

생각난 김에 구글 그룹스에 그룹을 만들어 보았습니다.


자유게시판: https://groups.google.com/forum/#!forum/dbgl-ko

게임정보 게시판: https://groups.google.com/forum/#!forum/dbgl-ko-game-info


구글 그룹스 설정이 익숙하지 않아서 제대로 한건지는 모르겠습니다만, 자유게시판은 누구나 자유롭게 글을 쓸 수 있게 하였고, 게임정보 게시판은 그룹에 참가한 사람만 글을 작성할 수 있도록 하였습니다. 물론 참가는 자유롭게 할 수 있습니다.





반응형

'게임 > DOSBox Game Launcher' 카테고리의 다른 글

DBGL: DOSBox Game Launcher를 소개합니다.  (2) 2016.10.13

설정

트랙백

댓글

  • BlogIcon 뚜뚜월드 2016.11.09 16:19 신고 답글 | 수정/삭제 | ADDR

    저작권에서 자유롭지 못하니~ 커뮤니티성 사이트로 운영하는게 맞는거죠

    예를들어 런처제작을 가르쳐주는 사이트라던지

    타인의 영역을 침범하지 않는 범위내에서 자유롭게 창의적으로 인터넷 활동을 한다면

    조금 더 유익하게 인터넷을 이용할 수 있겠죠~

    아니면 아예 어둠의영역에서 활동을

    하던지 해야합니다. 토런트쪽으로 자신

    이 하고자하는 셋팅을 다해놓고 전송하

    는 방식~ 이때 최대한 자신이 누군지는

    밝히는 게 좋을리 없겠죠?

    뭐 그런류가 하이퍼스핀이라고 생각되네요!

    우리는 늘 합법과 비합법의 경계에서

    고민해야 합니다. 콩밥을 먹을 것인지

    쌀밥을 먹을 것인지

    • BlogIcon 아자 2016.11.10 11:19 신고 수정/삭제

      댓글을 보고 글을 내릴까 살짝 고민 했습니다.
      저작권 문제 보다는 다른 무엇을 할 여력이 되지는 않은 상태라
      다른 분들이 관심을 가져도 진행할 상황이 아니라서요.

      게임을 직접 배포할 생각이 있는 것도 아니고
      다운로드 방법을 알려드릴 것도 아니라서
      저작권 문제는 걱정하지 않습니다.