2008-08-12 10 views
11

Mam klasy bazowej, która reprezentuje test bazy danych w TestNG, i chcę określić, że wszystkie klasy od tej klasy są grupy "db-test", jednak uznałem, że nie wydaje się to możliwe. Próbowałem @Test adnotacji:Czy mogę określić grupę obejmującą całą klasę w teście testowym TestNG?

@Test(groups = { "db-test" }) 
public class DBTestBase { 
} 

Jednak to nie działa, ponieważ @Test adnotacja postara się zrobić kilka metod do badań i ostrzeżeń/błędy pop up w Eclipse, gdy testy są biegać.

Więc próbowałem wyłączenie testu, więc przynajmniej grupy przypisane są:

@Test(enabled = false, groups = { "db-test" }) 
public class DBTestBase { 
} 

ale wtedy każdy @BeforeTest (i inne podobne adnotacje) również uzyskać wyłączone ... co jest oczywiście nie to, co ja chcieć.

Chciałbym jakoś opisać klasę jako będącą szczególnym typem grupy, ale nie wydaje się to możliwe w TestNG. Czy ktoś ma jakieś inne pomysły?

+0

Po prostu dodano możliwe rozwiązanie problemu Twojej grupy testowej "klasa ogólna". Mógłbyś to sprawdzić i powiedzieć, czy to idzie w dobrym kierunku? – VonC

Odpowiedz

2

Odpowiedź jest dzięki niestandardowym org.testng.IMethodSelector:

Jego includeMethod() może wykluczyć dowolną metodę, jaką chcemy, na przykład publiczną metodę bez adnotacji.

Jednak, aby zarejestrować zwyczaj Java MethodSelector, trzeba go dodać do instancji XMLTest zarządzanym przez jakikolwiek TestRunner, co oznacza, że ​​trzeba własną niestandardową TestRunner.

Jednak, aby zbudować własny TestRunner, trzeba zarejestrować TestRunnerFactory, poprzez -testrunfactory Opcja .

ale -testrunfactory NIGDY nie jest brane pod uwagę przez TestNG klasy ... więc trzeba również zdefiniować niestandardową TestNG Klasa:

  • w celu nadpisania Konfiguruj metody

    (MAP),
  • więc rzeczywiście można ustawić TestRunnerFactory
  • TestRunnerFactory który zbuduje ci niestandardowego TestRunner,
  • TestRunner który będzie ustawiony na XMLTest przykład zwyczaj XMLMethodSelector
  • XMLMethodSelector, który zbuduje niestandardowy IMethodSelector
  • IMethodSelector, który wykluczy dowolne metody TestNG według własnego wyboru!

Ok ... to koszmar. Ale jest to również wyzwanie kodowe, więc musi być trochę trudne;)

Cały kod jest dostępny pod numerem DZone snippets.

Jak zwykle w starciu kod:

  • jednej klasy Java (i całkiem kilku klas wewnętrznych)
  • copy-paste klasę w katalogu „źródło/test” (ponieważ pakiet jest " test ')
  • uruchomić go (żadne argumenty potrzebne)

Aktualizacja od Mike'a Stone'a: ​​

Zaakceptuję to, ponieważ brzmi to całkiem blisko tego, co zrobiłem, ale pomyślałem, że dodam to, co zrobiłem.

Zasadniczo utworzyłem adnotację Grup, która zachowuje się jak własność grup Testów (i innych) adnotacji.

Następnie utworzyłem program GroupAnnotationTransformer, który używa funkcji IAnnotationTransformer do sprawdzania wszystkich testów i definiowanych klas testowych, a następnie modyfikuje test w celu dodania grup, co idealnie sprawdza się w przypadku wykluczania i włączania grup.

Zmodyfikuj kompilację, aby używać nowego transformatora adnotacji, i wszystko działa idealnie!

Cóż ... jedyne zastrzeżenie to to, że nie dodaje grup do metod niebadawczych ... ponieważ w tamtym czasie powstał inny transformator z adnotacjami, który pozwala przekształcić WSZYSTKO, ale w jakiś sposób nie został uwzględniony w TestNG, którego używałem z jakiegoś powodu ... więc dobrym pomysłem jest uczynienie twoich przed/po adnotacjami metod alwaysRun = true ... co jest dla mnie wystarczające.

Wynik końcowy jest co mogę zrobić:

@Groups({ "myGroup1", "myGroup2"}) 
public class MyTestCase { 
    @Test 
    @Groups("aMethodLevelGroup") 
    public void myTest() { 
    } 
} 

I zrobiłem pracę transformator z podklasy i wszystko.

+0

Przepraszam, że tak długo ... Przerwałem oglądanie przez chwilę :-) –

+0

Mike !!! Mike Stone powrócił! Cieszę się, że podoba mi się moje "rozwiązanie": było to jedno z moich pierwszych wyzwań kodowych na SO;) – VonC

+0

"Modyfikuj kompilację"? Modyfikujesz kompilację Testng? Ponieważ złożoność mojego rozwiązania polega właśnie na unikaniu modyfikowania Testng ... – VonC

2

TestNG uruchomi wszystkie publiczne metody z klasy z adnotacją @Test. Może mógłbyś zmienić metody, których nie chcesz, aby TestNG działał jako niepubliczny?

0

Możesz określić adnotację @Test na poziomie metody, która pozwala na maksymalną elastyczność.

public class DBTestBase { 

    @BeforeTest(groups = "db-test") 
    public void beforeTest() { 
     System.out.println("Running before test"); 
    } 

    public void method1() { 
     Assert.fail(); // this does not run. It does not belong to 'db-test' group. 
    } 

    @Test(groups = "db-test") 
    public void testMethod1() { 
     Assert.assertTrue(true); 
    } 
} 

Czy to działa dla Ciebie lub brakuje mi czegoś z Twojego pytania.

1

To wydaje mi się następujący kod prowokacji (Wiki post):

Jak być w stanie wykonać wszystkie metody badań rozszerzonych klasy z grupy „aGlobalGroup” bez:

  • określając grupę "aGlobalGroup" w samej klasie Extended?
  • testowanie publicznych metod rozszerzonych bez adnotacji?

Pierwsza odpowiedź jest prosta:
dodać klasę TestNG (grupy = { „aGlobalGroup”}) na poziomie klasy podstawowej

Grupa ta będzie miała zastosowanie do wszystkich metod publicznych zarówno klasy bazowej i klasa Extended.

ALE: w tej grupie zostaną uwzględnione nawet publiczne metody bez testowania (bez adnotacji TestNG).

WYZWANIE: należy unikać stosowania metod innych niż TestNG.

@Test(groups = { "aGlobalGroup" }) 
public class Base { 

    /** 
    * 
    */ 
    @BeforeClass 
    public final void setUp() { 
      System.out.println("Base class: @BeforeClass"); 
    } 


    /** 
    * Test not part a 'aGlobalGroup', but still included in that group due to the class annotation. <br /> 
    * Will be executed even if the TestNG class tested is a sub-class. 
    */ 
    @Test(groups = { "aLocalGroup" }) 
    public final void aFastTest() { 
     System.out.println("Base class: Fast test"); 
    } 

    /** 
    * Test not part a 'aGlobalGroup', but still included in that group due to the class annotation. <br /> 
    * Will be executed even if the TestNG class tested is a sub-class. 
    */ 
    @Test(groups = { "aLocalGroup" }) 
    public final void aSlowTest() { 
     System.out.println("Base class: Slow test"); 
     //throw new IllegalArgumentException("oups"); 
    } 

    /** 
     * Should not be executed. <br /> 
     * Yet the global annotation Test on the class would include it in the TestNG methods... 
    */ 
    public final void notATest() { 
     System.out.println("Base class: NOT a test"); 
    } 

    /** 
    * SubClass of a TestNG class. Some of its methods are TestNG methods, other are not. <br /> 
    * The goal is to check if a group specify in the super-class will include methods of this class. <br /> 
    * And to avoid including too much methods, such as public methods not intended to be TestNG methods. 
    * @author <a href="http://stackoverflow.com/users/6309/vonc">VonC</a> 
    */ 
    public static class Extended extends Base 
    { 
     /** 
     * Test not part a 'aGlobalGroup', but still included in that group due to the super-class annotation. <br /> 
     * Will be executed even if the TestNG class tested is a sub-class. 
     */ 
     @Test 
     public final void anExtendedTest() { 
      System.out.println("Extended class: An Extended test"); 
     } 

     /** 
     * Should not be executed. <br /> 
     * Yet the global annotation Test on the class would include it in the TestNG methods... 
     */ 
     public final void notAnExtendedTest() { 
      System.out.println("Extended class: NOT an Extended test"); 
     } 
    }