3

我正在使用 Selenium 和 TestNG 来测试一个网站。我使用 Selenium IDE 创建了测试并将它们导出到 TestNG,每个测试都是类中的一个方法。例如,

对于登录测试,有一个 Login 类,它具有方法 testLogin()、testLogin2() 等 对于注册测试,有一个 Signup 类具有方法 testSignup()、testSignup2() 等

我正在使用 Ant 运行测试,除了每个类都将打开一个浏览器然后运行它的方法之外,它运行良好,例如,如果我有五个类,那么五个浏览器将同时打开然后运行测试。

我想要的是让 Ant/Selenium/TestNG 只打开一个浏览器,然后在我在 testng.xml 中指定的所有类中运行所有测试(在同一个浏览器中)。使用上面的示例,我希望打开一个浏览器,然后运行 ​​testLogin()、testLogin2()、testSignup()、testSignup2()。如果这无法实现,那么我想打开一个浏览器,在一个类中运行所有测试,然后关闭浏览器,然后打开另一个浏览器,然后在下一个类中运行一组测试方法。

任何帮助表示赞赏。提前致谢。

4

3 回答 3

2

今天我找到了适合我的答案。给我几分钟来收集所有代码示例 :)

初始化.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");
    }

}

主意:

  • 启动浏览器一次有测试
  • 在所有其他测试之前运行(isBrowserRunning)
  • 从单个测试中引用浏览器

这段代码已经过测试,但目前我是从头顶上拿的,所以明天我可能会编辑它以使其更准确。

更新:此结果基于 testng.org 文档 + 我在 stackoverflow 上提出的一些问题 + 在几个论坛/组中找到的一些答案

我必须添加我正在以编程方式运行 testng,并且我正在动态生成 xml(就像在 documentation.org 上所做的那样)。我在一个包中使用它,我将包添加到 xml,只包括类 Init + 从 TemplateForClasses 继承的类。如果你需要那个 xml,请告诉我。

于 2009-09-01T18:55:11.713 回答
0

我也陷入同样的​​问题很长一段时间了。我将尽可能用最简单的术语来解释它。考虑以下示例:

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

现在每次我们运行这些测试方法时,它都会执行父类构造函数 selenium.start() 中的代码;那是多个浏览器都将在您的屏幕上打开的时候。

现在将一一执行测试方法 - 假设执行 B 类中的测试,它们将在一个窗口中发生,对于 C 类,则在另一个窗口中执行,依此类推。

所以基本上,您所要做的就是从父构造函数中删除 start() 代码并将其放在类 B、C 和 D 中的某个位置。

只要您继续使用一个 selenium 对象,一切都会在一个浏览器窗口中发生。当你把 start(); 该浏览器将打开(如果它没有打开)并创建一个新会话。停止(); 会话终止。

控制流程是这样的=>

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

因此,如果您能找到一种方法,在上面显示的整个执行序列中继续使用只有 1 个 start() 和 1 个 stop() 的同一个 selenium 对象,那么您的测试执行将只在一个浏览器窗口中发生。

如果您将 start() 代码放在 A 类中并在 B、C 和 D 中的每一个中放置代码,那么您将打开 3 个窗口,并且随着执行的进行,它们将一个一个地关闭。

如果您将 start() 和 stop() 代码分别放在 B、C 和 D 中,那么您将看到一个浏览器打开、执行测试用例、关闭。然后另一个将打开,执行 C 的测试用例,关闭等。

希望这可以帮助。:-)

于 2009-09-04T09:25:14.310 回答
0

我用 Spring 的依赖注入做到了这一点。初始化代码在工厂中。我需要一种方法让 Selenium 实例不仅在测试之间共享,而且在辅助类之间共享。selenium.someMethod() 很少在测试中直接调用。它更像是 helper.goToSomePage() 或 preferencesPage.changePassword(....)。

在测试之间共享一个 Selenium 实例可能被认为是一个坏主意,但它带来的一些错误并不难找到。测试按顺序运行,Selenium 对象不需要是线程安全的。对象的状态必须保持一致。

作为信息,Spring 是一个 Java 框架,依赖注入只是其中的一部分。当然可以使用其他 DI 框架,如 Guice。

于 2010-08-25T08:51:51.570 回答