문제

망쳤는 여러 유닛 테스트는 몇 시간 전에 갔을 때 통과 리팩터링하게 그들을 더 목적 각각의 테스트는 더 이상 명확하다.그것은 보인다 거기에 사이에는 테스트는'가독성하고 관리할 수 있습니다.을 떠나는 경우에 복제 코드에서는 단위 테스트,그들은 더 읽기 쉬운,그러나 그 후 변경하는 경우 SUT, 어,아 추적하고 변화의 각 사본에는 중복된 코드입니다.

당신은 동의는 이 거래는?그렇다면,당신이 선호하는 테스트를 읽을 수 있는,또는 유지 보수가?

도움이 되었습니까?

해결책

복제 코드는 다른 코드와 마찬가지로 단위 테스트 코드의 냄새입니다. 테스트에 복제 된 코드가있는 경우 업데이트 할 수있는 테스트 수가 불균형하기 때문에 구현 코드를 리팩터링하기가 더 어려워집니다. 테스트는 테스트중인 코드에 대한 작업을 방해하는 큰 부담이 아니라 자신감을 갖도록 리팩터링하는 데 도움이됩니다.

복제가 고정 장치에 설정되어 있으면 더 많은 사용을 고려하십시오. setUp 방법 또는 더 많은 (또는 더 유연한) 제공 창조 방법.

중복이 SUT를 조작하는 코드에있는 경우, 소위 "단위"테스트가 정확히 동일한 기능을 수행하는 이유를 스스로에게 물어보십시오.

중복이 주장에 있다면 아마도 일부가 필요할 것입니다. 맞춤형 어설 션. 예를 들어, 여러 테스트에 다음과 같은 다양한 어설 션이있는 경우

assertEqual('Joe', person.getFirstName())
assertEqual('Bloggs', person.getLastName())
assertEqual(23, person.getAge())

그렇다면 아마도 당신은 싱글이 필요할 것입니다 assertPersonEqual 글을 쓸 수 있도록 방법 assertPersonEqual(Person('Joe', 'Bloggs', 23), person). (또는 아마도 당신은 단순히 평등 연산자를 과부하하면됩니다. Person.)

언급했듯이 테스트 코드를 읽을 수있는 것이 중요합니다. 특히, 의지 테스트의 분명합니다. 많은 테스트가 대부분 동일하게 보이면 (예 : 라인의 3/4이 동일하거나 사실상 동일합니다)주의 깊게 읽고 비교하지 않고 중요한 차이점을 발견하고 인식하기가 어렵습니다. 따라서 복제를 제거하기위한 리팩토링을 발견했습니다 도움이됩니다 모든 테스트 방법의 모든 라인은 테스트 목적과 직접 관련이 있기 때문에 가독성. 직접 관련이있는 라인의 임의의 조합과 단지 보일러 플레이트 인 선의 임의의 조합보다 독자에게 훨씬 더 도움이됩니다.

즉, 때로는 테스트가 비슷하지만 여전히 다르고 여전히 다른 복잡한 상황을 행사하고 있으며, 복제를 줄이는 좋은 방법을 찾기가 어렵습니다. 상식 사용 : 테스트가 읽을 수 있다고 생각하고 의도를 명확하게하고, 테스트에 의해 호출 된 코드를 리팩토링 할 때 이론적으로 최소한의 테스트 수보다 더 업데이트 해야하는 경우, 불완전 성을 수락하고 이동할 수 있습니다. 더 생산적인 일에. 영감이 닥칠 때 언제든지 다시 와서 테스트를 리팩터링 할 수 있습니다!

다른 팁

가독성은 테스트에 더 중요합니다. 테스트가 실패하면 문제가 분명해지기를 원합니다. 개발자는 실패한 내용을 정확하게 결정하기 위해 많은 고려 된 테스트 코드를 많이 살 필요가 없습니다. 테스트 코드가 너무 복잡해지기 때문에 단위 테스트 테스트를 작성해야합니다.

그러나 중복을 제거하는 것은 일반적으로 아무것도 모호하지 않은 한 좋은 일입니다. 테스트에서 복제를 제거하면 API가 더 나을 수 있습니다. 수익이 줄어드는 지점을 지나치지 않도록하십시오.

Code 구현 및 테스트는 서로 다른 동물을 인수 분해하고 규칙을 적용하게 그들을.

중복된 코드나 구조은 항상 냄새가 구현에 코드입니다.시작할 때는 보일러에 구현할 수정해야의 추상화.

다른 한편으로,코드를 테스트해야 합 수준을 유지하는 없다.중복에서 테스트 코드를 달성한 두 개의 목표:

  • 유 테스트 분리됩니다.과도한 테스트는 연결 어렵게 만들 수 있습을 변경하는 단 하나 실패 테스트를 필요로 하는 업데이트하기 때문에 계약이 변경되었습니다.
  • 테스트를 유지는 의미에서 격리됩니다.단일 테스트,실패해야 합리적으로 간단하게 찾을 수 있을 정확히 그것이 무엇인지 테스트합니다.

나는 무시하는 경향이있는 사소한 중복에서 테스트 코드는 만큼 각각의 시험 방법 유지보다 짧은 약 20lines.내가 좋아할 때 설정-실행-지 확인합 리듬에서 명백한 테스트 방법이 있습니다.

경우 중복 섬뜩한에서"확인"의 부분 테스트,그것은 종종에 유익한 정의 사용자 정의 주장 방법이 있습니다.물론 그 방법이 여전히 해야 합 테스트는 명확하게 식별한 관계를 만들 수 있는 명백한 메서드 이름: assertPegFitsInHole ->좋은, assertPegIsGood ->bad.

때 테스트 방법은 성장하고 긴 반복적인 가끔 그것을 찾을 유용한 정의 fill-in-the-공백 테스트 템플릿을 매개 변수입니다.다음 실제 테스트 방법을 감소를 호출하여 템플릿 방법으로 적절한 매개 변수입니다.

로에 대한 많은 것들을 프로그래밍 및 테스트가 없다,분명한 대답합니다.을 개발하는 데 필요한 맛,그리고 그렇게 할 수 있는 가장 좋은 방법은은 실수를 할 수 있습니다.

여러 가지 맛을 사용하여 반복을 줄일 수 있습니다 유틸리티 방법을 테스트하십시오.

나는 프로덕션 코드보다 테스트 코드에서 반복이 더 견딜 수 있지만 때로는 좌절했습니다. 클래스의 디자인을 변경하고 모두 동일한 설정 단계를 수행하는 10 가지 테스트 방법을 조정 해야하는 경우 실망 스럽습니다.

동의한다. 트레이드 오프는 존재하지만 다른 곳에서는 다릅니다.

상태를 설정하기 위해 복제 된 코드를 리팩터 할 가능성이 높습니다. 그러나 실제로 코드를 연습하는 테스트의 일부를 리팩터링 할 가능성이 적습니다. 즉, 코드를 연습하면 항상 여러 줄의 코드를 가져 오면 테스트중인 실제 코드를 냄새와 리팩터라고 생각할 수 있습니다. 이는 코드와 테스트 모두의 가독성과 유지 가능성을 향상시킬 것입니다.

Jay Fields는 "DSL은 건조하지 않고 습기가 없어야한다"라는 문구를 만들었습니다. 습기 수단 설명적이고 의미있는 문구. 나는 같은 것이 테스트에도 적용된다고 생각합니다. 분명히, 너무 많은 복제는 나쁘다. 그러나 모든 비용으로 복제를 제거하는 것은 훨씬 더 나쁩니다. 테스트는 의도적 회피 사양으로 작용해야합니다. 예를 들어 여러 각도에서 동일한 기능을 지정하면 일정량의 복제가 예상됩니다.

나는 이것 때문에 RSPEC를 좋아합니다.

도움이 될 두 가지가 있습니다.

  • 공통 동작을 테스트하기위한 공유 예술 그룹.
    테스트 세트를 정의한 다음 실제 테스트에 설정된 '포함'을 정의 할 수 있습니다.

  • 중첩 된 맥락.
    클래스의 모든 것뿐만 아니라 테스트의 특정 하위 집합에 대한 '설정'및 '눈물 다운'메소드가 본질적으로 가질 수 있습니다.

.NET/java/기타 테스트 프레임 워크가 이러한 방법을 채택할수록 더 나은 방법 (또는 Ironruby 또는 Jruby를 사용하여 테스트를 작성할 수 있습니다. 개인적으로 개인적으로 더 나은 선택이라고 생각합니다).

더 복제 된 코드와 읽기 쉬운 코드 사이에는 관계가 없다고 생각합니다. 테스트 코드가 다른 코드만큼 좋을 것이라고 생각합니다. 비 반복 코드는 잘 완료되면 복제 된 코드를 읽을 수 있습니다.

이상적으로는 단위 테스트가 작성되면 크게 변경되어서는 안됩니다.

단위 테스트는 가능한 한 이산화되면 테스트가 타겟팅하는 특정 기능에 초점을 맞추는 데 도움이됩니다.

그렇게 말하면, 나는 일련의 테스트 세트에서 정확히 동일한 설정 코드와 같이 반복해서 사용하는 특정 코드를 재사용하는 경향이 있습니다.

테스트 코드에는 일반적으로 생산 코드에 적용되는 유사한 수준의 엔지니어링이 필요하다고 생각합니다. 가독성에 유리한 논쟁이있을 수 있으며, 그것이 중요하다는 데 동의 할 것입니다.

그러나 내 경험에 따르면, 잘 알고있는 테스트는 읽고 이해하기가 더 쉽다는 것을 알게되었습니다. 변경된 하나의 변수를 제외하고는 각각이 동일하게 보이는 5 개의 테스트가있는 경우, 단일 다른 항목이 무엇인지 찾기가 매우 어려울 수 있습니다. 마찬가지로, 변경되는 변수 만 볼 수 있도록 고려 된 경우 테스트가 즉시 수행하는 작업을 쉽게 파악할 수 있습니다.

테스트 할 때 올바른 수준의 추상화를 찾는 것은 어려울 수 있으며 가치가 있다고 생각합니다.

"그들을 더 건조하게 만들기 위해 그들을 재현했습니다. 각 테스트의 의도는 더 이상 명확하지 않았습니다."

리팩토링을하는 데 어려움이있는 것 같습니다. 나는 단지 추측하고 있지만, 그것이 덜 명확 해졌다면, 그것이 당신이 완벽하게 명확한 합리적으로 우아한 테스트를 할 수 있도록 더 많은 일을한다는 것을 의미하지 않습니까?

그렇기 때문에 테스트는 UnitTest의 서브 클래스 인 이유입니다. 따라서 올바른 테스트 스위트를 설계 할 수 있으며, 유효성이 쉽고 명확하게 설계 할 수 있습니다.

옛날에는 다른 프로그래밍 언어를 사용하는 테스트 도구가있었습니다. 테스트를 통해 즐겁고 작업하기 쉬운 작업을 설계하는 것은 어렵거나 불가능했습니다.

Python, Java, C# 등을 사용하는 모든 언어의 전체 힘이 있으므로 해당 언어를 잘 사용하십시오. 명확하고 너무 중복되지 않는 잘 생긴 테스트 코드를 달성 할 수 있습니다. 트레이드 오프가 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top