안드로이드 TDD 요약

Dev 2025. 2. 21. 16:22

안드로이드 앱을 개발하게 됐습니다.
할 일은 많고 일손은 부족합니다. 무심코 개발을 진행하다 삐끗하면 버그 잡느라 많은 시간을 소진할 것 같습니다. 그래서 웹앱 개발할 때 도움됐던 TDD를 안드로이드 앱 개발에도 적용해보기로 합니다.

관련 내용을 요약합니다. 과제가 마무리되면 소감도 올려보겠습니다.

 

개요

  • 안드로이드는 앱 테스트 자동화를 위해 JUnit(Test Runner)을 사용한다
  • 안드로이드 앱 프로젝트를 생성하면 유닛 테스트(Unit Test)와 기기 테스트(Instrumentation Test) 환경이 자동 생성된다
    • Unit Test: app/src/test 디렉토리의 test 프로젝트
    • Instrumentation Test: app/src/androidTest 디렉토리의 androidTest 프로젝트

 

상세

  • 주로 ViewModel 클래스가 안드로이드 Unit Test의 대상이다
  • JUnit에서 사용하는 주요 어노테이션은 다음과 같다
    • @Before, @After, @Test, @Ignore, ...
  • 테스트 피라미드

 

TDD 관점 상세

  • 테스트 코드를 (구현 코드보다) 먼저 작성해야 TDD다
  • TDD의 효과
    • 테스트 코드가 프로젝트에 대한 최신의(up-to-date한) 문서 역할을 한다
    • 확신을 갖고 개발할 수 있다 (코드 수정으로 인해 깨지는 기능이 없음을 확신할 수 있다)
  • 테스트 피라미드
    • (최상위) End-to-end Test : Appium, Calaba.sh 사용 (둘 다 Selenium 기반 도구)
    • (중간) Integration Test : mockServer with OkHttp 사용
    • (최하위) Unit Test : JUnit, Robolectric, Espresso 사용

테스트 피라미드

  • 다음과 같은 경우 Unit Test가 아니다
    • DB를 호출하는 경우
    • 네트워크를 이용하는 경우
    • 파일 시스템을 건드리는 경우
    • 다른 유닛 테스트와 동시에 실행할 수 없는 경우
    • 테스트 실행을 위해 (환경 변수 설정 같은) 특별한 작업이 필요한 경우

 

테스트 프레임워크 Robolectric

  • app/src/test 디렉토리에 위치하는 Unit Test 작성에 적합하다 (실행 속도가 빠르고 안드로이드 view의 라이프사이클을 테스트할 수 있다)
  • 테스트 코드 샘플 : 버튼을 클릭하면 inputText에 입력한 문자열을 label에 표시
@Test 
public void shouIdDispIayTextFromEditTextOnTextField_whenClickOnChangeHelloWorldButton() throws Exception { 
  EditText inputText = (EditText) mainActivity.findViewById(R.id.label_input);
  inputText.setText("This app is fun!"); 
  changeHelloWorldTextButton.performClick();
  assertThat(helloWordLabel).hasText("This app is fun!");
}

 

테스트 프레임워크 Espresso

  • app/src/androidTest 디렉토리에 위치하는 기기 테스트(instrumentation test: 실제 기기 또는 에뮬레이터에서 실행되는 테스트) 작성에 적합하다
  • Espresso 테스트는 실행 시간이 오래 걸린다 (그래서 빠른 피드백이 필수인 TDD에 적합하지 않다)
  • Unit Test보다 End-to-end Test에 가깝게 쓰는 게 좋다

 

결론 (이렇게 해보기로 했다)

  • app/src/test 디렉토리의 test 프로젝트에서 Roboletric을 이용해서 Unit Test를 작성하면서 TDD를 시도한다
  • 통합 테스트는 필요할 경우(Unit Test 보다 적게), app/src/androidTest 디렉토리의 androidTest 프로젝트에서 Espresso를 이용해서 작성한다
  • e2e 테스트는 정말 필요성할 때만, Appium을 이용해서 작성한다

 

후기

  • 안드로이드 테스트 자동화 관련 최신 자료가 별로 없었다
  • 테스트 도구 자체는 오랫동안 변화가 없었던 듯하다

 

Ref.

Posted by ingeeC
,

들어가며.
UCAN은 웹3 세상을 위한 Authorization(이후 AuthZ) 기술 입니다.
DID를 이용해서, DID document가 제공하는 pub-key를 인증 수단으로 사용하자는 아이디어가 핵심입니다.

 

웹3를 위한 Access Token, UCAN

 

개요

  • UCAN은 User Controlled AuthZ Network의 약자 (본질은 Access Token)
  • 사용자 데이터의 통제권을 사용자 개인에게 부여하는 기술
  • UCAN의 특징
    • Trustless: UCAN 토큰의 유통 및 권한 행사에 참여하는 누구도 신뢰를 강요하지 않는다 (Trustless한 객체들이 모여 신뢰할 수 있는 결과를 만든다)
    • Secure: 암호 알고리즘이 안전을 보장한다
    • 그리고, local-first, user-originated 하다

 

상세

  • 아이디어의 배경: 탈중앙화된 웹3 환경에서는 기존과 다른 AuthZ 방식을 고민해야 한다
    • ACL을 관리하는 '중앙'이 없기 때문이다
    • AuthZ 관리에 필요한 모든 내용을 포함한 토큰을 이용하면 탈중앙화된 방식으로 권한 관리를 수행할 수 있다 (UCAN은 SPKI와 OCAP/object capability 기술을 참조했다)
  • UCAN 토큰은 영화티켓에 비유할 수 있다
    • 누구도 당신의 신원/Identity을 묻지 않는다
    • 다른 사람에게 티켓을 양도할 수 있다 (이를 위해 극장과 협의할 필요도 없다)
  • UCAN은 자원, 권한, 주체를 명시하기 위해 DID를 사용한다
    • UCAN 규격은 다음 예시와 같다 (Payload 스펙 참조)
      {
        `header`: {
          `alg`: Algorithm, // the type of signature.
          `typ`: Type, // the type of this data structure, JWT.
          `uav`: UCAN version.
        },
        `payload`: {
          `iss`: DID, // Required. Issuer DID (sender)
          `aud`: DID, // Required. Audience DID (receiver)
          `sub`: DID, // Required. Principal that the chain is about (the [Subject])
          `cmd`: String, // Required. The [Command] to eventually invoke
          `args`: {String : Any}, // Required. Any [Arguments] for the Invocation
          `nonce`: Bytes, // Required. Nonce
          `meta`: {String : Any}, // Not Required. [Meta] (asserted, signed data)
          `nbf`: Integer, // Not Required. "Not before" UTC Unix Timestamp
          `exp`: Integer | Null, // Required. Expiration UTC Unix Timestamp
        },
        `signature`: Bytes // A signature (using alg) of the base64 encoded header and payload concatenated together and delimited by '.'
      }
  • UCAN으로 할 수 있는 일
    • Delegation/위임: 권한을 발급, 전달, 제한한다
    • Invocation/사용: 위임된 권한을 행사한다
    • Revocation/철회: UCAN 토큰에 명시된 권한을 철회한다
  • UCAN 토큰 발급과 검증을 위한 다수의 라이브러리가 존재한다

 

Ref.

 

요약.
UCAN은 DID를 기반으로 정의한 탈중앙화 Web3 시대를 위한 억세스 토큰(AuthZ 토큰)입니다.
UCAN이 동작하려면 DID 인프라가 갖춰져 있어야 합니다.

Posted by ingeeC
,

DID-Core 스펙을 요약합니다.
DID-Core 스펙은 2022년 표준화 완료되었습니다 (W3C Recommendation 19 July 2022).
DID는 웹3 세계의 기초를 이루는 기반 기술입니다.

 

Web3를 위한 ID, DID

DID는 `Scheme + DID Method + DID Method-specific ID`로 구성된 문자열이다

  • 예시) did:example:123456789abcdefghi

 

DID는 개념이자 인프라다

  • Key-pair의 유통과 검증을 위해 PKI(인프라)가 존재하는 것처럼, DID와 DID document의 유통과 검증을 위해 DID 인프라가 필요하다
  • 어떤 DID가 있으면 이에 대한 DID document를 가져올 수 있다 (DID Resolution)
  • DID document를 어떻게 저장하고 검색해서 가져오는지는 스펙 범위 밖이다 (마음대로 구현해도 좋다)
  • DID document에는 pub-key 같은 증명수단(verification method)들이 담겨있다 
# DID document 샘플
{
"@context": [
  "https://www.w3.org/ns/did/v1",
  "https://w3id.org/security/suites/ed25519-2020/v1"
]
"id": "did:example:123456789abcdefghi",
"authentication": [{
  "id": "did:example:123456789abcdefghi#keys-1",
  "type": "Ed25519VerificationKey2020",
  "controller": "did:example:123456789abcdefghi",
  "publicKeyMultibase": "zH3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
}]
}

 

DID method가 DID Resolution 방식을 결정한다

  • DID method에 따라 어떤 종류의 DID는 생성하면 끝이다 (더 이상의 추가 절차가 필요 없다)
  • 어떤 종류의 DID는 생성후 verifiable data registry에 등록하는 절차가 필요하다
  • 다양한 DID method 목록이 DID Methods 목록 문서에 정리되어 있다 (비트코인 기반의 btcr, 이더리움 기반의 ethr, IPFS 기반의 ipid를 눈여겨볼 만하다)

 

결론
요약하자면, DID는 ID로 document를 조회할 수 있는 ID체계입니다.

 

Posted by ingeeC
,

웹브라우저 기반 IPFS 네트워크에 관심이 많습니다.
웹브라우저만으로 IPFS 네트워크를 구축할 수 있다면, 서버 없는 서비스(웹3 서비스)가 가능해질 것입니다.
IPFS 블로그(https://blog.ipfs.tech/)에서 이와 관련된 기사를 엄선하여 요약합니다.

The State of Dapps on IPFS: Trust vs. Verification

https://blog.ipfs.tech/dapps-ipfs/
2024-01-29

  • SPA 또는 MPA 형태로 개발된 Dapp은 IPFS로 쉽게 배포할 수 있다
  • Helia는 브라우저를 IPFS 노드로 만들어주는 라이브러리다
  • Helia가 브라우저에서 제공하는 기능은 'CID 데이터 관리'와 'CID 데이터에 대한 Verified Retrieval' 2가지다
    • CID 데이터 관리: 데이터를 CID 데이터로 만들고 해석하는 기능을 제공한다
    • CID 데이터에 대한 Verified Retrieval: CID로 지정된 데이터를 Bitswap 또는 IPFS Gateway를 통해 가져올 수 있다
    • 브라우저 IPFS 노드는 보통 수명주기가 짧기 때문에, CID 데이터를 업로드할 때는 1) pinning 서비스를 이용하거나, 2)직접 운영하는 IPFS 노드(서버)를 이용하는 것이 좋다

 

Verified IPFS Retrieval in Browsers with @helia/verified-fetch

https://blog.ipfs.tech/verified-fetch/
2024-04-18

  • IPFS Gateway는 브라우저에서 IPFS 데이터를 가져올 때 특히 유용한 기술이다
  • IPFS 데이터에 대한 검증(Verification: IPFS Gateway가 전송한 데이터가 내가 요구한 그 데이터가 맞는가에 대한 검증)을 브라우저가 수행한다면, 브라우저는 IPFS Gateway를 신뢰하지 않더라도 문제 없이 이용할 수 있다 (Trustless Gateway 사용이 가능하다)
  • 이를 위해 Interplanetary Shipyard팀(프로토콜랩으로부터 분사한 개발조직)이 @helia/verified-fetch 라이브러리를 개발/배포한다
  • Shipyard팀의 다음 목표는 WebRTC와 WebTransport 프로토콜을 이용해서 브라우저에서 직접 Kubo IPFS 노드와 통신하는 것이다

 

IPFS on the Web in 2024: Update From Interplanetary Shipyard

https://blog.ipfs.tech/2024-shipyard-improving-ipfs-on-the-web/
2024-11-25

  • 우리(Interplanetary Shipyard)가 관심을 갖는 주제는 웹에서 IPFS를 사용하는 것이다
  • 다시 말해 웹브라우저에서 다른 IPFS 노드에 연결할 수 있게 만드는 것이다
  • 이를 위해 다음과 같은 프로젝트를 진행하고 있다
    • Verified Fetch: 브라우저의 fetch API와 유사한 API를 제공, 이를 통해 IPFS 데이터를 검증/수신하는 기능을 제공한다
    • Browser Transport: 브라우저에서 사용할 수 있는 WebRTC와 WebTransport 프로토콜을 기반으로 외부 IPFS 노드와 통신하는 기능을 제공한다
    • AutoTLS: 브라우저는 보안 통신을 위해 CA 공인 인증서를 요구하나 IPFS 노드는 통상 인증서 없이 운영된다. AutoTLS는 이 갭을 메꾸는 기능을 한다
    • Delegated Routing: 브라우저가 IPFS 기능을 호출할 때 이용할 수 있는 https://delegated-ipfs.dev/routing/v1 엔드포인트를 프로토콜랩이 운영/제공한다

 

Browser P2P Connectivity with WebRTC and js-libp2p

https://docs.libp2p.io/guides/getting-started/webrtc/
2024-06-12

  • 브라우저 p2p 커넥션을 만들려면 서버의 지원이 필요하다
    • STUN: 브라우저 노드의 public ip를 알아내기 위해 필요하다
    • TURN: 공개 IP가 부여된 서버가 브라우저-to-브라우저 통신을 중계한다 (서버 비용이 든다. 이 글에서는 TURN 서버 대신 GossipSub 프로토콜 이용을 추천한다)
    • Signaling: libp2p의 WebRTC 통신 초기 연결을 위해서 필요하다
    • Libp2p relay: 브라우저 노드도 PubSub 프로토콜(GossipSub)을 이용하면 서로 연결될 수 있다 (데모 용도로는 좋으나 배틀 테스트를 거치지 않아서 제품 용도로는 신뢰할 수 없다)
  • GossipSub 프로토콜을 이용한 브라우저 간 libp2p 통신 수립 가이드 (실제 동작하는 데모, 강추!)
    • 스텝1: 소스레포 복사 및 라이브러리 설치
    • 스텝2: js-libp2p node.js relay 실행
    • 스텝3: 브라우저에서 js-libp2p 실행
    • 스텝4: 브라우저에서 relay로 연결
    • 스텝5: Circuit Relay를 이용, 브라우저를 dialable하게 만들기
    • 스텝6: relay를 브라우저 앱의 부트스트랩 피어로 설정
    • 스텝7: WebRTC를 listen하여 direct connection 만들기
    • 스텝8: PubSub 피어 찾기

 

결론
1)인푸라 등에서 제공하는 무료 IPFS 노드와 2)Helia 라이브러리와 3)PubSub(GossipSub) 프로토콜을 이용하면 비용 없이 브라우저-to-브라우저 IPFS 네트워크를 구축하는 것이 가능합니다.
다시 말해, 비용 없이 웹3 서비스를 실현할 수 있습니다. 이제 필요한 건 당신의 상상력입니다.

Posted by ingeeC
,

IPFS Camp 2024 요약

Dev 2024. 12. 12. 11:24

유튜브 세션 모음을 요약합니다.
벨기에 브뤼셀에서 있었던 IPFS Camp 2024 행사 동영상입니다.

3줄 요약

  • IPFS 기술에 대한 이야기보다 블록체인 응용사례에 대한 이야기가 많았다 (다소 실망)
  • 개발 업체가 망했다가 오픈소스로 되살아난 '탈중앙화 인증기술, UCAN'과 개발 활동이 멈췄다가 되살아난 '탈중앙화 DB, OrbitDB'가 흥미로왔다
  • 트위터의 대안 서비스 'BlueSky'가 널리 쓰이는 것 같았다 (BlueSky 계정 소개가 많았다)

TOP3 세션

The State of IPFS in JS

  • 12분 동영상
  • kubo(IPFS go 구현체)와 helia(IPFS js 구현체) 개발팀이 PL에서 Interplanetary Shipyard로 분사했다 (후원 바란다)
  • helia의 성능 지표들이 kubo와 비교해서도 양호하다 (helia를 써라)
  • OrbitDB가 돌아왔다 (한때 개발이 중단됐다가 다시 재개됐으며, Helia를 기반으로 한다)

Decentralised Super app. Local First + Blockchain

  • 17분 동영상
  • 중앙 서버에 의존하는 소셜네트워크는 검열을 피할 수 없다 (Post Cloud 기술에 기반한 소셜네트워크가 필요하다)
  • 오프라인에서도 동작하는 소셜네트워크 데모가 좋았다 소스레포

What's New in UCAN 1.0

  • 22분 동영상
  • Fission 회사가 망했어도 UCAN 스펙은 커뮤니티를 기반으로 지속되고 있다
  • JWT와 UCAN의 관계를 청산해서 문제를 단순화시켰다 (JWT 포맷 대신 IPLD를 이용한다)
  • 관련 자료: Ucanto 소스레포, Ucan 워킹그룹

기타등등

그밖에

  • 과학 분야의 대용량 데이터 스토리지 운영 사례,
  • 게이밍 분야의 블록체인 응용 사례,
  • 법률 분야의 분쟁 해소 자동화 사례
    등이 발표됐으나 흥미롭지 않았다.

(이상입니다)

Posted by ingeeC
,