데이터 정렬시 테스트가 너무 번거 롭습니까?


19

나는 파서를 작성하고 있으며 그 일환으로 Expander하나의 복잡한 문장을 여러 개의 간단한 문장으로 "확장" 하는 클래스가 있습니다. 예를 들어 다음을 확장합니다.

x = 2 + 3 * a

으로:

tmp1 = 3 * a
x = 2 + tmp1

이제이 클래스를 테스트하는 방법, 특히 테스트를 정렬하는 방법에 대해 생각하고 있습니다. 입력 구문 트리를 수동으로 만들 수 있습니다.

var input = new AssignStatement(
    new Variable("x"),
    new BinaryExpression(
        new Constant(2),
        BinaryOperator.Plus,
        new BinaryExpression(new Constant(3), BinaryOperator.Multiply, new Variable("a"))));

또는 문자열로 작성하여 구문 분석 할 수 있습니다.

var input = new Parser().ParseStatement("x = 2 + 3 * a");

두 번째 옵션은 훨씬 간단하고 짧으며 읽기 쉽습니다. 그러나 또한에 밀도를 도입하여 Parser버그 Parser가이 테스트에 실패 할 수 있음을 의미합니다 . 따라서 테스트는의 단위 테스트가되는 것을 멈추고 Expander기술적으로 Parser와 의 통합 테스트가되는 것 같습니다 Expander.

내 질문은 :이 Expander클래스 를 테스트하기 위해 이러한 종류의 통합 테스트에 주로 (또는 완전히) 의존하는 것이 괜찮 습니까?


3
버그가 Parser0으로 만 습관적으로 커밋하는 경우 버그가 다른 테스트에 실패 할 수 있다는 것은 문제가되지 않습니다 Parser. 내가 오히려 걱정하고있는 것은이 버그 가 실패했을Parser 때이 테스트를 성공시킬 수 있다는 버그이다 . 단위 테스트는 결국 버그를 찾기 위해 존재합니다. 테스트는 그렇지 않은 경우에는 중단됩니다.
Jonas Kölker

답변:


27

간단하게 할 수 있다면 훨씬 더 많은 테스트, 훨씬 더 복잡하고 흥미롭고 유용한 동작을 작성하게 될 것입니다. 따라서 관련된 옵션

var input = new Parser().ParseStatement("x = 2 + 3 * a");

꽤 유효합니다. 다른 구성 요소에 따라 다릅니다. 그러나 모든 것은 수십 가지 다른 구성 요소 에 달려 있습니다. 당신이 인생의 1 인치 이내에 무언가를 조롱한다면 아마도 많은 조롱 기능과 테스트 설비에 의존하고있을 것입니다.

개발자는 때때로 모듈, 통합, 스트레스 또는 다른 종류의 테스트없이 단위 테스트 의 순도에 초점을 맞추 거나 단위 테스트 및 단위 테스트 개발 합니다. 이러한 모든 형태는 유효하고 유용하며, Q / A 나 운영 인력뿐만 아니라 파이프 라인을 넘어 개발자의 책임도 있습니다.

내가 사용한 한 가지 접근 방식은 이러한 높은 수준의 실행으로 시작한 다음 생성 된 데이터를 사용하여 테스트의 긴 형식의 최소 공통 분모 표현을 구성하는 것입니다. 예를 들어 input위에서 생성 된 데이터 구조를 덤프하면 다음을 쉽게 구성 할 수 있습니다.

var input = new AssignStatement(
    new Variable("x"),
    new BinaryExpression(
        new Constant(2),
        BinaryOperator.Plus,
        new BinaryExpression(new Constant(3), BinaryOperator.Multiply, new Variable("a"))));

가장 낮은 수준에서 테스트하는 테스트. 그렇게하면 좋은 조합을 얻을 수 있습니다 : 가장 기본적인 기본 테스트 (순수한 단위 테스트) 중 소수는 그 기본 수준에서 테스트를 작성하는 데 일주일을 소비하지 않았습니다. Parser따라서 도우미로 사용하여 더 적은 원자 테스트를 더 많이 작성하는 데 필요한 시간 리소스를 제공합니다 . 최종 결과 : 더 많은 테스트, 더 많은 적용 범위, 더 많은 코너 및 기타 흥미로운 사례, 더 나은 코드 및 더 높은 품질 보증.


2
이것은 모든 것이 많은 다른 사람들에 의존한다는 사실과 관련하여 합리적입니다. 좋은 단위 테스트는 가능한 최소한의 테스트를해야합니다. 가능한 최소량 내에있는 것은 앞에 나오는 단위 테스트로 테스트해야합니다. 파서를 완전히 테스트했다면, 파서를 사용하여 ParseStatement를 안전하게 테스트 할 수 있다고 가정 할 수 있습니다
Jon Story

6
순도의 주요 관심사는 단위 테스트에서 순환 종속성 작성을 피하는 것입니다. 파서 또는 파서 테스트 중 하나가 확장기를 사용하고이 확장기 테스트가 파서 작업에 의존하는 경우 관리하기 어려운 위험이 있으므로 테스트하는 모든 것이 파서와 확장기가 일관된 것입니다. 익스팬더가 실제로 예상대로 작동하는지 테스트하고 싶었 습니다 . 그러나 다른 방법으로 의존성이 없다면,이 단위 테스트에서 파서를 사용하는 것이 단위 테스트에서 표준 라이브러리를 사용하는 것과 실제로 다르지 않습니다.
Steve Jessop

@SteveJessop 좋은 지적입니다. 독립적 인 구성 요소 를 사용하는 것이 중요합니다 .
Jonathan Eunice

3
구문 분석기 자체가 값 비싼 작업 인 경우 (예 : com interop를 통해 Excel 파일에서 데이터 읽기) 구문 분석기 및 출력 코드를 콘솔에 실행하는 테스트 생성 메소드를 작성하여 구문 분석기가 리턴하는 데이터 구조를 다시 작성하는 것 . 그런 다음 생성기의 출력을보다 일반적인 단위 테스트로 복사합니다. 따라서 파서가 실행될 때마다 테스트를 수행 할 때만 파서가 올바르게 작동해야한다는 점에서 상호 종속성을 줄일 수 있습니다. (엑셀 프로세스를 생성 / 파괴하는 멋진 보너스를 몇 초 / 테스트를했다 낭비하지 않습니다.)
댄 닐리

@DanNeely의 접근 방식에 +1. 우리는 데이터 모델의 여러 직렬화 된 버전을 테스트 데이터로 저장하기 위해 비슷한 것을 사용하므로 새로운 코드가 여전히 오래된 데이터와 작동 할 수 있습니다.
Chris Hayes

6

물론 괜찮습니다!

완전한 코드 경로를 사용하는 기능 / 통합 테스트가 항상 필요합니다. 이 경우 완전한 코드 경로는 생성 된 코드의 평가를 포함 함을 의미합니다. 즉, 그 분석 테스트입니다 x = 2 + 3 * a으로 실행하면 그 코드 생성 a = 5뜻을 세트 x17해서 실행하는 경우이 a = -2설정됩니다 x에를 -4.

아래에서 실제로 코드 디버깅에 도움이되는 한 더 작은 비트에 대한 단위 테스트를 수행해야 합니다 . 세분화 된 테스트는 내부 인터페이스가 변경되므로 코드를 변경하면 테스트도 변경해야 할 확률이 높아집니다. 이러한 테스트는 장기적인 가치가 거의 없으며 유지 보수 작업을 추가합니다. 따라서 수익이 감소하는 시점이 있으므로 중단해야합니다.


4

단위 테스트를 통해 고장난 특정 항목과 코드에서 고장난 위치를 정확히 파악할 수 있습니다. 따라서 매우 세밀한 테스트에 적합합니다. 좋은 단위 테스트는 디버깅 시간을 줄이는 데 도움이됩니다.

그러나 내 경험상 단위 테스트는 실제로 올바른 작동을 확인하기에 충분하지 않습니다. 따라서 통합 테스트는 체인 또는 일련의 작업을 확인하는데도 도움이됩니다. 통합 테스트를 통해 기능 테스트를 수행 할 수 있습니다. 지적했듯이 통합 테스트의 복잡성으로 인해 테스트에서 중단되는 코드에서 특정 지점을 찾기가 더 어렵습니다. 또한 체인의 어느 곳에서나 고장이 발생하면 테스트가 실패한다는 점에서 취성이 약간 더 높습니다. 그러나 프로덕션 코드에는 여전히 해당 체인이 있으므로 실제 체인을 테스트하는 것이 여전히 유용합니다.

이상적으로는 두 가지 모두를 갖지만, 일반적으로 자동화 된 테스트를하는 것이 테스트를하지 않는 것보다 낫습니다.


0

구문 분석기에서 많은 테스트를 수행하고 구문 분석기가 테스트를 통과하면 해당 출력을 파일에 저장하여 구문 분석기를 모의하고 다른 구성 요소를 테스트하십시오.

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