복붙노트

[SPRING] junit 테스트를 개선하려면 어떻게해야합니까?

SPRING

junit 테스트를 개선하려면 어떻게해야합니까?

바로 내 유니폼 테스트는 긴 이야기처럼 보입니다.

장점 : 테스트는 매우 효과적이며 (버그를 발견하는 데 매우 효과적입니다.) 코드를 리팩토링하면 테스트가 리팩토링되기 때문에 API 만 사용하기 때문에 테스트가 매우 안정적입니다. 주어진 상태에서 db를 저장하고 다시로드하는 것과 같은 "더러운 트릭"을 사용하지 않기 때문에 필자의 테스트는 스키마 변경 및 구현 변경을 알지 못합니다.

단점 : 테스트가 유지 보수하기 어려워지고 테스트의 변경 사항이 다른 테스트에 영향을 미칩니다. 테스트는 8-9 분을 실행하며 이는 지속적인 통합에 적합하지만 개발자에게는 다소 실망 스럽습니다. 테스트를 격리해서 실행할 수는 없지만, 관심있는 테스트가 실행 된 후에 중지하는 것이 가장 좋지만, 전에 온 모든 테스트를 반드시 실행해야합니다.

테스트를 개선하는 방법에 대해 어떻게 생각하십니까?

해결법

  1. ==============================

    1.단위 테스트는 이상적으로는 독립적이어야하며 어떤 순서로도 실행할 수 있어야합니다. 그래서 저는 여러분에게 다음과 같이 제안합니다 :

    단위 테스트는 이상적으로는 독립적이어야하며 어떤 순서로도 실행할 수 있어야합니다. 그래서 저는 여러분에게 다음과 같이 제안합니다 :

    몇 명의 사용자를 생성하고 몇 개의 메시지를 보내는 데 8 분이 걸리면 성능 문제가 테스트에 포함되지 않을 수 있습니다. 이는 시스템 자체의 성능 문제 증상 일 수 있습니다. 프로파일 작성자 만이 알고 있습니다!

    [경고 : 나는 이러한 종류의 테스트를 '통합 테스트'로 간주하지 않지만, 소수에 속할 수도 있습니다. 이러한 유형의 테스트를 기능의 단위 테스트로 간주합니다 (예 : TDD)

  2. ==============================

    2.먼저 통합 테스트 인 테스트를 이해하십시오 (아마 외부 시스템에 액세스하고 다양한 클래스에 부딪 힐 수 있습니다). 단위 테스트는 훨씬 더 구체적이어야하며 이미 구축 된 시스템에 대한 도전입니다. 이를 달성하는 주요 쟁점은 일반적으로 코드가 구조화되는 방식입니다.

    먼저 통합 테스트 인 테스트를 이해하십시오 (아마 외부 시스템에 액세스하고 다양한 클래스에 부딪 힐 수 있습니다). 단위 테스트는 훨씬 더 구체적이어야하며 이미 구축 된 시스템에 대한 도전입니다. 이를 달성하는 주요 쟁점은 일반적으로 코드가 구조화되는 방식입니다.

    즉 외부 시스템 (또는 다른 클래스들)에 단단히 결합 된 클래스. 그렇게 할 수 있으려면 단위 테스트 중에 외부 시스템을 치는 것을 실제로 피할 수있는 방법으로 클래스를 작성해야합니다.

    업데이트 1 : 다음을 읽고 결과 디자인으로 파일 / 데이터베이스를 치지 않고 암호화 논리를 실제로 테스트 할 수 있다고 생각하십시오. - http://www.lostechies.com/blogs/gabrielschenker/archive/2009/01/30/ the-dependency-inversion-principle.aspx (자바에는 없지만 문제는 매우 잘 ilustrates) ... 모두 함께 테스트 할 필요없이 독자 / 작성자를위한 집중적 인 통합 테스트를 수행 할 수 있다는 점에 유의하십시오.

    나는 제안한다.

    업데이트 2 : 다른 답변을 바탕으로 TDD 수행에 관한 내용을 정리하고 싶습니다. 말하자면 주어진 로직이 이메일을 보내고, 파일에 정보를 기록하고, 데이터를 데이터베이스에 저장하고, 웹 서비스를 호출하는지 확인해야한다고합니다. (모든 정보를 아는 것은 아니지만 각각에 대한 테스트를 추가하기 시작합니다. . 각 테스트에서 외부 시스템과 충돌하기를 원하지 않는다면, 테스트하려는 것은 로직이 원하는 시스템에 전화를 걸면됩니다. 따라서 사용자를 만들 때 전자 메일이 전송되는지 확인하는 테스트를 작성할 때 논리가 해당 종속성을 호출하는 경우 테스트 할 수 있습니다. 전자 메일을 보내는 코드를 실제로 구현할 필요없이 (그리고 보낸 전자 메일을 알기 위해 외부 시스템에 액세스해야 함) 이러한 테스트 및 관련 논리를 작성할 수 있습니다. 이를 통해 당면 과제에 집중하고 분리 된 시스템을 얻을 수 있습니다. 또한 이러한 시스템에 전송되는 내용을 간단하게 테스트 할 수 있습니다.

  3. ==============================

    3.이제 한 가지 방법으로 여러 가지를 테스트하고 있습니다 (테스트 당 하나의 어설 션 위반). 이러한 일이 바뀌면 전체 테스트가 실패하기 때문에 이것은 나쁜 것입니다. 이로 인해 테스트가 실패한 이유와 해결해야 할 사항을 즉시 명백히 알 수 없습니다. 또한 의도적으로 시스템 동작을 변경하면 변경된 동작 (예 : 테스트가 깨지기 쉬운)에 해당하는 테스트를 더 변경해야합니다.

    이제 한 가지 방법으로 여러 가지를 테스트하고 있습니다 (테스트 당 하나의 어설 션 위반). 이러한 일이 바뀌면 전체 테스트가 실패하기 때문에 이것은 나쁜 것입니다. 이로 인해 테스트가 실패한 이유와 해결해야 할 사항을 즉시 명백히 알 수 없습니다. 또한 의도적으로 시스템 동작을 변경하면 변경된 동작 (예 : 테스트가 깨지기 쉬운)에 해당하는 테스트를 더 변경해야합니다.

    어떤 종류의 테스트가 좋은지 알아 보려면 BDD에 대해 자세히 읽어보십시오. http://dannorth.net/introducing-bdd http://techblog.daveastels.com/2005/07/05/a-new-look- at-test-driven-development / http://jonkruger.com/blog/2008/07/25/why-behavior-driven-development-is-good/

    언급 한 테스트를 개선하기 위해이 컨텍스트와 테스트 메소드 이름을 사용하여 다음 세 가지 테스트 클래스로 나눠 보겠습니다.

    사용자 계정 만들기

    로그인 중

    메시지 보내기

    또한 테스트 속도를 향상시켜야합니다. 몇 초 안에 실행될 수있는 좋은 커버리지를 가진 유닛 테스트 스위트가 있어야한다. 테스트를 실행하는 데 10-20 초 이상이 걸리면 모든 변경 후에 테스트를 실행하는 것을 주저 할 것이며 테스트를 실행하면 몇 가지 빠른 피드백을 잃게됩니다. (데이터베이스와 대화하는 경우 단위 테스트가 아니지만 용도가 있지만 지속적으로 실행될만큼 빠르지 않은 시스템 또는 통합 테스트입니다.) 테스트중인 클래스의 종속성을 조롱해야합니다 또는 그들을 stubbing. 또한 설명에 따르면 테스트가 격리되어 있지 않은 것으로 나타나지만 대신 테스트는 이전 테스트로 인한 부작용에 달려 있습니다. 이것은 아니오입니다. 좋은 테스트는 FIRST입니다.

  4. ==============================

    4.테스트 간의 종속성을 줄입니다. 이것은 Mock을 사용하여 수행 할 수 있습니다. Martin Fowler는 모의 (Mock)에서 스텁이 아니며 특히 조롱이 테스트 간의 종속성을 줄이는 이유에 대해 말합니다.

    테스트 간의 종속성을 줄입니다. 이것은 Mock을 사용하여 수행 할 수 있습니다. Martin Fowler는 모의 (Mock)에서 스텁이 아니며 특히 조롱이 테스트 간의 종속성을 줄이는 이유에 대해 말합니다.

  5. ==============================

    5.테스트 메소드가 다른 테스트에서 재사용되는 리턴 값을 가질 수있게 해주는 JUnit의 확장 인 JExample을 사용할 수 있습니다. JExample 테스트는 Eclipse의 일반적인 JUnit 플러그인으로 실행되며 일반적인 JUnit 테스트와 나란히 작동합니다. 따라서 마이그레이션은 문제가되지 않아야합니다. JExample은 다음과 같이 사용됩니다.

    테스트 메소드가 다른 테스트에서 재사용되는 리턴 값을 가질 수있게 해주는 JUnit의 확장 인 JExample을 사용할 수 있습니다. JExample 테스트는 Eclipse의 일반적인 JUnit 플러그인으로 실행되며 일반적인 JUnit 테스트와 나란히 작동합니다. 따라서 마이그레이션은 문제가되지 않아야합니다. JExample은 다음과 같이 사용됩니다.

    @RunWith(JExample.class)
    public class MyTest {
    
        @Test
        public Object a() { 
            return new Object();
        }
    
        @Test
        @Given("#a")
        public Object b(Object object) { 
            // do something with object
            return object; 
        }
    
        @Test
        @Given("#b")
        public void c(Object object) { 
            // do some more things with object
        }
    
    }
    

    면책 조항, 나는 JExample 개발자 중 하나입니다.

  6. ==============================

    6.TestNG를 사용하면 다양한 방법으로 테스트에 주석을 달 수 있습니다. 예를 들어 위의 테스트에 장기 실행으로 주석을 달 수 있습니다. 그런 다음 자동화 된 빌드 / 연속 통합 서버가이를 실행하도록 구성 할 수 있지만 표준 "대화식"개발자 빌드는 (명시 적으로 선택하지 않는 한) 빌드되지 않습니다.

    TestNG를 사용하면 다양한 방법으로 테스트에 주석을 달 수 있습니다. 예를 들어 위의 테스트에 장기 실행으로 주석을 달 수 있습니다. 그런 다음 자동화 된 빌드 / 연속 통합 서버가이를 실행하도록 구성 할 수 있지만 표준 "대화식"개발자 빌드는 (명시 적으로 선택하지 않는 한) 빌드되지 않습니다.

    이 접근법은 테스트가 실행되도록 정기적 인 빌드를 정기적으로 확인하는 개발자에게 달려 있습니다!

    일부 테스트는 필연적으로 실행하는 데 오랜 시간이 걸립니다. 이 스레드의 주석은 다시 작성됩니다. 성능이 모두 유효합니다. 그러나 테스트가 오랜 시간이 걸린다면 실용적인 해결책은 실행하는 것입니다.하지만 시간이 많이 소요되는 특성으로 인해 개발자가 실행을 피할 수있는 시점에 영향을 미치지 않도록해야합니다.

    참고 : JUnit과 비슷한 기능을 수행하려면 다양한 형식의 테스트에 이름을 붙이고 테스트 클래스의 특정 하위 집합을 실행하는 연속 빌드를 작성하십시오.

  7. ==============================

    7.당신이 설명하는 것과 같은 이야기를 시험함으로써, 당신은 매우 부서지기 쉬운 시험을합니다. 기능의 극히 일부만 변경되면 전체 테스트가 엉망이 될 수 있습니다. 그런 다음 변경 사항의 영향을받는 모든 테스트를 변경하게 될 것입니다.

    당신이 설명하는 것과 같은 이야기를 시험함으로써, 당신은 매우 부서지기 쉬운 시험을합니다. 기능의 극히 일부만 변경되면 전체 테스트가 엉망이 될 수 있습니다. 그런 다음 변경 사항의 영향을받는 모든 테스트를 변경하게 될 것입니다.

    실제로 설명하는 테스트는 단위 테스트보다 기능 테스트 또는 구성 요소 테스트와 비슷합니다. 따라서 비 단위 테스트를 위해 단위 테스트 프레임 워크 (junit)를 사용하고 있습니다. 필자가 알고있는 경우 단위 테스트 프레임 워크를 사용하여 비 단위 테스트를 수행하는 것은 잘못된 것이 아닙니다.

    그래서 다음과 같은 옵션이 있습니다 :

    프로젝트에 있고 시간이 없으면 두 옵션 모두 더 이상 도움이되지 않을 수도 있습니다. 그렇다면 그 검사들과 함께 살아야 할 것이지만, 당신은 고통을 덜어주기 위해 노력할 수 있습니다 :

    API의 서명 예 :

    createUserAndDelete(string[] usersForCreation, string[] userForDeletion);
    logonWithUser(string user);
    sendAndCheckMessageBoxes(string fromUser, string toUser);
    

    일반적인 유닛 테스트를 위해서는 Gerard Meszaros의 XUnit 테스트 패턴을 살펴 보는 것이 좋습니다.

    프로덕션 테스트의 종속성을 없애기 위해 마이클 페더스의 레거시 코드로 효과적으로 작업하기

  8. ==============================

    8.위의 내용 외에도 TDD에 대한 좋은 책을 준비합니다 ( "TDD 및 Java 개발자 용 TDD"권장). TDD 관점에서 접근 할지라도 올바른 종류의 단위 테스트를 작성하는 데 유용한 정보가 많이 있습니다.

    위의 내용 외에도 TDD에 대한 좋은 책을 준비합니다 ( "TDD 및 Java 개발자 용 TDD"권장). TDD 관점에서 접근 할지라도 올바른 종류의 단위 테스트를 작성하는 데 유용한 정보가 많이 있습니다.

    해당 지역에 대한 지식이 많은 사람을 찾아 테스트를 향상시킬 수있는 방법을 찾아 내십시오.

    메일 링리스트에 가입하여 질문을하고 들어오는 트래픽을 읽으십시오. 야후의 JUnit 목록 (groups.yahoo.com/junit과 같은 것). JUnit 세계의 일부 발동기와 쉐이커는 그 목록에 올라 있으며 적극적으로 참여하고 있습니다.

    단위 테스트의 황금률 목록을 가져 와서 여러분의 (그리고 다른 것들) 칸막이 벽에 붙이십시오 :

  9. ==============================

    9.다른 사람들이 구조에 대해 이야기하고 있기 때문에 나는 다른 점을 고를 것입니다. 이것은 bottleknecks를 찾기 위해 코드를 프로파일 링하고 코드 커버리지를 통해 코드를 실행하여 누락 된 사항이 있는지 확인하는 좋은 기회입니다 (결과를 실행하는 데 시간이 주어진다면 재미있을 수 있음).

    다른 사람들이 구조에 대해 이야기하고 있기 때문에 나는 다른 점을 고를 것입니다. 이것은 bottleknecks를 찾기 위해 코드를 프로파일 링하고 코드 커버리지를 통해 코드를 실행하여 누락 된 사항이 있는지 확인하는 좋은 기회입니다 (결과를 실행하는 데 시간이 주어진다면 재미있을 수 있음).

    개인적으로 Netbeans 프로파일 러를 사용하지만 다른 IDE에있는 프로파일 러와 독립형 프로파일 러도 있습니다.

    코드 커버 리지를 위해 나는 Cobertura를 사용하지만 EMMA도 작동합니다 (EMMA는 Cobertura가 가지고 있지 않은 성가심을 가졌습니다 ... 나는 그게 무엇인지 잊었고 더 이상 문제가되지 않을 수도 있음). 그 두 사람은 무료이며 유료 사람도 있습니다.

  10. from https://stackoverflow.com/questions/589603/how-can-i-improve-my-junit-tests by cc-by-sa and MIT license