IT

단위 테스트는 얼마나 깊습니까?

lottoking 2020. 9. 8. 08:18
반응형

단위 테스트는 얼마나 깊습니까?


내가 TDD에 대해 알게 된 것은 테스트를 설정하는 데 시간이 걸리고 자연스럽게 게으르다는 것입니다. 저는 항상 가능한 한 약간의 코드를 작성하고 싶습니다. 내가하는 첫 번째 일은 내 생성자가 모든 속성을 설정했지만 과잉입니까?

내 질문은 단위 테스트를 어떤 수준으로 작성하고 있습니까?

.. 너무 많은 테스트 사례가 있습니까?


나는 테스트가 아니라 작동하는 코드에 대해 보수를 받기 때문에 주어진 신뢰 수준에 도달하기 위해 가능한 한 적게 테스트하는 것이 내 철학입니다 (이 신뢰 수준은 업계 표준에 비해 높지만 오만 할 수 있습니다). . 일반적으로 생성자에 잘못된 변수를 설정하는 것과 같은 실수를하지 테스트하지 않습니다. 나는 테스트 오류를 ​​이해하는 경향이 있으므로 복잡한 조건이있는 논리가있을 때 특히주의합니다. 팀에서 코딩 할 때 저는 우리가 전체적으로 잘못되는 경향이있는 코드를 신중하게 테스트하는 전략을 수정합니다.

다른 사람들은이 철학을 바탕으로 다른 테스트 전략을 가지고있을 것이지만, 테스트가 코딩의 내부 루프에 가장 잘 맞을 수있는 방법에 대한 미성숙 한 이해 상태를 감안할 때 나에게 합리적으로 정당해야합니다. 이제 10 년 또는 20 년 후에 우리는 어떤 테스트를 작성하고 어떤 테스트를 작성하지, 차이점을 구분하는지에 대한 것보다 보편적 인 이론을 얼마나 구분하는지입니다. 그 동안 실험은 순서대로 보인다.


깨질 예상되는 항목과 엣지 케이스에 대한 단위 테스트를 작성하십시오. 그 후 버그에 대한 수정을 작성하기 전에 버그 보고서가 들어 오면 테스트 케이스를 추가해야합니다. 개발자는 다음을 확신 할 수 있습니다.

  1. 버그가 수정되었습니다.
  2. 버그가 다시 준비되었습니다.

첨부 된 주석에 따라-시간이 지남에 따라 주어진 클래스에서 많은 버그가있을 때 단위 테스트를 작성하는 접근 방식이 문제를 수 있습니다. 이것은 아마도 재량권이 도움이 될 것입니다.-다시 가능성이있는 버그에 버그 단위 테스트를 추가하거나 다시 발생하면 심각한 문제가 있습니다. 단위 테스트에서 통합 테스트의 척도가있는 시나리오에서 도움이 될 수 있음을 발견했습니다. 코드 경로가 높은 코드를 테스트하면 코드 경로가 아래로 내려갈 수 있습니다.


모든 것이 가능한 한 단순해야하지만 더 단순해야합니다. -ㅏ. 아인슈타인

TDD에 대해 가장 오해를받는 것 중 하나는 첫 번째 단어입니다. 테스트. 이것이 BDD가 등장한 이유입니다. 즉, 즉 D가 중요한 것입니다. 우리 모두는 테스트에 대해 조금에서 많이 생각하고 디자인의 추진에 대해 조금에서 조금씩 생각하는 경향이 있습니다. 그리고 귀하의 질문에 대한 모호한 대답이라고 생각합니다. 그러나 실제로 테스트하는 대신 코드를 구동하는 방법을시기합니다. 그것은 당신을 도울 수있는 것입니다. 디자인은 더 선호되는 문제입니다.


"모든"테스트를 제안하는 사람들에게 : "완전히 테스트"하는 방법 int square(int x)은 공통 언어 및 일반적인 환경에서 약 40 억 개의 테스트 케이스가 필요 하다는 것을 인식하십시오 .

사실, 그보다 훨씬 더 나쁜 :은 방법 void setX(int newX)또한 의무가 없습니다 이외의 다른 멤버의 값을 변경하는 x- 당신이를 테스트하고 obj.y, obj.z모든 호출 한 후 변경되지 않은 상태 로 유지 등 obj.setX(42);?

"모든 것"의 일부만 테스트하는 것이 실용적입니다. 일단 당신이 받아들이면 믿을 수 없을만큼 기본적인 행동을 테스트하지 않습니다. 프로그래머는 모든 버그 위치 확률 분포가지고 있습니다. 현명한 접근 방식은 버그 확률이 ​​높은 예상되는 테스트 지역에 에너지를 집중하는 것입니다.


고전적인 대답은 "파손될 수있는 모든 것을 테스트"하는 것입니다. set 또는 get 외에는 아무것도하지 않는 setter와 getter를 테스트하는 것이 아마도 너무 많은 테스트 시간이 걸리지 않는다는 의미로 해석합니다. IDE가 당신을 위해 작성하지 않는 한, 당신도 그렇게 할 수 있습니다.

생성자 속성을 설정 하지 않으면 나중에 오류가 발생할 수있는 경우 해당 속성이 설정되었는지 테스트하는 [해석] 과도하지 않습니다.


나는 내가있는 클래스의 가정을 다루기 위해 테스트를 작성합니다. 테스트는 요구 사항을 적용합니다. 예를 들어, 기본적으로 x가 3 일 수없는 경우에 해당하는 요구를 듣고 테스트가 확인하겠습니다.

변함없이 조건을 다루는 테스트를 작성하지 않고 "인간"테스트에서 나타납니다. 나는 확실히 그때 하나를 쓸 것이지만, 나는 초기 잡을 것이다. 요점은 테스트가 지루하지만 (아마도) 필요하다고합니다. 나는 완료 수준 충분한 테스트를 작성하지만 그 이상은 아닙니다.


지금 간단한 테스트를 건너 뛰는 문제의 일부는 리팩토링으로 인해 많은 논리로 인해 간단한 속성이 매우 복잡하게 될 수 있습니다. 가장 좋은 아이디어는 테스트를 사용하여 모듈의 요구 사항을 확인할 수있는 것입니다. X를 도착했을 때 Y를 되 찾아야한다면 테스트하고 싶은 것입니다. 그런 다음 나중에 제공되는 코드를 설명 할 때 X가 Y를 확인할 수 있고 해당 요구 사항이 추가 될 때 A에 대한 테스트를 추가하여 B를 제공 할 수 있습니다.

초기 개발 테스트를 작성하는 동안 보낸 시간이 첫 번째 또는 두 번째 버그 수정에서 효과가 있음을 발견했습니다. 3 개월 동안 살펴 보지 않은 코드를 선택하고 수정 사항이 모든 경우를 다루고 "아마도"어떤 것도 손상시키지 않는지 합리적으로 확신 할 수있는 능력은 매우 중요합니다. 또한 단위 테스트가 스택 추적을 넘어서는 버그를 분류하는 데 도움이된다는 것을 알게 될 것입니다. 앱의 개별 부분이 어떻게 작동하고 실패하는지 확인하면 전체적으로 작동하거나 실패하는 이유에 대한 큰 통찰력을 얻을 수 있습니다.


대부분의 경우에 논리가 있다면 테스트 해보자. 여기에는 생성자 및 속성이 포함되며, 특히 속성에 둘 이상의 항목이 설정된 경우 더욱 그렇습니다.

너무 많은 테스트와 관련하여 논쟁의 여지가 있습니다. 어떤 사람들은 모든 것이 견고 함을 위해 테스트되어야한다고 말하고 다른 사람들은 효율적인 테스트를 위해 깨질 수있는 것 (즉, 논리) 만 테스트해야한다고 말합니다.

나는 개인적인 경험에서 두 번째 캠프에 더 의지하고 싶지만 누군가가 모든 것을 테스트하기로 결정했다면 그것이 너무 많지 않다고 말하지 않을 것입니다. 아마도 약간 과잉일지도 모르지만 그들에게는 너무 많지는 않습니다.

그래서, 아니오 – 일반적인 의미에서 "너무 많은"테스트는 개인만을위한 것이 아니라고 말하고 싶습니다.


Test Driven Development는 모든 테스트가 통과되면 코딩을 중지하는 것을 의미합니다.

속성에 대한 테스트가없는 경우이를 구현해야하는 이유는 무엇입니까? "불법"할당의 경우 예상되는 동작을 테스트 / 정의하지 않으면 속성은 어떻게해야합니까?

따라서 나는 전적으로 클래스가 보여야 할 모든 행동을 테스트합니다. "기본"속성을 포함합니다.

이 테스트를 더 쉽게하기 위해 TestFixture값을 설정 / 가져 오기위한 확장 점을 제공하고 유효하고 잘못된 값 목록을 가져오고 속성이 올바르게 작동하는지 확인하는 단일 테스트가있는 간단한 NUnit 만들었습니다 . 단일 속성 테스트는 다음과 같습니다.

[TestFixture]
public class Test_MyObject_SomeProperty : PropertyTest<int>
{

    private MyObject obj = null;

    public override void SetUp() { obj = new MyObject(); }
    public override void TearDown() { obj = null; }

    public override int Get() { return obj.SomeProperty; }
    public override Set(int value) { obj.SomeProperty = value; }

    public override IEnumerable<int> SomeValidValues() { return new List() { 1,3,5,7 }; }
    public override IEnumerable<int> SomeInvalidValues() { return new List() { 2,4,6 }; }

}

람다와 속성을 사용하면 더 간결하게 작성할 수도 있습니다. MBUnit은 이와 같은 것들을 기본적으로 지원합니다. 요점은 위의 코드가 속성의 의도를 포착한다는 것입니다.

추신 : 아마도 PropertyTest 에는 객체의 다른 속성이 변경되지 않았는지 확인하는 방법이 있어야합니다 . 흠 .. 다시 드로잉 보드로.


가능한 최대 범위에 도달하기 위해 단위 테스트를합니다. 일부 코드에 도달 할 수 없으면 적용 범위가 최대한 꽉 찰 때까지 리팩터링합니다.

블라인드 작문 테스트를 마친 후 보통 각 버그를 재현하는 테스트 케이스를 하나씩 작성합니다.

저는 코드 테스트와 통합 테스트를 구분하는 데 익숙합니다. 통합 테스트 중에 (단위 테스트이지만 구성 요소 그룹에 대한 것이기 때문에 단위 테스트의 대상이 아님) 올바르게 구현 될 요구 사항을 테스트합니다.


따라서 테스트를 작성하여 프로그래밍을 많이할수록 테스트의 세분성 수준에 대한 걱정이 줄어 듭니다. 되돌아 보면 내가 행동 을 검증한다는 목표를 달성하기 위해 가능한 가장 간단한 일을하고있는 것 같습니다 . 이것은 내 코드가 내가 요청한 작업을 수행하고 있다는 확신을 생성하고 있음을 의미하지만 내 코드가 버그가 없다는 절대적인 보장으로 간주되지는 않습니다. 올바른 균형은 표준 동작을 테스트하고 아마도 한두 개의 경우를 테스트 한 다음 내 디자인의 다음 부분으로 이동하는 것이라고 생각합니다.

나는 이것이 모든 버그를 다루지 않을 것이며이를 포착하기 위해 다른 전통적인 테스트 방법을 사용한다는 것을 인정합니다.


일반적으로 나는 작게 시작하고 내가 알아야 할 입력과 출력으로 시작합니다. 그런 다음 버그를 수정하면서 수정 한 사항이 테스트되었는지 확인하기 위해 더 많은 테스트를 추가합니다. 그것은 유기적이고 저에게 잘 작동합니다.

너무 많이 테스트 할 수 있습니까? 아마,하지만 당신의 애플리케이션이 얼마나 미션 크리티컬한지에 따라 다르 겠지만, 일반적으로주의를 기울이는 편이 낫습니다.


비즈니스 로직의 "핵심"에서 모든 것을 테스트해야한다고 생각합니다. Getter 및 Setter도 허용하지 않을 수있는 음수 또는 null 값을 허용 할 수 있기 때문입니다. 시간이 있다면 (항상 상사에게 의존) 다른 비즈니스 로직과 이러한 개체를 호출하는 모든 컨트롤러를 테스트하는 것이 좋습니다 (단위 테스트에서 통합 테스트로 천천히 이동).


나는 부작용이없는 간단한 setter / getter 메서드를 단위 테스트하지 않습니다. 그러나 나는 다른 모든 공개 방법을 단위 테스트합니다. 알고리즘의 모든 경계 조건에 대한 테스트를 만들고 단위 테스트의 범위를 확인하려고합니다.

많은 일이지만 그만한 가치가 있다고 생각합니다. 디버거에서 코드를 단계별로 실행하는 것보다 코드 (심지어 테스트 코드 포함)를 작성하는 것이 좋습니다. 코드-빌드-배포-디버그주기는 시간이 많이 걸리고 빌드에 통합 한 단위 테스트가 더 철저할수록 코드-빌드-배포-디버그주기를 거치는 데 드는 시간이 줄어 듭니다.

왜 아키텍처를 코딩하고 있는지 말하지 않았습니다. 그러나 Java의 경우 Maven 2 , JUnit , DbUnit , CoberturaEasyMock을 사용 합니다.


더 많이 읽을수록 일부 단위 테스트는 어떤 패턴과 똑같다고 생각합니다. 부족한 언어 냄새.

사소한 게터가 실제로 올바른 값을 반환하는지 테스트해야 할 때, 이는 게터 이름과 멤버 변수 이름을 혼용 할 수 있기 때문입니다. 루비의 'attr_reader : name'을 입력하면 더 이상 일어날 수 없습니다. 자바에서는 불가능합니다.

게터가 사소하지 않은 경우 에도 여전히 테스트를 추가 할 수 있습니다.


걱정하게 만드는 소스 코드를 테스트하십시오.

실수하지 않는 한 매우 자신있는 코드 부분을 테스트하는 데 유용하지 않습니다.

버그 수정을 테스트하여 버그를 처음 수정하고 마지막으로 수정합니다.

모호한 코드 부분에 대한 확신을 얻으려면 테스트하여 지식을 만드십시오.

헤비 및 중간 리팩토링 전에 테스트하여 기존 기능을 손상시키지 마십시오.


이 답변은 중요도 / 중요성으로 인해 단위 테스트를 원하는 주어진 방법에 대해 사용할 단위 테스트 수를 파악하는 데 더 적합합니다. McCabe의 Basis Path Testing 기술을 사용 하면 다음을 수행하여 단순한 "문장 범위"또는 "분기 범위"보다 코드 범위 신뢰도를 양적으로 높일 수 있습니다.

  1. 단위 테스트 할 메서드의 Cyclomatic Complexity 값을 결정합니다 (예를 들어 Visual Studio 2010 Ultimate는 정적 분석 도구를 사용하여이 값을 계산할 수 있습니다. 그렇지 않으면 플로우 그래프 메서드 ( http://users.csc) 를 통해 직접 계산할 수 있습니다. calpoly.edu/~jdalbey/206/Lectures/BasisPathTutorial/index.html )
  2. 방법을 통해 흐르는 독립 경로의 기본 세트를 나열하십시오. 플로우 그래프 예제는 위의 링크를 참조하십시오.
  3. 2 단계에서 결정된 각 독립 기반 경로에 대한 단위 테스트 준비

참고 URL : https://stackoverflow.com/questions/153234/how-deep-are-your-unit-tests

반응형