스텁
스텁은 쓰는 자리마다 다른 물건을 가리키는 말입니다. 검사에서는 정해 둔 값을 돌려주고 멈추는 함수입니다. 원격 호출에서는 호출을 진짜 구현까지 실어 나르는 객체입니다. 타입 검사에서는 타입 정보만 담긴 파일입니다.
상세
스텁이라는 한 낱말이 세 세계에서 각각 다르게 정의됩니다. 검사에서는 돌려줄 값을 지정해 둔 함수입니다. 원격 호출에서는 클라이언트 쪽에 놓인 로컬 객체입니다. 타입 검사에서는 타입 힌트만 담긴 파일입니다.
검사 쪽 정의는 Software Engineering at Google 13장이 적습니다. 스터빙은 그 자체로는 아무 동작이 없는 함수에 동작을 부여하는 과정이라고 적습니다. 그 함수가 정확히 어떤 값을 돌려줄지 지정하는 일이라고 적습니다. 여기서 스텁은 호출을 받아 정해진 답을 내놓는 자리입니다.
원격 호출 쪽 정의는 gRPC(gRPC Remote Procedure Calls, 원격 프로시저 호출) 공식 문서가 적습니다. 클라이언트 쪽에 서비스와 같은 메서드를 구현한 로컬 객체가 있다고 적습니다. 그 객체를 스텁이라고 부른다고 적습니다. 클라이언트가 그 로컬 객체의 메서드를 부르면 메서드는 인자를 알맞은 프로토콜 버퍼 메시지 타입으로 쌉니다. 그리고 서버로 요청을 보냅니다. 서버의 프로토콜 버퍼 응답을 돌려줍니다. 여기서 스텁은 호출을 받아 진짜 구현까지 실어 나르는 자리입니다.
두 정의는 반대 방향을 봅니다. 검사 쪽 스텁은 호출이 자기 자리에서 끝나게 합니다. 원격 호출 쪽 스텁은 호출이 자기를 지나 서버 구현까지 가게 합니다. 목적이 정반대입니다.
flowchart TD
T["테스트"] --> S1["검사 쪽 스텁"]
S1 -->|지정해 둔 값| T
C["클라이언트"] --> S2["원격 호출 쪽 스텁"]
S2 -->|요청| R["서버 구현"]
R -->|응답| S2
세 번째 자리에서는 물건의 종류가 바뀝니다. 파이썬의 PEP(Python Enhancement Proposal, 파이썬 개선 제안) 484 는 스텁 파일을 타입 힌트를 담은 파일이라고 적습니다. 그 힌트는 런타임이 아니라 타입 검사기만 쓴다고 적습니다. 함수도 객체도 아닙니다. 파일입니다.
그래서 스텁이라는 말만으로는 어느 물건을 가리키는지 정해지지 않습니다. 맥락 이름을 먼저 대야 문장이 읽힙니다.
맥락별 뜻
| 맥락 | 뜻 | 출처 |
|---|---|---|
| 검사 | 그 자체로는 동작이 없는 함수에 동작을 주어, 어떤 값을 돌려줄지 지정해 둔 것 | Software Engineering at Google 13장 |
| 원격 호출 | 클라이언트 쪽에 있는 로컬 객체. 서비스와 같은 메서드를 구현한다. 인자를 메시지로 싸서 서버로 보낸다 | gRPC 공식 문서, Core concepts |
| 타입 검사 | 런타임이 아니라 타입 검사기만 쓰는, 타입 힌트를 담은 파일 | PEP 484, Stub Files |
검사
Software Engineering at Google 13장은 스터빙을 과정으로 정의합니다. 그 자체로는 아무 동작이 없는 함수에 동작을 부여하는 과정입니다. 그 함수에 정확히 어떤 값을 돌려줄지 지정하는 일입니다.
같은 문장이 이 세계의 어법도 보여 줍니다. 반환값을 스텁한다고 씁니다. 스텁은 물건 이름이면서 동시에 그 물건을 세우는 행위의 이름입니다.
이 자리에서 스텁이 서는 목적은 진짜 구현을 부르지 않는 것입니다. 호출은 스텁에서 답을 받고 끝납니다.
원격 호출
gRPC 공식 문서는 클라이언트 쪽 스텁을 이렇게 적습니다. 클라이언트 쪽에는 서비스와 같은 메서드를 구현한 로컬 객체가 있습니다. 그 객체를 스텁이라고 부릅니다. 언어에 따라서는 client 라는 이름을 더 쓴다고 적습니다.
클라이언트는 그 로컬 객체의 메서드를 그냥 부르면 됩니다. 메서드가 호출 인자를 알맞은 프로토콜 버퍼 메시지 타입으로 쌉니다. 그리고 서버로 요청을 보냅니다. 서버의 프로토콜 버퍼 응답을 돌려줍니다.
sequenceDiagram
participant 클라이언트
participant 스텁
participant 서버
클라이언트->>스텁: 서비스와 같은 메서드를 부른다
스텁->>서버: 인자를 프로토콜 버퍼 메시지로 싸서 보낸다
서버-->>스텁: 프로토콜 버퍼 응답
스텁-->>클라이언트: 응답을 돌려준다
스텁은 혼자 생기지 않습니다. 같은 문서의 채널 설명은 채널이 클라이언트 스텁을 만들 때 쓰인다고 적습니다.
이 자리에서 스텁이 서는 목적은 진짜 구현에 닿는 것입니다. 호출은 스텁을 지나 서버까지 갑니다.
타입 검사
PEP 484 는 스텁 파일을 타입 힌트를 담은 파일이라고 적습니다. 그 힌트는 런타임이 아니라 타입 검사기만 쓰기 위한 것입니다.
같은 문서가 스텁 파일을 쓰는 자리를 여럿 듭니다. 확장 모듈입니다. 아직 타입 힌트를 붙이지 않은 서드파티 모듈입니다. 아직 타입 힌트가 쓰이지 않은 표준 라이브러리 모듈입니다. 파이썬 2와 3 양쪽에 맞아야 하는 모듈입니다. 애너테이션을 다른 목적으로 쓰는 모듈입니다.
앞의 두 맥락과 달리 여기서 스텁은 실행되는 물건이 아닙니다. 호출을 받지도 않습니다. 타입 검사기가 읽는 파일입니다.
경계
목 객체에 어떤 값을 돌려줄지 지정해 두는 것도 스터빙인가. 맞습니다.
Software Engineering at Google 13장은 목킹 프레임워크를 테스트 안에서 테스트 더블을 만들도록 도와주는 라이브러리라고 적습니다. 그 라이브러리가 객체를 목으로 바꿔 놓습니다. 목은 그 동작이 테스트 안에 인라인으로 지정되는 테스트 더블이라고 적습니다. 같은 문서가 스터빙은 동작이 없는 함수에 동작을 주고 돌려줄 값을 지정하는 과정이라고 정의합니다. 그러니 목 위에서 반환값을 지정하는 순간 그 행위는 스터빙입니다. 스터빙은 물건의 종류가 아니라 행위의 이름이기 때문입니다.
반대는 성립하지 않습니다. 목이 곧 스텁이라는 뜻은 아닙니다. 목은 테스트 더블의 한 갈래를 가리키는 물건 이름입니다. 스텁이라는 말을 물건으로 쓸 때 그것이 목을 포함한다고 이 문서는 적지 않습니다.
관련 항목
테스트 더블 안에서 스텁과 나뉘는 갈래
스텁을 세우는 데 관여하는 요소
스텁이 흉내 내고 감싸는 대상
스텁을 세우는 gRPC 구성 요소
gRPC · 원격 프로시저 호출 · 채널 · 클라이언트
스텁 파일이 쓰이는 경우
확장 모듈 · 표준 라이브러리 · 애너테이션
스텁 파일이 속하는 타입 검사 체계
스텁 파일 · 타입 힌트 · 타입 검사기 · Python
다른 이름: stub