2009-07-19 8 views
3

Ich verwende Selenium mit TestNG, um eine Website zu testen. Ich habe Tests mit der Selenium IDE erstellt und diese nach TestNG exportiert, wobei jeder Test eine Methode in einer Klasse war. ZBSo erhalten Sie Selenium und TestNG, um einen Browser zu öffnen, um Tests in mehreren Klassen auszuführen

Für Login-Tests gibt es eine Login-Klasse, die ein Anmelden Klasse gibt es Methoden TESTLOGIN(), testlogin2() etc Für Anmeldungen Tests hat Methoden testSignup() hat, testSignup2(), etc

I Ich benutze Ant, um die Tests zu starten, was gut funktioniert, außer dass jede Klasse einen Browser öffnet und dann ihre Methoden ausführt, zB wenn ich fünf Klassen habe, dann öffnen sich fünf Browser gleichzeitig und führen dann die Tests aus.

Was ich will, ist Ant/Selenium/TestNG zu bekommen, nur einen Browser zu öffnen und dann alle Tests (im selben Browser) in allen Klassen, die ich in testng.xml angegeben habe. Im obigen Beispiel möchte ich einen Browser öffnen und dann testLogin(), testLogin2(), testSignup(), testSignup2() ausführen. Wenn dies nicht erreicht werden kann, dann möchte ich einen Browser öffnen, alle Tests in einer Klasse ausführen, dann den Browser schließen, dann einen anderen Browser öffnen und dann die Testmethoden in der nächsten Klasse ausführen.

Jede Hilfe wird geschätzt. Danke im Voraus.

Antwort

2

Heute habe ich die Antwort gefunden, die für mich funktioniert. Gib mir ein paar Minuten, um alle Codebeispiele zu sammeln :)

Init.java

//base class that will be called before all tests 
@Test(groups = "init") 
public class Init{ 

    DefaultSelenium browser; 

    public void start(ITestContext itc){ 
     browser = (DefaultSelenium) itc.getAttribute("browser"); 
     browser.open("url"); 
     browser.click("xpath"); 
    } 

} 

TemplateForClasses.java

/* - all public methods will be tests 
* - all tests will be called after group init 
* - just before suite will start we will start 1 browser instance 
*/ 
@Test(dependsOnGroup="init") 
public class TemplateForClasses{ 

    DefaultSelenium browser; 

    @BeforeSuite 
    public void startBrowser(ITestContext itc){ 
     browser = new DefaultSelenium(host,port,browser_type,url); 
     itc.setAttribute("browser",browser); 
     browser.start(); 
    } 

    @AfterSuite 
    public void stopBrowser(ITestContext itc){ 
     browser = (DefaultSelenium) itc.getAttribute("browser"); 
     browser.stop(); 
    } 

    //any other: @Before, @After methods 

} 

FirstGroupOfTests.java

//all tests classes will inherit preferences set in TemplateForClasses 
public class FirstGroupOfTests extends TemplateForClasses{ 

    public void FirstTest(ITestContext itc){ 
     browser = (DefaultSelenium) itc.getAttribute("browser"); 
     //browser.click("start"); 
    } 

} 

Idee:

  • Start Browser nur einmal Tests
  • und die vor allen anderen Tests (isBrowserRunning)
  • Zum Browser aus einzelnem Test beziehen

Dieser Code getestet wurde, aber zur Zeit habe ich es von der Spitze meines Kopf, vielleicht werde ich es morgen bearbeiten, um es genauer zu machen.

Update: Dieses Ergebnis basiert auf testng.org Dokumentation + einige von mir gestellten Fragen auf Stackoverflow + einige auf mehreren Foren/Gruppen

Ich muss ich laufen testng programmatisch gefunden Antworten hinzufügen und ich bin das Erzeugen von XML im laufenden Betrieb (wie es auf documentation.org geschieht). Ich benutze es alle in einem Paket, ich fügte Paket dem xml hinzu, enthielt nur Klassen Init + die, die von TemplateForClasses erben. Wenn Sie diese XML benötigen, lassen Sie es mich wissen.

0

Ich war auch in dem gleichen Problem seit einiger Zeit fest. Ich werde es so einfach wie möglich erklären. Betrachten Sie das folgende Beispiel:

Class A (contains the code selenium.start();) 
| 
|(inherited classes) 
|--------class B } 
|--------class C } Have some @Test methods 
|--------class D } 

Jetzt jedes Mal laufen wir diese Testmethoden wird der Code in der übergeordneten Klasse Konstruktor selenium.start execute(); Das ist, wenn die verschiedenen Browser alle auf Ihrem Bildschirm öffnen werden.

Nun werden nacheinander die Testmethoden ausgeführt - vorausgesetzt, Tests in Klasse B werden ausgeführt, sie werden in einem Fenster, für Klasse C und so weiter ausgeführt.

Also im Grunde alles, was Sie tun müssen, ist der Start() Code aus dem Konstruktor übergeordneten entfernen und irgendwo in den Klassen B setzen, C und D.

Solange Sie mit einem Selen-Objekt weiter arbeiten alles wird in einem Browserfenster passieren. Wenn Sie starten(); Dieser Browser öffnet sich (wenn er nicht geöffnet wurde) und eine neue Sitzung wird erstellt. halt(); und die Sitzung wird beendet.

Der Ablauf der Steuerung so geht =>

Class A, Class B 
Class A, Class C 
Class A, Class D 

Wenn Sie also einen Weg finden, um mit nur 1 start() und 1 stop() für die gesamte Ausführung mit dem gleichen Selen Objekt zu halten Wie oben gezeigt, wird Ihre Testausführung nur in einem Browserfenster ausgeführt.

Wenn Sie start() - Code in Klasse A setzen und Code in jedem von B, C und D stoppen, dann haben Sie 3 Fenster geöffnet und eines nach dem anderen werden sie geschlossen, wenn die Ausführung fortschreitet.

Wenn Sie den Code start() und stop() einzeln in B, C und D eingeben, sehen Sie einen Browser, der Testfälle ausführt und schließt. Ein anderes wird dann öffnen, führen Sie Testfälle für C aus, schließen Sie usw.

Hoffnung hilft dieses. :-)

+0

Könnten Sie bitte tatsächlichen Code teilen? – paul

0

Ich habe dies mit Spring Abhängigkeit Injektion. Und der Init-Code ist in einer Fabrik. Ich brauchte einen Weg, um eine Selenium-Instanz nicht nur zwischen Tests, sondern auch zwischen Hilfsklassen zu teilen. Sehr selten wird selen.someMethod() direkt in den Tests aufgerufen. Es ist eher wie helper.goToSomePage() oder preferencesPage.changePassword (....).

Es könnte als eine schlechte Idee betrachtet werden, eine Selenium-Instanz zwischen den Tests zu teilen, aber die wenigen Fehler, die es mit sich brachte, waren nicht so schwer zu finden. Die Tests werden sequenziell ausgeführt und das Selenium-Objekt muss nicht Thread-sicher sein. Der Zustand des Objekts muss jedoch konsistent sein.

Für Informationen ist Spring ein Java-Framework und Dependency-Injektion ist nur ein Teil davon. Andere DI-Frameworks wie Guice können natürlich stattdessen verwendet werden.