setUp()、tearDown() 中的浏览器会话,没有每个测试用例设置?

发布于 2024-10-29 16:16:07 字数 474 浏览 1 评论 0原文

我之前使用 ruby​​/rspec 编写了一些 selenium 测试,发现它非常强大。现在,我将 Selenium 与 PHPUnit 一起使用,并且我缺少一些东西,这可能只是因为缺乏经验。在 Ruby/RSpec 中,我习惯于能够为每个测试用例定义一个“全局”设置,其中我打开浏览器窗口并登录到我的站点。

我觉得 PHPUnit 在这里有点缺乏,因为 1) 你只有 setUp()tearDown(),它们在每个单独的测试之前和之后运行,并且2) 看起来实际的浏览器会话是在 setUp() 和测试之间建立的,并在 tearDown() 之前关闭的。

这使得测试本身变得更加混乱,因为您明确必须在开始时打开页面,并在最后执行清理。在每一次测试中。对于每个测试关闭并重新打开浏览器,而不是仅仅返回登陆页面,这似乎也是不必要的开销。

有没有其他方法可以实现我正在寻找的目标?

I've previously written some selenium tests using ruby/rspec, and found it quite powerful. Now, I'm using Selenium with PHPUnit, and there are a couple of things I'm missing, it might just be because of inexperience. In Ruby/RSpec, I'm used to being able to define a "global" setup, for each test case, where I, among other things, open up the browser window and log into my site.

I feel that PHPUnit is a bit lacking here, in that 1) you only have setUp() and tearDown(), which are run before and after each individual test, and that 2) it seems that the actual browser session is set up between setUp() and the test, and closed before tearDown().

This makes for a bit more clutter in the tests themselves, because you explicitly have to open the page at the beginning, and perform cleanups at the end. In every single test. It also seems like unnecessary overhead to close and reopen the browser for every single test, in stead of just going back to the landing page.

Are there any alternative ways of achieving what I'm looking for?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

司马昭之心 2024-11-05 16:16:07

我过去所做的是创建一个受保护的方法,为会话返回一个对象,如下所示:

protected function initBrowserSession() {
    if (!$this->browserSession) {
        $this->setBrowser('*firefox');
        $this->setBrowserUrl('http://www.example.com/');
        //Initialize Session
        $this->open('http://www.example.com/login.php');
        // Do whatever other setup you need here
    }
    $this->browserSession = true;
}

public function testSomePage() {
    $this->initBrowserSession();
    //Perform your test here
}

您不能真正使用 setupBefore/AfterClass 函数,因为它们是静态的(因此您可以将无权访问该实例)。

现在,话虽如此,我会质疑你这样做的动机。通过在测试之间重复使用会话的测试,您可能会引入测试之间产生副作用的可能性。通过为每个测试重新打开一个新会话,您可以将影响隔离到测试的影响范围内。谁关心重新打开浏览器的性能(至少在合理的范围内)?这样做实际上提高了测试的有效性,因为它是孤立的。话又说回来,对于测试长时间的会话可能有一些话要说。但如果是这样的话,我会将其作为单独的测试用例/类来进行单独的功能测试......

What I have done in the past is to make a protected method that returns an object for the session like so:

protected function initBrowserSession() {
    if (!$this->browserSession) {
        $this->setBrowser('*firefox');
        $this->setBrowserUrl('http://www.example.com/');
        //Initialize Session
        $this->open('http://www.example.com/login.php');
        // Do whatever other setup you need here
    }
    $this->browserSession = true;
}

public function testSomePage() {
    $this->initBrowserSession();
    //Perform your test here
}

You can't really use the setupBefore/AfterClass functions since they are static (and as such you won't have access to the instance).

Now, with that said, I would question your motivation for doing so. By having a test that re-uses a session between tests you're introducing the possibility of having side-effects between the tests. By re-opening a new session for each test you're isolating the effects down to just that of the test. Who cares about the performance (to a reasonable extent at least) of re-opening the browser? Doing so actually increases the validity of the test since it's isolated. Then again, there could be something to be said for testing a prolonged session. But if that was the case, I would make that a separate test case/class to the individual functionality test...

我不吻晚风 2024-11-05 16:16:07

尽管我同意 @ircmaxell 的观点,即最好在测试之间重置会话,但我可以看到测试从需要几分钟到需要几个小时才能重新启动浏览器的情况。

因此,我做了一些挖掘,发现您可以重写基类中的 start() 方法。在我的设置中,我有以下内容:

<?php
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';

class SeleniumTestCase extends PHPUnit_Extensions_SeleniumTestCase
{
    public function setUp() {
        parent::setUp();
        // Set browser, URL, etc.
        $this->setBrowser('firefox');
        $this->setBrowserUrl('http://www.example.com');
    }

    public function start() {
        parent::start();
        // Perform any setup steps that depend on
        // the browser session being started, like logging in/out
    }
}

这将自动影响扩展 SeleniumTestCase 的任何类,因此您不必担心在每个测试中设置环境。

我没有测试过,但似乎在tearDown() 之前也调用了一个stop() 方法。

希望这有帮助。

Although I agree with @ircmaxell that it might be best to reset the session between tests, I can see the case where tests would go from taking minutes to taking hours just to restart the browser.

Therefore, I did some digging, and found out that you can override the start() method in a base class. In my setup, I have the following:

<?php
require_once 'PHPUnit/Extensions/SeleniumTestCase.php';

class SeleniumTestCase extends PHPUnit_Extensions_SeleniumTestCase
{
    public function setUp() {
        parent::setUp();
        // Set browser, URL, etc.
        $this->setBrowser('firefox');
        $this->setBrowserUrl('http://www.example.com');
    }

    public function start() {
        parent::start();
        // Perform any setup steps that depend on
        // the browser session being started, like logging in/out
    }
}

This will automatically affect any classes that extend SeleniumTestCase, so you don't have to worry about setting up the environment in every single test.

I haven't tested, but it seems likely that there is a stop() method called before tearDown() as well.

Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文