구문 수준에서 언어를 지원하는 기능으로 테스트하지 않는 이유는 무엇입니까?


37

소스 코드 단위 테스트 의 이점을 홍보하는 블로그, 기사 및 웹 사이트의 끝없는 목록을 찾을 수 있습니다 . Java, C ++, C # 및 기타 유형의 언어에 대한 컴파일러를 프로그래밍 한 개발자는 단위 테스트를 사용하여 작업을 확인한 것이 거의 보장됩니다.

그렇다면 왜 인기가 높음에도 불구하고 이러한 언어의 구문이 없는지 테스트하고 있습니까?

Microsoft는 LINQC #에 도입 했는데 왜 테스트를 추가 할 수 없었습니까?

나는 그 언어 변화가 무엇인지 예측하지 않고, 왜 그들이 언어 변화가 없는지 분명히 밝히고 자한다.

예를 들면 : 문장 for의 구문없이 루프를 작성할 수 있다는 것을 알고 있습니다 for. while또는 if/를 사용할 수 있습니다 goto. 어떤 사람은 for성명서가 더 효율적이라고 결정하고 그것을 언어로 소개했습니다.

테스트가 프로그래밍 언어의 동일한 진화를 따르지 않은 이유는 무엇입니까?


24
일반적인 방식으로 쉽게 확장 할 수있는 간단한 규칙을 사용하여 언어를 디자인하는 것과 달리 구문을 추가하여 언어 사양을 더 복잡하게 만드는 것이 실제로 더 낫습니까?
KChaloux

6
"구문 레벨에서"는 무엇을 의미합니까? 구현 방법에 대한 세부 정보 / 아이디어가 있습니까?
SJuan76

21
구문 지원 기능으로 의사 코드 테스트 예제를 제공 할 수 있습니까? 당신이 어떻게 보일지 궁금합니다.
FrustratedWithFormsDesigner

12
@FrustratedWithFormsDesigner 예제 는 D 언어참조하십시오 .
Doval

4
단위 테스트 기능이 내장 된 다른 언어는 Rust입니다.
Sebastian Redl

답변:


36

많은 것들과 마찬가지로 단위 테스트는 언어 수준이 아닌 라이브러리 수준에서 가장 잘 지원됩니다. 특히 C #에는 .NET Framework 고유의 것뿐만 아니라 수많은 단위 테스팅 라이브러리가 있습니다 Microsoft.VisualStudio.TestTools.UnitTesting.

각 단위 테스트 라이브러리에는 테스트 철학과 구문이 약간 다릅니다. 모든 것이 평등하고, 더 많은 선택이 적은 것보다 낫습니다. 단위 테스트가 언어로 구워 졌다면 언어 디자이너의 선택에 잠겨 있거나 라이브러리를 사용하고 언어 테스트 기능을 완전히 피할 수 있습니다.

  • Nunit -C #의 언어 기능을 최대한 활용하는 범용, 관용적으로 설계된 단위 테스트 프레임 워크입니다.

  • Moq- 레코드 / 재생 메타포없이 람다 식과 식 트리를 최대한 활용하는 Mocking 프레임 워크

다른 많은 선택이 있습니다. Microsoft Fakes와 같은 라이브러리는 인터페이스 또는 가상 메서드를 사용하여 클래스를 작성하지 않아도되는 "shims ..."모의를 만들 수 있습니다.

Linq는 언어 기능이 아닙니다 (이름에도 불구하고).

Linq는 라이브러리 기능입니다. 람다 식 및 확장 메서드와 같이 C # 언어 자체에 많은 새로운 기능이 무료로 제공되지만 Linq의 실제 구현은 .NET Framework에 있습니다.

linq 문을 더 깨끗하게하기 위해 C #에 추가 된 구문 설탕이 있지만, 설탕이 linq를 사용할 필요는 없습니다.


1
LINQ가 언어 기능이 아니라는 점에 동의하지만 LINQ를 구현하려면 기본 언어 기능, 특히 제네릭 및 동적 형식이 필요합니다.
Wyatt Barnett

@WyattBarnett : 그렇습니다. 리플렉션 및 속성과 같은 쉬운 단위 테스트도 마찬가지입니다.
Doc Brown

8
LINQ는 람다와 표현 트리가 필요했습니다. 제네릭은 이미 C #에 있었고 (일반적으로 .Net에는 CLR에 있음) 역학은 LINQ와 관련이 없습니다. 동적으로 LINQ를 수행 할 수 있습니다.
Arthur van Leeuwen

Perl의 DBIx :: Class는 LINQ와 유사한 기능을 구현하는 데 필요한 모든 기능이 언어로 구현 된 후 10 년 이상 구현 된 예입니다.
slebetman

2
@ Carson63000 var키워드 와 함께 익명 유형을 의미한다고 생각합니다. :)
M.Mimpen

21

많은 이유가 있습니다. Eric Lippert는 feature XC #에 해당하지 않는 이유 는 예산이 충분하지 않기 때문 이라고 여러 번 언급 했습니다. 언어 디자이너는 구현할 시간과 비용이 무한하며 새로운 기능마다 유지 관리 비용이 발생합니다. 언어를 가능한 한 작게 유지하는 것은 언어 디자이너에게 더 쉬운 일이 아닙니다. 대안 구현 및 도구 (예 : IDE)를 작성하는 사람도 더 쉽습니다. 또한 언어의 일부가 아닌 언어로 무언가가 구현되면 무료로 휴대 할 수 있습니다. 단위 테스트가 라이브러리로 구현되는 경우 한 번만 작성하면 언어를 준수하는 모든 구현에서 작동합니다.

D 는 단위 테스트를위한 구문 수준의 지원을 가지고 있습니다 . 왜 그들이 그것을 던지기로 결정했는지 모르겠지만, D가 "고수준 시스템 프로그래밍 언어"라는 점은 주목할 가치가 있습니다. 설계자들은 C ++이 전통적으로 사용되었던 안전하지 않은 저수준 코드의 종류에 대해 실행 가능하기를 원했으며 안전하지 않은 코드의 실수는 엄청나게 비용이 많이 드는 정의되지 않은 동작입니다. 따라서 안전하지 않은 코드가 작동하는지 확인하는 데 도움이되는 모든 것에 추가 노력을 기울이는 것이 합리적이라고 생각합니다. 예를 들어, 신뢰할 수있는 특정 모듈 만 검사되지 않은 배열 액세스 또는 포인터 산술과 같은 안전하지 않은 작업을 수행 할 수 있도록 할 수 있습니다.

빠른 개발은 또한 그들에게 우선 순위가되었으므로 D 코드를 스크립팅 언어로 사용할 수있을 정도로 빠르게 컴파일하는 디자인 목표로 만들었습니다. 베이킹 유닛 테스트는 언어로 바로 테스트되므로 컴파일러에 추가 플래그를 전달하여 테스트를 실행할 수 있습니다.

그러나 훌륭한 단위 테스트 라이브러리는 몇 가지 방법을 찾아서 실행하는 것 이상을 수행 한다고 생각 합니다. 예를 들어 Haskell의 QuickCheck 를 예로 들어 "모든 x 및 y에 대해"와 같은 것을 테스트 할 수 있습니다 f (x, y) == f (y, x). QuickCheck는 단위 테스트 생성기 로 더 잘 설명되며 "이 입력에 대해이 출력을 기대합니다"보다 더 높은 수준에서 테스트 할 수 있습니다. QuickCheck와 Linq는 그다지 다르지 않습니다. 둘 다 도메인 별 언어입니다. 따라서 단위 테스트 지원을 언어에 적용하지 않고 DSL을 실용적으로 만드는 데 필요한 기능을 추가하지 않겠습니까? 당신은 단위 테스트뿐만 아니라 결과적으로 더 나은 언어로 끝납니다.


3
.Net 세계에 머무르기 위해 F #에 대한 QuickCheck 포트 인 FsCheck가 있으며 C #에서 사용할 수있는 도우미가 있습니다.
Arthur van Leeuwen

.NET 세계에 머 무르려면? 이 질문은 .NET과 관련이 없습니다.
Miles Rout

@MilesRout C #은 .NET의 일부입니다. 질문과 대답은 C #에 대해 자주 이야기하며, LINQ에 대해서도 이야기합니다.
Zachary Dow

질문에는 .NET 또는 C # 태그가 없습니다.
Miles Rout

@MilesRout 사실 일 수도 있지만 태그가 없기 때문에 아무런 관련없다고 합리적으로 말할 수는 없습니다 . :)
Zachary Dow

13

테스트, 특히 테스트 중심 개발은 매우 반 직관적 인 현상이기 때문입니다.

거의 모든 프로그래머는 실제보다 복잡성을 관리하는 것이 훨씬 낫다고 생각하면서 경력을 시작합니다. 많은 프로그래머 들이 회귀 테스트를 많이 사용하지 않으면 가장 큰 프로그래머조차도 큰 오류없이 크고 복잡한 프로그램을 작성할 수 없다는 사실은 많은 실무자에게 심각하게 실망스럽고 수치스러운 일입니다. 따라서 이미 더 잘 알고 있어야하는 전문가들 사이에서도 정기적 인 테스트에 대한 일반적인 탈퇴.

종교적 테스트가 점점 더 주류가되고 있으며 예상되는 사실은 스토리지 용량과 컴퓨팅 성능의 폭발로 인해 이전보다 더 큰 시스템이 구축되고 있으며 매우 큰 시스템은 특히 복잡성 붕괴가 발생하기 때문입니다. 회귀 테스트의 안전망이 없으면 관리 할 수 ​​없습니다. 결과적으로, 특히 고집스럽고 솔직한 개발자조차도 테스트가 필요하고 항상 테스트가 필요하다는 것을 단호하게 인정합니다 (AA 회의에서 고백처럼 들리면 안전 의도가 필요합니다. 개인).

오늘날 인기있는 대부분의 언어는 이러한 태도 변화 이전부터 시작되었으므로 테스트를 거의 기본적으로 지원 assert하지 않습니다. 추세가 지속되면 향후 언어가 라이브러리 수준이 아닌 언어에 대해 더 많은 지원을 제공 할 것이라고 확신합니다.


3
당신은 당신의 사건을 약간 과장합니다. 단위 테스트는 의심 할 여지없이 가장 중요한 요소이지만, 프로그램을 적절한 방식으로 구축 하는 것은 불필요한 복잡성을 최소화하는 방식으로 중요합니다. Haskell과 같은 언어에는 작성된 프로그램의 신뢰성과 확률을 향상시키는 유형 시스템이 있으며 코딩 및 디자인의 모범 사례는 테스트되지 않은 코드의 많은 함정을 피하여 단위 테스트가 다른 것보다 덜 중요하게 만듭니다.
Robert Harvey

1
@RobertHarve ... 그리고 단위 테스팅은 개발자를 간접적으로 이끌어내는 아주 좋은 방법입니다. 테스트를 다른 코드와 함께 사용하지 않고 테스트를 작성하는 동안 API 작업을 수행하면 누출이있는 추상화 나 홀수 메서드 호출을 제한하거나 제거 할 수있는 올바른 사고 방식에 배치 할 수 있습니다. KillianFoth가 아무 것도 과장하고 있다고 생각하지 않습니다.
이즈 카타

@Robert : 그가 강조한다고 유일하게 믿는 것은 "종교적 테스트가 점점 더 주류가되고있다"는 것입니다. 지리적 시간대에 대해 느리게 정의된다면 아마 멀지 않을 것입니다 ..... :)
mattnz

+1 현재 직장에서 새로운 라이브러리와 기술을 사용하여 개발 태도의 변화에 ​​깜짝 놀랐습니다. 내 경력에서 처음으로,이 사람들이 강의하는 보다 정교한 개발 프로세스를 사용하여, 나 대신 내가 바람의 언덕 소리의 상단에있어 같은 느낌. 이러한 태도가 모국어 구문으로 표현되기까지는 시간 문제 일뿐입니다.
Rob

1
죄송합니다. Robert Harvey의 의견입니다. 현재 타입 시스템은 좋은 점검이지만 타입에 대한 제약 조건을 정의하는 데 놀랍게도 부족합니다. 인터페이스를 다루지 만 올바른 동작을 제한하지는 않습니다. (즉, 1 + 1 == 3은 컴파일되지만 +의 구현에 따라 사실 일 수도 있고 그렇지 않을 수도 있습니다) 다음 트렌드가 현재 단위 테스트로 간주되는 것을 결합한 더 표현적인 유형 시스템을 볼지 궁금합니다.
Rob

6

많은 언어가 테스트를 지원합니다. C의 주장은 프로그램이 실패 할 수있는 테스트입니다. 그것은 대부분의 언어가 멈추는 곳이지만 에펠 탑과 더 최근의 Ada 2012에는 사전 불변 (함수에 대한 인수가 전달 해야하는 것)과 사후 불변 (함수의 출력이 전달 해야하는 것)이 있으며 Ada는 변하지 않는. Ada 2012는 유형 불변 값도 제공하므로 Ada 클래스에서 메소드가 호출 될 때마다 유형 불변 값이 리턴되기 전에 확인됩니다.

좋은 테스트 프레임 워크가 제공 할 수있는 완전한 테스트 유형은 아니지만 언어가 가장 잘 지원할 수있는 중요한 테스트 유형입니다.


2
Eiffel에서 약간의 작업을 수행하고 광범위한 어설 션을 사용하면서 경험상 계약 상 수행 할 수있는 모든 작업이 많은 버그를 제거하는 데 도움이됩니다.
Blrfl

2

강력한 유형의 기능 언어를지지하는 일부 지지자들은 이러한 언어 기능이 단위 테스트의 필요성을 줄이거 나 없 that다고 주장합니다.

두, 이럴이이의 좋은 예는 재미와 이익을위한 F 번호에서입니다 여기여기에

개인적으로, 나는 여전히 단위 테스트의 가치를 믿지만 몇 가지 유효한 점이 있습니다. 예를 들어, 코드에서 불법 상태를 표현할 수없는 경우,이 경우 단위 테스트를 작성할 필요가없고 불가능합니다.


2

단위 테스트 와 같이 강조 표시되지 않았기 때문에 필요한 기능 중 일부 를 추가하지 않았다고 주장합니다 .

예를 들어 C #의 단위 테스트는 주로 특성을 사용하여 수행됩니다. 사용자 정의 속성 기능 같은 것들과 반복, 그리고 경쟁에 NUnit과 같은 프레임 워크를 수있는 풍부한 확장 메커니즘을 제공 이론 기반매개 변수화 된 테스트를.

이것은 저의 두 번째 주요 요점을 알려줍니다. 우리는 그것을 언어로 구워 낼 수있는 좋은 시험 성을 만드는 것에 대해 충분히 알지 못합니다. 테스트의 혁신 속도는 다른 언어 구조보다 훨씬 빠르므로 자유롭게 혁신 할 수 있도록 언어에 유연한 메커니즘이 필요합니다.

저는 사용자이지만 TDD에 열광하지는 않습니다. 경우에 따라 특히 디자인 사고를 개선하는 데 매우 유용합니다. 더 큰 레거시 시스템에는 반드시 유용한 것은 아닙니다. 우수한 데이터 및 자동화를 통한 높은 수준의 테스트 는 강력한 코드 검사 문화와 함께 더 많은 이점 을 제공 할 것입니다 .

기타 관련 자료 :

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.