2015-03-27 5 views
6

Po pierwsze, w przypadku, gdy istnieje prostszy sposób rozwiązania tego problemu, oto zarys tego, co próbuję osiągnąć. Chcę opisać moje metody testowe za pomocą adnotacji KnownIssue (rozszerzenie AbstractAnnotationDrivenExtension), która pobiera identyfikator defektu jako parametr i sprawdza stan defektu przed wykonaniem testów. Jeśli defekt zostanie naprawiony, będzie kontynuował wykonywanie, jeśli nie zostanie naprawiony, chcę go zignorować, ale jeśli jest zamknięty lub usunięty, chcę wywołać niepowodzenie testu z logowaniem stwierdzające, że test powinien zostać usunięty lub zaktualizowany i adnotację usunięto, ponieważ usterka jest teraz zamknięta lub usunięta.W jaki sposób można uzyskać spock do wykonania innej metody w środowisku wykonawczym za pomocą rozszerzenia opisów?

Mam wszystko, co działa, aż do wywołania awarii testu. To, czego próbowałem, nie działa:

  • Zgłaszanie wyjątku w metodzie visitFeatureAnnotation, która powoduje błąd, który powoduje, że wszystkie testy nie będą wykonywane.
  • Utworzenie klasy rozszerzającej specyfikację i obejmującej metodę testowania, która rejestruje komunikat i kończy się niepowodzeniem, a następnie spróbowała użyć metody feature.featureMethod.setReflection() w celu ustawienia metody do wykonania w innej metodzie. W tym przypadku otrzymuję obiekt java.lang.IllegalArgumentException: obiekt nie jest instancją deklarowania klasy
  • Następnie spróbowałem użyć metody ExpandoMetaClass w celu dodania metody bezpośrednio do deklarującej klasy i wskazania punktu feature.featureMethod.setReflection, ale wciąż mam ten sam wyjątek IllegalArgumentException.

Oto co mam w środku mojego sposobu visitFeatureAnnotation dla mojej ostatniej próbie:

def myMetaClass = feature.getFeatureMethod().getReflection().declaringClass.metaClass 
myMetaClass.KnownIssueMethod = { -> return false } 
feature.featureMethod.setReflection(myMetaClass.methods[0].getDoCall().getCachedMethod()); 

Wszelkie inne pomysły jak mogę to osiągnąć, i albo wywołać awarię testową, lub zastąpić metodę z inny, który się nie powiedzie?

Odpowiedz

1

Ok ... W końcu wymyśliłem rozwiązanie. Oto, co otrzymałem. W ramach metody visitFeatureAnnotation dodaję obiekt CauseFailureInterceptor, który utworzyłem.

Oto pełna źródła w przypadku gdy ktoś jest zainteresowany, po prostu wymaga, aby przedłużyć KnownIssueExtension i wdrożenie metody abstrakcyjne getDefectStatus:

public abstract class KnownIssueExtension extends AbstractAnnotationDrivenExtension<KnownIssue> { 
    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(KnownIssueExtension.class) 
    public void visitFeatureAnnotation(KnownIssue knownIssue, FeatureInfo feature) { 
     DefectStatus status = null 
     try{ 
      status = getDefectStatus(knownIssue.value()) 
     } catch(Exception ex){ 
      LOGGER.warn("Unable to determine defect status for defect ID '{}', test case {}", knownIssue.value(), feature.getName()) 
      // If we can't get info from Defect repository, just skip it, it should not cause failures or cause us not to execute tests. 
     } 
     if (status != null){ 
      if(!status.open && !status.fixed){ 
       LOGGER.error("Defect with ID '{}' and title '{}' is no longer in an open status and is not fixed, for test case '{}'. Update or remove test case.", knownIssue.value(), status.defectTitle, feature.getName()) 
       feature.addInterceptor(new CauseFailureInterceptor("Defect with ID '" + knownIssue.value() + "' and title '" + status.defectTitle + "' is no longer in an open status and is not fixed, for test case '" + feature.getName() + "'. Update or remove test case.")) 
      }else if (status.open && !status.fixed){ 
       LOGGER.warn("Defect with ID '{}' and title '{}' is still open and has not been fixed. Not executing test '{}'", knownIssue.value(), status.defectTitle, feature.getName()) 
       feature.setSkipped(true) 
      }else if (!status.open && status.fixed){ 
       LOGGER.error("Defect with ID '{}' and title '{}' has been fixed and closed. Remove KnownIssue annotation from test '{}'.", knownIssue.value(), status.defectTitle, feature.getName()) 
       feature.addInterceptor(new CauseFailureInterceptor("Defect with ID '" + knownIssue.value() + "' and title '" + status.defectTitle + "' has been fixed and closed. Remove KnownIssue annotation from test '" + feature.getName() + "'.")) 
      }else { // status.open && status.fixed 
       LOGGER.warn("Defect with ID '{}' and title '{}' has recently been fixed. Remove KnownIssue annotation from test '{}'", knownIssue.value(), status.defectTitle, feature.getName()) 
      } 
     } 
    } 

    public abstract DefectStatus getDefectStatus(String defectId) 

} 

public class CauseFailureInterceptor extends AbstractMethodInterceptor{ 
    public String failureReason 
    public CauseFailureInterceptor(String failureReason = ""){ 
     this.failureReason = failureReason 
    } 

    @Override 
    public void interceptFeatureExecution(IMethodInvocation invocation) throws Throwable { 
     throw new Exception(failureReason) 
    } 
} 

class DefectStatus{ 
    boolean open 
    boolean fixed 
    String defectTitle 
} 
Powiązane problemy