2016-08-09 156 views
1

Ich habe die gleichen Tests für mehr als 70 Websites, die alle funktionsgleich sind, aber unterschiedliche Skins haben. Sie werden jedoch alle über verschiedene URLs aufgerufen.Das Ausführen derselben Tests für eine große Anzahl von Websites

Mit TestNG und Java, was eine effiziente Möglichkeit wäre, die URLs zu den Tests bestehen, so dass ich kann: a) jeden Test gegen jede Website laufen und darüber berichten gleichen b) ausführen Tests parallel um Zeit zu sparen (zukünftiger Bedarf)

Ich möchte die URLs in einem Format speichern, das den Endbenutzern offen steht und von ihnen konfiguriert werden kann. Dies wäre idealerweise in einer CSV-Datei oder alternativ in der Datei testng.xml enthalten. Ich denke entweder @DataProvider oder @Factory, bin mir aber nicht sicher, wie man diese auf eine effiziente und wartbare Art und Weise verwendet, um Parameter aus einer externen Quelle zu übernehmen, oder wo in meinem aktuellen Modell solche Methoden am besten platziert sind? Die Schwierigkeit, die ich habe, ist, dass ich die Daten nicht unbedingt in @ Test's übergeben möchte, sondern jeweils einen Wert (eine URL) weitergeben und gegen alle annotierten Methoden von @Test laufen muss.

Meine aktuelle einfache Einrichtung ist wie folgt:

testngxml: 
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > 

<suite name="Suite1" verbose="1"> 
<test name="FindARouteTest"> 
    <parameter name="number" value="1"/> 
    <parameter name="from" value="LONDON"/> 
    <parameter name="to" value="GLASGOW"/> 
    <parameter name="emailAddress" value="[email protected]"/> 
    <classes> 
     <class name="acceptancetests.EndToEndTest"> 
     </class> 
    </classes> 
</test> 

Mein Acceptance Test:

public class EndToEndTest extends DriverBase{ 

private HomePage home; 
private String url; 

@Factory(dataProvider = "urls", dataProviderClass = URLProvider.class) 
public EndToEndTest(String url) { 
    this.url = url; 
} 


@BeforeSuite 
public void stuff(){ 
    newDriver(); 
} 


@BeforeClass 
public void setup(){ 
    home = new HomePage(driver, url); 
} 

@Test (priority = 1) 
@Parameters({"from","to"}) 
public void searchForARoute(String from, String to) throws InterruptedException { 
    home.selectWhereFrom(from); 
    home.selectWhereTo(to); 
    //some assertions... 

My Pageobject:

public class HomePage extends SeleniumBase { 

public HomePage(WebDriver driver, String url) { 
    super(driver, url); 
    try { 
     visit(url); 
    } catch (MalformedURLException e) { 
     e.printStackTrace(); 
    } 
    driver.manage().window().maximize(); 
} 

public void someMethodOrOther(){ 
//some methods... 

Meiner Selen Methoden Basepage:

public class SeleniumBase implements Config { 

public WebDriver driver; 
public String url; 

public SeleniumBase(WebDriver driver) { 
    this.driver = driver; 
    this.url = url; 
} 

public void visit() throws MalformedURLException { 
    driver.get(url); 
} //more methods... 

My Driver Base-Seite:

public class DriverBase implements Config { 

public static WebDriver driver; 
public static String url; 

    protected void newDriver() { 
     if (host.equals("localhost")) { 
      if (browser.equals("firefox")) { 
       System.setProperty("webdriver.gecko.driver", 
         System.getProperty("user.dir") + "\\drivers\\geckodriver.exe"); 
       FirefoxProfile fp = new FirefoxProfile(); 
//more stuff 

URL-Provider-Klasse:

public class URLProvider { 

@DataProvider(name = "urls") 
public static Object[][] dataProviderMethod() 
{ 
    return new Object[][] {{"http://siteone.com"}, 
          {"http://sitetwo.com"}, 
          {"http://sitethree.com"} 
    }; 
} 
} 

schließlich ein Config, die derzeit nur ein BaseUrl hält:

public interface Config { 

String baseUrl = System.getProperty("baseUrl", 
String browser = System.getProperty("browser", "chrome"); 
String host = System.getProperty("host", "localhost"); 

} 

Antwort

2

können Sie Verwenden Sie die Annotation @Factory für t im Konstruktor est Klasse EndToEndTest und geben Sie einen Datenprovider.

private String url; 

@Factory(dataProvider = "urls", dataProviderClass = URLProvider.class) 
public EndToEndTest(String url) { 
    this.url = url; 
} 

Sie müssen die Implementierung der URL-Datenprovider Klasse, um die Excel-Datei oder was auch immer Sie wollen den Zugriff auf und ein Object [] [] zurückzukehren.

Sie müssen die Konstruktoren von HomePage und SeleniumBase so ändern, dass sie die URL übergeben, die Sie von Ihrer @BeforeClass-Methode aufrufen.

Dies sollte eine separate Instanz für diese Testklasse für jede URL-Zeichenfolge erstellen und die @ Test-Methoden aufrufen.

Wenn Sie mehr Daten als eine Zeichenfolge-URL übergeben müssen, können Sie stattdessen ein Objekt verwenden. Wie ich Ihre 4 Parameter in Ihrer testng.xml für eine Methode übergeben kann.

Parallelität sollte ziemlich einfach sein, raten Sie würden alle @ Test-Methoden für eine bestimmte URL in einem einzigen Thread ausführen möchten. Die parallele Option wäre "Klassen".

+0

Vielen Dank für die detaillierte Antwort - Ich werde versuchen, Ihre Vorschläge und lassen Sie wissen, wie ich auf – Steerpike

+0

das funktioniert gut, aber debuggen mit x3 URLs in der URLProvider.class, kann ich sehen, dass '@Factory' annotierte Konstruktor wird dreimal aufgerufen (einmal für jeden Parameter) vor '@BeforeClass' und das bedeutet 3 Threads? Ich glaube, und 3 Browser-Fenster mit den Tests parallel laufen. Zu Beginn möchte ich, dass jede URL übergeben wird, alle "Tests" laufen gegen eine URL und holen dann die nächste. Übergeben Sie also eine URL an EndtoEnd-Konstruktor, führen Sie Tests aus und holen Sie dann die nächste - nicht sicher, wie das möglich ist. – Steerpike

+0

Wie ich verstehe, möchten Sie, dass es seriell läuft, eine URL nach der anderen. Nicht parallel. Ist das korrekt? Entfernen Sie einfach die parallele Option aus Ihrer testng.xml oder Tests und es wird nacheinander ausgeführt. – Grasshopper