Executando os mesmos testes em um grande número de sites

Eu preciso executar os mesmos testes em mais de 70 sites, todos funcionalmente iguais, mas com skins diferentes. No entanto, todos são acessados através de URLs diferentes.

Usando TestNG e Java, qual seria uma maneira eficiente de passar as URLs para os testes para que eu possa: a) executar cada teste em cada site e reportar o mesmo b) executar testes em paralelo para economizar tempo (necessidade futura)

Quero armazenar os URLs em um formato que seja exposto aos usuários finais e configurável por eles. Idealmente, isso seria em um arquivo .csv ou, alternativamente, como no arquivo testng.xml. Estou pensando em @DataProvider ou @Factory, mas não tenho certeza de como usá-los de maneira eficiente e sustentável para obter parâmetros de uma fonte externa ou onde, no meu modelo atual, esses métodos estariam melhor posicionados? A dificuldade que tenho é que não quero passar os dados necessariamente para os @ Testes, mas sim passar um valor de cada vez (um URL) e executar contra todos os métodos anotados do @Test.

Minha configuração simples atual é a seguinte:

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>

Meu teste de aceitação:

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...

My Selenium Methods 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...

Página Minha Base de Driver:

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

Classe de provedor de URL:

public class URLProvider {

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

Por fim, um Config que atualmente contém apenas um BaseUrl:

public interface Config {

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

}

questionAnswers(1)

yourAnswerToTheQuestion