junit vs testng what are differences
Kompleksowe porównanie między frameworkami JUnit Vs TestNG. Obejmuje porównanie adnotacji i porównanie funkcji z przykładami:
W poprzednim samouczku nauczyliśmy się adnotacji DisplayName i warunkowego wykonywania testów na podstawie różnych kryteriów, takich jak wersja środowiska JRE, zmienne środowiskowe itp. Odpowiedzieliśmy również na kilka ważnych pytań na ten temat.
Ponieważ nieustannie uczyliśmy się o JUnit w poprzednich samouczkach, ten będzie wytchnieniem dla naszych odbiorców, ponieważ na chwilę przeniesiemy naszą uwagę z JUnit jako jedynego planu na porównanie JUnit vs TestNG.
=> Sprawdź idealny przewodnik szkoleniowy JUnit tutaj.
Czego się nauczysz:
- JUnit Vs TestNG: porównanie
- Wniosek
JUnit Vs TestNG: porównanie
funkcje | JUnit | TestNG |
---|---|---|
Limit czasu na testy | tak | tak |
Framework open source | tak JUnit to framework open source | tak TestNG to framework open source |
Przyjazny użytkownikowi | JUnit jest dystrybuowany w różnych modułach, na przykład: ? Do parametryzacji możesz potrzebować JUnit Jupiter. ? To sprawia, że JUnit jest nieco niewygodny w użyciu w porównaniu z TestNG | Wszystkie funkcje TestNG są zawarte w jednym module. To sprawia, że TestNG jest bardziej przyjazny dla użytkownika. |
Główne wsparcie IDE ( Przykład: Eclipse, IntelliJ) | tak Oba obsługują jednakowo większość środowiska IDE | tak Oba obsługują jednakowo większość środowiska IDE |
Implementacja adnotacji | tak JUnit działa na adnotacjach z niewielkimi różnicami dla różnych funkcji | tak TestNG działa na adnotacjach z niewielkimi różnicami dla różnych funkcji |
Realizacja twierdzeń | tak JUnit zapewnia wystarczającą liczbę twierdzeń, aby zweryfikować oczekiwane i rzeczywiste wyniki z pewnymi różnicami w stwierdzeniach w TestNG | tak TestNG obsługuje również ogromną listę twierdzeń do porównania oczekiwanych i rzeczywistych wyników. Dodatkowo TestNG zapewnia dwa mechanizmy asercji - Soft Assertion i Hard Assertion |
Wyjątki | tak JUnit udostępnia funkcję testu wyjątków z niewielką zmianą w stosunku do TestNG | tak TestNG zapewnia również funkcję testu wyjątków |
Testy parametryzowane | tak JUnit obsługuje testy sparametryzowane | tak TestNG obsługuje również testy sparametryzowane |
Pakiet testowy | tak JUnit obsługuje używanie zestawów testów | tak TestNG obsługuje również Test Suite. |
Test zależności | Nie rób JUnit nie obsługuje funkcji testu zależności | tak Jest to zaawansowana funkcja w TestNG przez JUnit. Dzięki tej funkcji jedna metoda może zostać uzależniona od drugiej, tak że będzie ona działać dopiero po uruchomieniu metody zależnej i przejściu jej pomyślnie, w przeciwnym razie test zależny nie zostanie uruchomiony. |
Równoległe wykonywanie testów | Nie rób Wykonywanie równoległe nie jest dostępne w JUnit | tak TestNG obsługuje równoległe wykonywanie testów, ale JUnit nie. Istnieje plik XML TestNG, w którym można ustawić wykonywanie równoległe |
Integracja z Maven | tak Oba narzędzia obsługują integrację Maven | tak Oba narzędzia obsługują integrację Maven |
Realizacje założeń | tak Założenia służą do pomijania testów opartych na pewnych założeniach lub warunkach i ma to zastosowanie tylko w JUnit. | Nie rób TestNG nie obsługuje założeń |
Kolejność wykonywania testów | tak Junit obsługuje kolejność wykonywania testów. | tak TestNG obsługuje kolejność wykonywania testów |
Implementacja Listeners | tak JUnit obsługuje słuchaczy nie za pośrednictwem adnotacji, ale przez interfejs API Listeners. | tak TestNG obsługuje słuchaczy za pomocą adnotacji. |
Ignoruj testy | tak Oba obsługują wyłączanie testów, ale JUnit obsługuje wyłączanie testów do wykonania na podstawie innych warunków | tak Obie obsługują wyłączanie testów |
Raportowanie | tak JUnit musi być zintegrowany z mavenem, aby generować raporty HTML | tak TestNG ma wbudowane raporty HTML. Może być zintegrowany również z Maven lub zewnętrznymi bibliotekami raportowania, takimi jak raporty ATU lub raporty Extent |
Porównanie adnotacji
TestNG i JUnit to frameworki do testów jednostkowych ze świata Java. Obie implementują bardzo bliższe i podobne funkcje. W tej sekcji przyjrzymy się pewnym podobieństwom we wdrażaniu kilku funkcji, a jednocześnie zobaczymy kilka innych funkcji, które są zaimplementowane inaczej w JUnit i TestNG.
# 1) Opis metody testowania
Nie ma różnicy w sposobie określania metody jako metody testowej zarówno w JUnit, jak i TestNG.
JUnit 5 | TestNG |
---|---|
@Test | @Test |
# 2) Adnotacja dotycząca pakietu
- Metoda z adnotacją @BeforeSuite jest wykonywana raz przed uruchomieniem bieżącego zestawu testów.
- Ta adnotacja ma zastosowanie tylko w TestNG.
JUnit 5 | TestNG |
---|---|
Nie dotyczy | @BeforeSuite |
# 3) Adnotacja do metody przed Class
To jest adnotacja dotycząca metody, która ma zostać wykonana raz przed uruchomieniem pierwszej metody testowej w klasie.
JUnit 5 | TestNG |
---|---|
@Przed wszystkim | @Przed zajęciami |
# 4) Adnotacja do metody przed testem
- Ta adnotacja jest wykonywana raz przed metodami zadeklarowanymi w tagu testng.xml.
- Ta adnotacja jest dostępna tylko dla TestNG.
JUnit 5 | TestNG |
---|---|
Nie dotyczy | @BeforeTest |
# 5) Adnotacja dotycząca metody, która ma być wykonana przed każdą metodą z wywołaniami @Test
JUnit 5 | TestNG |
---|---|
@BeforeEach | @BeforeMethod |
# 6) Adnotacja do metody, która ma być wykonana po każdej metodzie z wywołaniami @Test
JUnit 5 | TestNG |
---|---|
@Po każdym | @AfterMethod |
# 7) Adnotacja do metody po teście
- Ta adnotacja jest wykonywana raz po metodach zadeklarowanych w tagu testng.xml.
- Ta adnotacja jest dostępna tylko dla TestNG.
JUnit 5 | TestNG |
---|---|
Nie dotyczy | @AfterTest |
# 8) Adnotacja do metody po klasie
To jest adnotacja dotycząca metody, która ma zostać wykonana raz po uruchomieniu ostatniej metody testowej w klasie.
JUnit 5 | TestNG |
---|---|
@W sumie | @Po zajęciach |
# 9) Adnotacja wyłączająca wykonanie metody testowej.
- JUnit 5 zawiera adnotację wyłączającą wykonanie określonego testu.
- TestNG udostępnia atrybut @Test, tj. „Włączony” z wartością logiczną, która decyduje, czy wykonanie metody będzie wyłączone czy włączone
JUnit 5 | TestNG |
---|---|
@ignorować | @Test (włączone = fałsz) |
Odnosić się do Samouczek 7 Pomijanie wykonywania aby zrozumieć, jak wyłączyć testy w JUnit4 i JUnit 5
# 10) Adnotacja limitu czasu
Adnotacja jest taka sama dla JUnit 5 i TestNG
JUnit 5 | TestNG |
---|---|
@Test (limit czasu = 2000) | @Test (limit czasu = 2000) |
# 11) Oczekiwany atrybut wyjątku
- Klasa wyjątku stwierdza, że po wykonaniu testu generowany jest wyjątek danej klasy.
- Jest to obsługiwane zarówno w JUnit, jak i TestNG z różnicami w sposobie deklarowania obu.
JUnit 5 | TestNG | |
---|---|---|
@Test (oczekiwano = NullPointerException.class) | @Test (spodziewanyException = NullPointerException.class) |
# 12) Adnotacja związana z pakietem
- Metoda z adnotacją @AfterSuite jest wykonywana raz po uruchomieniu bieżącego zestawu testów.
- Ta adnotacja ma zastosowanie tylko w TestNG.
JUnit 5 | TestNG |
---|---|
Nie dotyczy | @AfterSuite |
# 13) Adnotacja związana z grupą
- Adnotacja jest dostępna tylko w TestNG.
- Metoda z adnotacją @BeforeGroups jest uruchamiana przed uruchomieniem metod testowych należących do określonej grupy.
JUnit 5 | TestNG | |
---|---|---|
Nie dotyczy | @BeforeGroups |
- Adnotacja jest dostępna tylko w TestNG.
- Metoda z adnotacją @BeforeGroups jest uruchamiana po uruchomieniu metod testowych należących do określonej grupy.
JUnit 5 | TestNG |
---|---|
Nie dotyczy | @AfterGroups |
# 14) Adnotacje związane z kolejnością wykonania
Zarówno JUnit, jak i TestNG obsługują jawne ustawianie kolejności testów do wykonania. Innymi słowy, ustalanie priorytetów dla przypadków testowych.
- JUnit 5 ma adnotację @TestMethodOrder () z wbudowaną klasą pakietu MethodOrderer - Alphanumeric.class lub OrderAnnotation.class lub Random.class jako parametr wejściowy dla adnotacji.
Odnosić się do Samouczek 9 - Kolejność wykonania testu Junit aby uzyskać więcej informacji na temat ustawiania kolejności wykonywania testów w JUnit.
- TestNG zawiera atrybut „priority” dla adnotacji @Test, który akceptuje wartość liczbową.
JUnit 5 | TestNG |
---|---|
@TestMethodOrder (Alphanumeric.class) | @Test (priorytet = 1) |
Podstawowy program do TestNG i JUnit 4
# 1) Kod TestNG
package newtest.com; import org.testng.annotations.Test; import org.testng.annotations.BeforeMethod; import org.testng.annotations.AfterMethod; import org.testng.annotations.DataProvider; import org.testng.annotations.BeforeClass; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeTest; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeSuite; import org.testng.annotations.AfterSuite; public class NewTestng { @Test(dataProvider = 'dp') public void f(Integer n, String s) { System.out.println(' * * * * * * *Parameterized method * * * * * * * * * '); System.out.println('Integer '+n+' String '+s); System.out.println(' * * * * * * * * * * * * * * * * '); } @BeforeMethod public void beforeMethod() { System.out.println('Before Method'); } @AfterMethod public void afterMethod() { System.out.println('After Method'); } @DataProvider public Object()() dp() { return new Object()() { new Object() { 1, 'a' }, new Object() { 2, 'b'}, }; } @BeforeClass public void beforeClass() { System.out.println('Before Class'); } @AfterClass public void afterClass() { System.out.println('After Class'); } @BeforeTest public void beforeTest() { System.out.println('Before Test'); } @AfterTest public void afterTest() { System.out.println('After Test'); } @BeforeSuite public void beforeSuite() { System.out.println('Before Suite'); } @AfterSuite public void afterSuite() { System.out.println('After Suite'); } }
Oczekiwany wynik:
# 2) Kod JUnit 4
package demo.tests; import static org.junit.Assert.*; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.BeforeClass; import org.junit.AfterClass; public class JunitTest { @Parameterized.Parameters public static Object()() data() { return new Object(3)(0); } @BeforeClass public static void beforeClass() { System.out.println('Before Class'; } @Before public void beforeMethod() { System.out.println('Before Method'); } @Test public void f() { System.out.println(' * * * * * * *test * * * * * * * * * '); int n=10; System.out.println('Integer '+n); System.out.println(' * * * * * * * * * * * * * * * * '); } @After public void afterMethod() { System.out.println('After Method'); } @AfterClass public static void afterClass() { System.out.println('After Class'); } }
Oczekiwany wynik:
JUnit 5 vs TestNG: różnica funkcji z przykładami
# 1) Pakiet testowy
- Zestaw testów to zbiór testów, co oznacza, że łączymy razem wiele przypadków testowych z wielu klas.
- Podejście, z którego korzysta TestNG, jest inne i potężne w porównaniu z JUnit.
Zestaw testów w JUnit 5
Przyjrzyjmy się szybko, jak JUnit 5 stosuje zestaw testów.
Odnosić się do Samouczek 8 -JUnit Test Suites & Filtering Przypadki testowe dla lepszego zrozumienia implementacji zestawu testów w JUnit 4 i JUnit 5.
@RunWith(JUnitPlatform.class) @SelectClasses({JUnit5TestCase1.class, JUnit5TestCase2.class }) public class JUnitTestSuite { }
Zestaw testów w TestNG
TestNG używa XML jako poniższego szablonu, aby opakować wszystkie logicznie łączące klasy Test
# 2) Test sparametryzowany
Zarówno TestNG, jak i JUnit pozwalają na parametryzację testów, co jest niczym innym jak przeprowadzaniem tych samych testów z różnymi zmianami danych.
Sparametryzowany test w JUnit 4
@RunWith(value=Parameterized.class) public class JUnitclass{ int n; public JUnitclass (int num){ this.n=num; } @Parameters public static Iterable data(){ Object()() objectArray =new Object()() {{1},{2},{3}}; returnArrays.asList(objectArray); } @Test public void Junittst(){ System.out.println(“Multiples of 2 are :”+ 2*n); } }
Sparametryzowany test w TestNG
Istnieją 2 sposoby wykorzystania parametryzacji w TestNG
- @Parameters i przechodząc przez TestNG XML
- Adnotacja @DataProvider
a) @Parameters i przechodząc przez TestNG XML
public class testins{ @Test @Parameters(value=”env_pd”) public void paramEnv(str env_pd){ If(env_pd=”QA”){ url=”definetest.com” } else if(env_pd=”accpt”){ url=”defineacc.com” }}}
XML dla tego samego
b) Dostawca danych
Adnotacja DataProvider zawsze zwraca Object () (), który jest tablicą obiektów.
@DataProvider(name='state') public Object()() getDataFromDataprovider(){ return new Object()() { { 'Maharashtra', 'Pune' }, { 'Karnataka', 'Bangalore' }, { 'Kerala', 'Trivandrum' } }; @Test(dataProvider=”state”) public void paramMethd(str stateName, str cityName){ System.out.println(stateName+” ”+cityName); }
# 3) Limit czasu
Jeśli określony test nie zakończy się w określonym czasie, zostanie przekroczony limit czasu. W innych wątek zostaje przerwany.
konwerter youtube na mp4 online za darmo bez pobierania
Limit czasu w JUnit
Istnieją różne podejścia do implementacji Timeout w JUnit. To są:
- Używanie zwykłego limitu czasu z określonymi milisekundami
- Używanie limitu czasu z potwierdzeniem
- Korzystanie z globalnego limitu czasu
Będziemy mieć szczegółowy samouczek dotyczący limitu czasu dla JUnit 4 i JUnit 5.
Poniżej znajduje się fragment pokazujący użycie zwykłego limitu czasu w JUnit 5:
@Test(timeout = 5000) public void testTimeout() throws InterruptedException { while (true) { } }
Powyższy limit czasu testu po 5 sekundach.
Limit czasu w TestNG
TestNG wykorzystuje również prosty sposób implementacji Timeout:
@Test(timeout = 5000) public void testTimeout() throws InterruptedException { while (true) { } }
# 4) Test wyjątków
Test wyjątku zapewnia, że gdy zostanie zgłoszony ten wstępnie zdefiniowany wyjątek, zostanie on bezpiecznie przechwycony i powiadomiony w dziennikach.
Test wyjątków w JUnit 4
@Test (expected = NumberFormatException.class) public void converttoint() { Int j=Integer.parseInt(“Four”); }
Będzie osobny samouczek szczegółowo omawiający Wyjątki dla JUnit 4 i 5.
Test wyjątków w TestNG
Istnieje niewielka zmiana w deklaracji testu wyjątków w TestNG:
@Test (expectedExceptions = NumberFormatException.class) public void converttoint() { Int j=Integer.parseInt(“Four”); }
# 5) Wyłącz test
Zarówno TestNG, jak i JUnit umożliwiają wyłączenie testu do wykonania.
Wyłączono test w JUnit 5
@Disabled adnotacja, gdy jest używana na początku klasy, wszystkie testy w klasie są pomijane do wykonania. Adnotacja, gdy jest używana nad określoną metodą @Test, ten konkretny przypadek testowy jest wyłączany do wykonania.
import org.junit.AfterClass; @Disabled('the testcase is under development') public class JUnitProgram {
Wyłączono test w TestNG
TestNG umożliwia testowi wyłączenie wykonywania testu, gdy atrybut „enabled” adnotacji @Test ma wartość false i jest włączony, gdy atrybut ma wartość true. Jeśli wszystkie testy w klasie muszą być włączone, jawnie zaznacz opcję enabled = true dla każdej metody @Test.
Poniżej znajduje się fragment kodu, który demonstruje pominięcie testu.
@Test(enabled=false) public void f_validate(){ // let us skip this function}
# 6) Testy grupowe
Na wielu stronach i forach pojawiły się sprzeczne stwierdzenia, na których ludzie wspominali, że JUnit nigdy nie wspierał grupowania testów o określonej nazwie grupy.
Adnotacje @BeforeGroups i @AfterGroups są dostępne tylko z TestNG, jednak grupowanie jest dozwolone w JUnit 4, a także w JUnit 5. Tutaj szybko zademonstrujemy użycie testów grupowych w JUnit 5. Testy grupowe są nazywane kategoriami w JUnit 4 i tagach w JUnit 5.
Możesz odnieść się do Samouczek 8 - JUnit Test Suites & Filtering Tests aby uzyskać szczegółowe informacje na temat wykorzystania w JUnit.
jak znaleźć klucz bezpieczeństwa routera
Testy grupowe w JUnit 5
@Tag(“Regression”) @Test public void junitMethod1(){} @Tag(“SmokeTest”) @Test public void junitMethod2(){
Fragment kodu z JUnit5TestSuite.java:
Poniższy kod zawiera grupę o nazwie „Regression” i wyklucza grupę „SmokeTest”, która wnioskuje, że zostanie uruchomiona junitMethod1 (), jednak junitMethod2 () jest wykluczona.
@RunWith(JUnitPlatform.class) @SelectPackages({“demo.tests“}) @IncludeTags(“Regression”) @ExcludeTags(“SmokeTest”) public class JUnit5TestSuite { }
Testy grupowe w TestNG
Jeśli powyższy fragment ma zostać zinterpretowany w TestNG, poniżej znajduje się kod dla tego samego:
@Test(groups={“Regression” }) public void junitMethod1(){} @Test(groups={“SmokeTest” }) public void junitMethod2(){}
TestNG XML wygląda następująco:
Tutaj metody grup regresji są uwzględnione w runner, podczas gdy pozostałe grupy, w tym SmokeTest, są wykluczone.
# 7) Testy równoległe
Ta funkcja jest dostępna tylko z TestNG. Zazwyczaj przypadki testowe są rodzajami wątków, które są wywoływane jeden po drugim. Jeśli jednak chcesz zaoszczędzić czas wykonywania, możesz to kontrolować w TestNG, ustawiając testy tak, aby były uruchamiane równolegle i podając liczbę wątków, które muszą być uruchamiane jednocześnie.
Pokrótce zademonstrujemy tutaj użycie metod zależnych i nie będziemy omawiać zależności od grup.
Test zależny dotyczący innej metody jest ustawiany za pośrednictwem pliku XML TestNG w następujący sposób:
# 8) Zależne testy
Testy zależne to zaawansowane funkcje dostępne tylko w TestNG. Zależności mogą dotyczyć testu lub grupy.
@Test mytest1(){ System.out.println(“My test : mytest1”); } @Test (dependensOnMethods={“mytest1”}) public void mytest2(){ System.out.println(“My test : mytest2”); }
W powyższym programie, ponieważ mytest2 zależy od mytest1, najpierw uruchamia się mytest1, a następnie mytest2. Jeśli mytest1 zawiedzie, to mytest2 nie zostanie wywołany. W ten sposób można wstępnie zdefiniować zależne przypadki testowe, aby kontrolować określony przepływ pracy, który chcesz wykonać.
# 9) Słuchacze
Słuchacze nasłuchują każdego zdarzenia, które ma miejsce podczas testów. Odbiorniki są obsługiwane zarówno w JUnit, jak i TestNG. Tak więc, jeśli chcesz wykonać określone zadania lub wyświetlić konkretny komunikat w dzienniku przed rozpoczęciem testu, po jego zakończeniu, gdy test zostanie pominięty, gdy test zostanie zaliczony lub nieudany, mamy te funkcje Listenera, które umożliwiają nam Zrób to
JUnit używa klasy Listener, a TestNG używa interfejsu Listener. TestNG napisze klasę detektora definiującą metody interfejsu Listener, a drugim krokiem jest wywołanie tej nazwy klasy Listener przy użyciu adnotacji @Listeners w klasie głównej.
JUnit dziedziczy również metody z klasy nadrzędnej Listener, po której zdefiniowano klasę wykonawczą Listener w celu zastosowania funkcji detektora do jednej lub większej liczby klas głównych.
Listener w TestNG
Istnieje interfejs ITestListener, z którego zaimplementowano TestNG.
Poniżej znajdują się metody, które należy zdefiniować po zaimplementowaniu ITestListener -
- OnTestStart ()
- OnTestFailure ()
- OnTestSuccess ()
- OnTestSkipped ()
- OnStart ()
- OnFinish ()
Poniżej znajduje się fragment kodu demonstrujący onTestStart () i onTestSuccess ()
import org.testng.ITestListener; import org.testng.ITestResult; public class TestListener implements ITestListener { @Override public void onTestStart(ITestResult result) { System.out.println('Execution started: '+result.getName()); } @Override public void onTestSuccess(ITestResult result) { System.out.println('Test Passed '+result.getName()); }
Wywołaj tę klasę listenera w swojej głównej klasie, jak pokazano poniżej, używając adnotacji @Listener:
import org.testng.annotations.Listeners; import org.testng.annotations.Test; @Listeners(com.javatpoint.Listener.class) public class MymainClass { @Test public void sum() {
Słuchacz w JUnit 5
RunListener to klasa, która musi zostać rozszerzona przez klasę detektora w celu zdefiniowania funkcji Listener.
Mamy następujące metody dla JUnit:
- testRunStarted
- testRunFinished
- testFailure
- tesIgnored
import org.junit.runner.notification.Failure; import org.junit.runner.notification.RunListener; public class Mylistenerclass extends RunListener { public void testRunStarted(Description desc) throws java.lang.Exception { System.out.println('Execution started' + desc.getMethodName()); } public void testRunFinished(Description desc) throws java.lang.Exception { System.out.println('Execution finished' + desc.getMethodName()); }
Musi być utworzona klasa wykonawcza detektora, aby wywołać powyższą klasę detektora.
Możesz zastosować klasę Mylistener detektora do wielu klas z metodami testowymi.
public class ListenerRunner { public static void main(String() args) { JUnitCore runme = new JUnitCore(); runme.addListener(new ListenerRunner()); runner.run(FirstClass.class, SecondClass.class); }
Wniosek
W tym samouczku JUnit Vs TestNG porównaliśmy platformy TestNG i JUnit. Dowiedzieliśmy się o wspólnych funkcjach obsługiwanych w obu frameworkach, a także dodatkowych funkcjach obsługiwanych tylko w TestNG. Najwyraźniej jest kilka dodatkowych funkcji tylko w TestNG, takich jak równoległe wykonywanie i testy zależności. Większość funkcji obsługiwanych przez TestNG jest również dostępna w JUnit.
Istnieją niewielkie odchylenia w zakresie składni, terminologii w JUnit vs TestNG dla wspólnych cech. Ci, którzy podważyli siłę JUnit nad TestNG, do tej pory zdawali sobie sprawę, że JUnit jest również jednym z potężnych frameworków automatyzacji.
Wrócimy z wieloma ciekawszymi aspektami JUnit. Trzymaj się nadchodzących samouczków !!!
rekomendowane lektury
- Samouczek JUnit dla początkujących - co to jest testowanie JUnit
- Lista adnotacji JUnit: JUnit 4 Vs JUnit 5
- Jak korzystać z adnotacji JUnit 5 @RepeatedTest z przykładami
- JUnit Ignore Test Case: JUnit 4 @Ignore Vs JUnit 5 @Disabled
- Instalacja TestNG, program podstawowy i raporty
- Adnotacje i słuchacze TestNG
- Samouczek TestNG: Wprowadzenie do Framework TestNG
- Assertions in Selenium using Junit and TestNG Frameworks