2017-12-14 1 views
1

비즈니스 요구 사항을 충족시키기 위해 건너 뛴 테스트에 대해보고하지 않도록 Java 테스트 스위트를 수정하려고합니다.런타임시 후크 또는 수정 클래스

TestNG를 사용하면 사용자 정의 리포터와 수신기를 작성할 수 있지만이 경우 Jenkins 및 SonarQube 인스턴스에서 사용하는 Junit 보고서를 수정하고 싶습니다. TestNG의 코드에 파고

나는이를 참조하십시오

private void initializeDefaultListeners() { 
    m_testListeners.add(new ExitCodeListener(this)); 

    if (m_useDefaultListeners) { 
     addReporter(SuiteHTMLReporter.class); 
     addReporter(Main.class); 
     addReporter(FailedReporter.class); 
     addReporter(XMLReporter.class); 
    if (System.getProperty("oldTestngEmailableReporter") != null) { 
     addReporter(EmailableReporter.class); 
    } else if (System.getProperty("noEmailableReporter") == null) { 
     addReporter(EmailableReporter2.class); 
    } 
    addReporter(JUnitReportReporter.class); 
    if (m_verbose != null && m_verbose > 4) { 
     addListener(new VerboseReporter("[TestNG] ")); 
    }  
} 

는 그래서 TestNG를 그렇게 그 클래스는 원하는 효과를 가지고하지 않을 확장, 기본적으로 JUnitReportReporter 수있게되는 것 같습니다.

Java에서 해당 클래스에 연결하여 generateReport 메서드에 필요한 변경을 수행하거나 런타임에 해당 클래스를 수정하는 방법이 있습니까?
testNG 자체에 패치를 적용 할 수는 있지만 지속 가능하거나 좋은 방법으로 보이지 않거나 빌드 자동화 프로세스를 다시 수행 할 수 있지만 다른 팀이 소유하고 있으므로 다른 것을 선호합니다.

+0

리플렉션을 사용할 수 있지만 다시는 좋지 않습니다. 이것을 달성하기위한 "좋은 연습"방법이 없습니다. 프레임 워크를 해킹하거나 다른 곳에서 처리해야합니다 (예 : 건너 뛰지 않고 테스트 제거). – Unihedron

답변

1

이 문제를 해결하는 방법에는 여러 가지가 있습니다. 이 방법에서는

을 무시 클래스 경로는 기본적으로 시작 :

당신이 TestNG를 최신 릴리스 버전을 사용하고 있는지 확인하십시오

접근 # 1 [그것은 은 6.13.1 현재] 프로젝트에 org.testng.reporters.JUnitReportReporter 복제 한 다음 필요에 따라 로컬로 변경하십시오. 이것은 Java를 스푸핑하여 먼저 변종을 찾고 TestNG에있는 것을 무시합니다. 그런 다음 필요에 맞게 클래스를 수정할 수 있습니다.

접근 방법 # 2 : 사용 안 함 기본 리스너

TestNG를 사용하면 false에 재산을 usedefaultlisteners을 설정하여 기본 리스너를 비활성화 할 수 있습니다. 아래는 Maven을 통해이 작업을 수행하는 방법입니다.

<build> 
    <plugins> 
     <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-surefire-plugin</artifactId> 
      <version>2.19.1</version> 
      <configuration> 
       <properties> 
        <property> 
         <name>usedefaultlisteners</name> 
         <value>false</value> 
        </property> 
      </configuration> 
     </plugin> 
    </plugins> 
</build> 

이제 리포터의 변형을 만든 다음 삽입 할 수 있습니다.

접근 # 3 : 당신의 청중이 당신의 청취자의 순서를 정의 할 수없는 기본 TestNG를으로 주문

에서 실행하게한다. 하지만 그렇게하는 방법이 있습니다.

  1. 모든 기본 수신기를 사용 중지합니다.
  2. 정의 된 SPI 메커니즘 (서비스 로더)을 통해 다른 모든 수신기 (사용자가 작성한 기본 수신기 및 사용자 지정 수신기 모두)에 연결할 프록시 수신기를 정의하십시오.
  3. 결국 프록시 수신기 만 연결합니다. 다른 모든 청취자를 연결하십시오.
  4. 기본적으로 실행될 때 JUnit 보고서 파일을 찾아서 xml 파일로 구문 분석하여 필요에 따라 관련 정보를 제거 할 리스너를 최종적으로 구성합니다.

나는 TestNG에게 청취자를 순서대로 실행시키는 방법에 대한 블로그 게시물을 만들었습니다. 자세한 내용은 here을 참조하십시오.

당신에게 맞는 접근 방식을 선택할 수 있습니다.

+0

# 1은 영리합니다. JVM이 클래스 패스에서 클래스를로드하는 순서를 아십니까? Jar/War/Ear에서 컴파일 한 클래스가 경로의 다른 클래스보다 선호된다고 어떻게 보장 할 수 있습니까? 궁극적으로는 기본 리스너를 끄고 JUnitReportReporter를 오버로드 한 다음 모든 기본 리스너를 수동으로 활성화합니다 (JUnitReportReporter에 대한 오버로드 된 클래스 교환). – Chris

+0

@Chris - 클래스 패스를 만드는 것이 빌드 도구로 쏟아 질 것이라고 생각합니다. 내 이론을 뒷받침 할 수있는 문서가 없다. 나는 경험에 근거하여 이것을 말하고있다. 필자가 제한된 경험을 통해 Java는 클래스 패스에서 사용할 수있는 jar를 검색하기 전에 항상 프로젝트에서 (. 기본적으로 빌드 경로 인) .class를 먼저 찾습니다. –