테스트 및 회복성 논쟁: 대상 vs. 함수식 프로그래밍

마이클 피처스의 최근 블로그 게시판에는 매우 격렬한 논쟁이 벌어졌다.Feathers는 일부 대상 프로그래밍 언어의 내장 특성이 테스트 진행에 도움이 되고 대상 프로그래밍 언어로 작성된 코드를 사용하면 복구가 쉽다고 발표했다.
그는 이런 예를 들었다.classX는badMethod라고 불리는 방법이 있는데 이 방법은'고통스러운'작업을 처리한다. 예를 들어 제품 데이터베이스를 호출하고 업데이트하거나 심지어 최종 하드웨어와 관련된 업무를 처리한다.
public class X {    public void method() {       ...       badMethod();       ...    }    ...}

이상적인 디자인은 시스템이 일반적인 클래스와 클래스 그룹을 독립적으로 테스트할 수 있다는 것이다.그러나 만약에 이 예가 이러한 디자인을 실현하지 못한다면'badMethod는 비final이고 덮어쓸 수 있는 방법'이라는 사실은'충분한 기동성을 테스트하는 데 필요한 유연성을 제공하는 데 유리하다. 왜냐하면'덮어쓰기 기능을 허용하고 우리에게 쐐기를 만들어서 테스트를 더욱 간단하게 할 수 있기 때문이다'.
public class TestableX extends X { void badMethod() { /* do nothing */ } }

Feathers는 하나의 seam(이음매)라고 부른다. "수정할 필요가 없이 다른 기능을 대체할 수 있는 부분"이라고 한다.그는 OO 언어가 제공하는 버퍼링 기술이 그 자체가 함수식 언어의 회복보다 더욱 우호적이라고 믿는다.
일부 평론가들은 Feathers 본인을 포함하여 대부분의 언어가 seam을 제공할 수 있다는 사실을 강조했다. 예처리기, 계승/다태성과 위임, 매크로와 함수 지침, 고급 함수, 동적 함수, 일등 함수, 모듈 경계 또는monads...일부 사람들은 진정으로 테스트 가능한 것은 프로그래밍 언어의 선택이 아니라 베이스 디자인이라고 생각한다.예를 들어 John은 어떤 언어를 사용하든지 "코드의 구조는 단원 테스트를 간소화하는 것을 먼저 고려해야 한다."라고 단언했다.또 다른 블로그 앤드류는 "코드의 구조가 필요한 테스트에 맞추지 않았다면"테스트에 순응하는 방향으로 그에 상응하는 수정을 해야 한다고 강조했다.이 때문에 그는 "'seam'에 대한 생각은 테스트 가능성을 실현하기 위해 적절한 설계를 하는 밑바닥 문제를 겨냥한 것이 확실하다"고 평했다. 즉, seam을 적절하게 배치하는 것이다.
이러한 논쟁에 대해 피더스는 대부분의 언어가 seam을 가지고 있지만 관건은 어느 언어가 더 쓰기 편한지, 특히 코드가 테스트하기 편리한 방식으로 설계되지 않은 상황에서
나는'테스트에 맞추어 디자인하는 것'이 진정한 중점이라는 것에 동의하지만, 우리가 무엇을 하든지 이런 방식으로 디자인하지 않은 시스템이 있다는 것을 나도 안다.바로 이 때문에 나는 회복성에 매우 신경을 쓴다.
[…]
나는 seams를 설계하는 것이 가능하다는 것을 알고 있지만, 그것은 문제가 되지 않는다.진정한 문제는 그들이 디자인에 들어가지 않은 상황에서 얼마나 간단하게 배치되었는가이다.
[…] 
물론 seams도 항상 당신이 실현하고자 하는 테스트 입도와 일치하지 않는다. 의심할 여지없이 seam에 좋은 지원을 가진 언어에서 테스트 입도와 일치하려면 훨씬 간단할 것이다. 왜냐하면 seam은 이미 거기에 존재하고 새로운 seam을 만드는 것이 더욱 간단하기 때문이다.
Feathers에 따르면 함수식 언어에서 다른 모델을 사용해서 같은 목적을 달성할 수 있지만, 이것은 무겁다. 그러나 Haskell은 예외이다.Haskell에서 "대부분 테스트에서 피하고 싶은 코드는 모두monad로 실현할 수 있다"고 말했다.
비록 피처스는 사람들이'순수함수식이 모든 단원 테스트의 수요를 충족시킬 수 있다'고 변론할 줄 알았지만, 여전히 많은 평론가들이 함수식 언어의 세부 사항과 함수식 언어가 제공할 수 있는 기회를 고려하지 않았다고 강력하게 변론한다.Erikd는 Feathers가 자바 구조기와 관용 방법을 함수식 코드에 활용하고 있다는 느낌을 표현했다.
우선, 그는 오캠 문법으로 자바 코드를 작성하는 것처럼 보였고, 오캠이 자바처럼 부족하다고 불평했다.그의 결론은 조금도 놀랍지 않다.Ocaml은 자바와 같은 대상을 위한 코드를 작성하기 위해 설계된 것이 아니라 이렇게 간단하다.
그 다음으로 그는 함수식 언어를 사용하는 것이 자바보다 어렵다고 주장했다.Ocaml 문법으로 자바 코드를 작성하는 것은 확실히 어려울 수 있지만 일반적인 Ocaml 코드나 함수식 코드를 작성하는 것은 그리 어렵지 않을 것이다.
많은 함수식 언어의 옹호자들은 함수식 프로그래밍에서 부작용이 없고 Greg M.에 따르면 이 점은 재구성이 필요한 코드를 쓰는 것을 예방할 수 있을 뿐만 아니라 테스트를 더욱 간단하게 할 수 있다고 강조한다.
함수식 언어는 코드 구조를 맨 위에 놓으면 모든 싫은 업무를 분리하고 코드의 순수한 논리를 유지할 수 있다.
[…] 
당신의 단원이 완전히 독립된 보장을 가지고 있을 때, 단원 테스트는 이렇게 간단해질 수 있습니다!아니면 최악의 경우에도 명확하고 뚜렷한 의존성을 보장할 수 있다.
로버트 골드맨도 "일반적인 대상 프로그래밍 언어에서 과도하게 적용된 상태는 테스트에 불리하다"며 "사람들이"엄청난 상호 연관된 대상 실체를 만들어야 테스트에 플랫폼을 제공할 수 있다"며"또한 예상되는 부작용을 검증하는 과정은 추가적인 복잡성을 초래할 수 있다"고 변론했다.반면 "Haskell과 같은 순수함수식 프레임워크에서는 이 모든 문제가 Monad에 봉인되어 있다"고 덧붙였다.Greg Monads에서 제시한 바와 같이, "IO 명령 흐름을 만드는 코드 한 단락 (근거 없이), 그리고 다른 한 단락의 코드를 작성해서 이 IO 흐름을 이용하고 명령을 어떻게 실행하는지 결정할 수 있습니다."
그렉과 같은 진영 출신인 에릭드는 함수식 프로그래밍에 내부 상태가 없기 때문에 상태 변화 처리도 없다고 주장했다."상태 변화가 없는 모델이나 시스템"을 테스트하려면 Feathers가 언급한 테스트가 필요하지 않습니다.
남은 유일한 테스트는 하나의 입력을 수집하여 모든 경계 조건을 테스트하고 이 입력을 대기 함수에 전달한 다음에 출력을 검증하는 것이다.
[...]
만약 구성 요소가 테스트(즉 순수함수)로 분리되고 테스트 결과에 함수가 정확하다는 것을 나타낼 수 있다면 이런 순수함수의 그룹은 합리적이고 당연히 정확하다.
피처스는 이에 대해 "순수함수식을 잘 이해하고 좋은 디자인을 가진 코드에 이런 문제가 있어서는 안 된다는 것도 알고 있다"고 답했다.그는 모든 코드가 좋은 디자인을 가지고 있는 것은 아니라고 강조하며 "Haskell은 부작용을 격리시키는 함수식 프로그래밍 언어의 일종이지만 Ocaml이나 Scala 같은 다른 언어들은 사람들이 코드를 엉망진창으로 만드는 것을 피할 수 없을 것 같다"고 말했다.
어쨌든 피더스의 견해에 동의하지 않는 많은 논쟁자들은 함수식 코드를 엉망진창으로 만드는 유일한 방법은 함수식 언어를 사용할 때 비함수식 용법을 사용하는 것이라고 생각한다.Goldman은 부작용을 가진 프로그램이 "ML, Ocaml, Common Lisp 같은 혼합성 언어의 비함수식 부분으로 공인되고 있다"며 사용을 피해야 한다고 단언했다.Greg 역시 이 관점을 지지한다. 그는 사람들이 굳이 함수식 언어와 맞서 비함수식 용법으로 코드를 작성하지 않으면 권위 있는 OO 코드에서'얻을 수 있는'IoC와 분리 관심사를 얻을 수 없다고 말했다.Erikd는 OO 기술적 배경이 있는 사람이 함수식 언어로 고품질 코드를 작성하려면'구습과 사고방식'을 버리고 가능한 한 오랫동안'대상과 독단적인 프로그래밍 특성'을 잊어야 한다고 주장하는 이유다.

좋은 웹페이지 즐겨찾기