Skip to main content

Command Palette

Search for a command to run...

함수형 프로그래밍으로 단위 테스트를 다시 재미있게 만들기

Published
View as Markdown
함수형 프로그래밍으로 단위 테스트를 다시 재미있게 만들기
J

Code Tinker. Interested in user interface software development. Trying to think functionally.

원문: Leo Lanese, "Making unit-test fun again with Functional Programming"

구조적 필요성

단위 테스트는 소프트웨어 개발에 있어 필수적인 부분이며 좋은 사례로 간주됩니다. 선택이 아니라 필수죠.

간략히 설명하자면 단위 테스트는 현재 우리가 하는 일을 테스트하는 데에 도움을 줄 뿐만 아니라 코드의 기본 단위를 격리시켜 신뢰할 수 있게 해줍니다. 또한 계속하여 소프트웨어를 만들고 밤에 잠도 푹 잘 수 있게 해주죠.

어떤 문제의 해결 방법이든 그 기능성을 시험하지 않는다면 완전할 수 없음에 우리 모두가 동의한 바 있지만 단위 테스트는 시간이 필요하며 항상 그리 재미있는 일은 아닙니다. 따라서 우리는 둘 중 하나의 접근 방식을 취하게 됩니다. 테스트 주도 개발(TDD: Test Driven Development) 혹은 나중에 테스트를 작성하기(WTA: Write After Test)가 우리의 최종 해결 방법이 될 것입니다.

함수형 프로그래밍과 함께 하는 테스트 지향 코드

"테스트하기 어려운 코드는 좋지 않은 코드다." - Joe Eames

코드를 작성하기 전이든 작성하고 나서든 우리는 코드가 동작하고 의도한 대로 기능하는지 확인하기 위해 단위 테스트를 작성할 것입니다. 이 부분에서 코드의 복잡도에 따라 우리는 시간을 더 쓰게 될 수도 혹은 덜 쓰게 될 수도 있습니다. 복잡도는 추상화와 부작용이 없는 순수한 코드를 통해 단순해질 수 있습니다.

간단히 말해서 함수형 프로그래밍은 함수를 이용해 프로그래밍하는 것이라는 점을 기억합시다.

여러 개의 작은 순수 함수를 만드는 것은 실제로 단위 테스트의 복잡도를 단순화할 수 있으며 우리 코드의 이식성, 재사용성, 예측 가능성을 높여줍니다. 그 결과 테스트하기가 쉬워지죠.

선언형과 명령형 패러다임의 제어 흐름

프로그래밍 언어는 일반적으로 선언형과 명령형 두 측면의 스펙트럼으로 나뉩니다.

선언형 언어는 컴퓨터에게 "무엇을 할 지"를 말하는 반면 명령형 언어는 "어떻게 할 지"를 말합니다.

명령형 패러다임 흐름: "어떻게 할 지" 부분이 테스트되어야

명령형 접근에서 우리는 제어에 따릅니다. 컴퓨터가 목표를 달성하기 위해 따라야 하는 단계 (어떻게 할 지)를 정확하고 자세하게 표현하는 코드를 개발자가 작성해야 하죠.

원하는 결과를 달성하기 위한 구체적인 단계를 표현하기 위해 몇 줄의 코드를 사용합니다.

// 명령형 패러다임
var array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for(let i = 0; i < array.length; i++) {
  array[i] = Math.pow(array[i], 2);
}
array; //-> [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

선언형 패러다임 흐름: "무엇을 할 지" 부분이 테스트되어야

선언형 접근에서는 우리가 흐름을 제어합니다. 함수형 접근은 해결해야 하는 문제를 실행할 함수의 집합(무엇을 할 지)으로 구성하는 과정이 포함됩니다. 이러한 접근은 여러 개의 "단일 함수"를 만드는 것을 장려합니다. 오직 한 가지 작업만 수행하는 함수인 단일 함수를 만드는 것은 각각의 함수를 더욱 이해하기 쉽고 테스트하기 쉽게 해주죠.

선언형은 흐름 제어 과정을 추상화하는 대신 데이터의 흐름(무엇을 할 지)을 표현하는 데에 몇 줄의 코드를 사용합니다.

// 선언형 프로그램
// 단위 테스트가 쉬워질 겁니다 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(num => Math.pow(num, 2));

테스트되어야 하는 상태

명령형 프로그래밍 테스트

평가되는 함수들은 시간이 지나며 상태가 변하거나 데이터가 변환됨에 따라 따라야 하는 특정한 단계가 있는 주요 경로입니다. 변수들은 프로그램의 현재 상태를 저장하기 위해 사용됩니다. 이러한 단계들과 변수들은 원하는 순서의 실행 단계를 얻기 위해 모의(mock)로 대체될 필요가 있습니다.

함수형 프로그래밍 테스트

함수형 프로그래밍은 상태가 없습니다. 이러한 무상태성은 함수형 언어를 그저 순수한 함수의 처리 과정(즉, 입력과 출력)을 보는 것만으로 추론할 수 있게 합니다. 또한 함수는 순수하기 때문에 실행 순서 또한 그 중요도가 낮습니다.

함수의 결과는 오직 입력에만 의존하며 다른 것에는 의존하지 않습니다.

동작하는 부분

객체지향은 동작하는 부분을 캡슐화하여 코드를 이해하기 쉽게 만듭니다.

함수형은 동작하는 부분을 최소화하여 코드를 이해하기 쉽게 만듭니다.

  • Michael Feathers

로직의 흐름은 가능한 한 최소화해야 합니다. 로직이 적으면 적을수록 테스트되어야 하는 새로운 로직도 적어집니다. 우리는 이러한 동작하는 부분을 상태 변화 (또는 상태 변이)로 이해해야 합니다. 함수형 프로그래밍에서는 객체지향 프로그래밍에서처럼 상태 변이를 캡슐화하는 것이 아니라 애초에 상태 변이를 다루는 것을 피하려 합니다.

순수한 코드와 "순수한 테스트"

어떻게 보자면 우리는 격리된 한 단위의 코드를 작성할 때마다 함수를 테스트하고 싶다고 할 수 있겠습니다.

즉, 함수는 주어진 하나의 입력에 대해 항상 동일하고 적절한 출력으로 응답합니다. 우리는 특정한 "단위"의 코드를 단독으로 테스트할 수 있으며 이는 다른 단위의 코드로부터 격리되어 있습니다. 어떤 테스트가 되었든 다른 테스트에 의존하면 안 되며 테스트들은 동시에 그리고 어떠한 순서로든 실행 가능해야 합니다.

예를 들어 순수 함수는 부작용이 없기 때문에 디버깅하기 쉽고 병렬적으로 실행하기 수월합니다. 이러한 특징들은 Jasmine 3 버전 이상과 Jest에 의해 강화됩니다.

테스트 작성하기: 당신이 작성하는 대부분의 Redux 코드가 함수이며 순수하기 때문에 모의로 대체하는 과정이 없어도 테스트하기 쉽습니다.

결론

함수형 프로그래밍은 일급 고차 함수에 의존함으로써 함수를 기본 단위로 취급하여 코드의 모듈성과 재사용성을 향상시킵니다. 선언형 패러다임, 순수 함수와 무상태성이라는 특성, 함수 지향 구조의 조합은 신뢰성 있고 빠르며 예측 가능하고 유지보수하기 쉬운 단위 테스트를 생성하는 테스트 지향 코드를 만들 수 있는 가능성을 제공하여 밤에 단잠을 잘 수 있도록 해줄 것입니다.

More from this blog

나의 오픈 소스 시작 이야기

원문: TkDoDo, “My Open Source Origin Story“ 가끔씩 제가 받는 질문이 하나 있는데, 바로 오픈 소스와 리액트 쿼리(React Query)를 어떻게 시작하게 되었는지입니다. 저의 기본 원칙은 어떤 질문을 세 번 받으면 더 이상 답변할 필요가 없도록 질문에 대해 글로 쓴다는 것입니다. 하지만 이 질문은 주로 직접 만났을 때 받는 질문이라 글로 작성할 생각을 한 적이 없었습니다. 최근에 오프라인 컨퍼런스에 더 많이 참...

Jul 30, 2025
나의 오픈 소스 시작 이야기

이더넷이란?

원문: baeldung, “What Is Ethernet?“ 1. 소개 이 튜토리얼에서는 이더넷(Ethernet)과 이를 통해 이루어지는 데이터 전송에 대해 알아보겠습니다. 2. 이더넷이란? 이더넷은 근거리 통신망(LAN) 또는 광역 네트워크(WAN) 내에서 장치들이 데이터를 주고받고 통신하기 쉽게 만들어 주는 널리 사용되는 기술입니다. 컴퓨터, 프린터, 서버는 물론 스마트 홈 기기까지도 이더넷으로 연결됩니다. 가정이나 사무실처럼 제한된 공간...

Jul 20, 2025
이더넷이란?

포스트 개발자 시대

원문: Josh W. Comeau, "The Post-Developer Era" 2년 전 2023년 3월, "프런트엔드 개발의 종말"이라는 제목의 블로그 글을 발행했습니다. 이는 OpenAI가 GPT-4 쇼케이스를 발표한 직후였고, 당시 업계 분위기는 머지않아 인간 소프트웨어 개발자는 필요 없어지고 앞으로는 소프트웨어 개발을 AI가 전담하게 될 것이라는 전망이 지배적이었습니다. 저는 이런 주장에 회의적이었고 그 블로그 글에서 소프트웨어 개발...

Jul 10, 2025
포스트 개발자 시대

널리 사용되는 네트워크 프로토콜

원문: Subham Datta, "Popular Network Protocols" 1. 개요 이 튜토리얼에서는 가장 널리 사용되고 인기 있는 네트워크 프로토콜들을 소개합니다. 2. 네트워크 프로토콜 소개 의사소통과 정보 교환은 현대 사회에서 가장 중요하고 강력한 역량입니다. 컴퓨터 네트워킹이란 여러 대의 컴퓨터와 장치를 케이블이나 위성을 통해 서로 연결하여, 거리와 상관없이 정보·자원·데이터베이스 등을 공유할 수 있게 하는 것을 말합니다. 네...

Jun 20, 2025
널리 사용되는 네트워크 프로토콜

커맨드 라인에 편해지는 법

원문: Julia Evans, "What helps people get comfortable on the command line?" 가끔 커맨드 라인을 써야 하는 친구들과 이야기하다 보면 많은 이들이 여전히 터미널을 두려워하고 있다는 걸 느낍니다. 그럴 때마다 어떤 조언을 할지 잘 모르겠더라고요. 저는 워낙 오래전부터 터미널을 써왔기 때문이죠. 그래서 Mastodon에 이렇게 물어봤습니다. 최근 1~3년 사이에 터미널 공포(?)를 극복한 분...

Jun 10, 2025
커맨드 라인에 편해지는 법
C

CodeSnap

84 posts

한국어로 전달하는 웹 개발 번역 매거진