【问题标题】:keeping selenium browser open with phpunit/selenium使用 phpunit/selenium 保持 selenium 浏览器打开
【发布时间】:2011-08-21 20:44:59
【问题描述】:

当测试失败时,运行 selenium 测试的浏览器将关闭。这在尝试调试时没有帮助。我知道我可以选择在失败时进行屏幕截图,但如果没有整个上下文,这无济于事。在浏览器仍然可用的情况下,我可以回击并检查发生了什么。

有没有办法在断言失败或未找到元素时保持浏览器打开?

【问题讨论】:

    标签: selenium phpunit


    【解决方案1】:

    数周后随机发现。

    启动服务器时,最后使用选项 -browserSessionReuse。这将在整个测试过程中保持一个浏览器会话打开,并且不会在失败时关闭

    【讨论】:

    • Parameter exception. We passed main parameter '-browserSessionReuse' but no main parameter was defined in your arg class。当我像这样启动服务器时会发生这种情况 - java -jar selenium .. bla bla .jar -browserSessionReuse。任何想法为什么会这样?提前谢谢你:)(我知道它已经快 7 年了,但.. 必须尝试 :D)
    • 和 Toma 一样的问题
    【解决方案2】:

    您可能会在测试结束时调用 selenium.stop()。您需要注释掉那行代码,并确保您的 selenium 对象在测试结束时没有被破坏。这将使窗口保持打开状态。同样的问题已经回答here

    【讨论】:

      【解决方案3】:

      关于https://stackoverflow.com/a/6904808/654026 上关于 -browserSessionReuse 的答案,请记住,您必须在测试执行之间清理 cookie。否则你可能很难调试错误。

      【讨论】:

        【解决方案4】:

        一个简单的解决方案是在测试 setUp() 方法中将会话 $stopped 属性设置为 true。由于该属性是私有的,我们需要使用 Reflection api。

            function setUp() {
        
                ....
        
                // Set the private property $stopped of session to true, so the window is not closed on error or at the end of tests
                $myClassReflection = new \ReflectionClass( get_class( $this->prepareSession() ) );
                $secret            = $myClassReflection->getProperty( 'stopped' );
                $secret->setAccessible( true );
                $secret->setValue( $this->prepareSession(), true );
        
                ...
        }
        

        【讨论】:

          【解决方案5】:

          经过长时间尝试创建一个相对干净的解决方法后,我现在求助于一个非常肮脏但非常简单的破解方法。 phpunit\selenium 源代码不容易被覆盖,如果有工厂用来创建 Session 对象会很好。我试图通过覆盖和代理对象来侵入对象创建,但仍然无法让它工作。最后,我不想在这上面花更多时间,而是走上了最简单和最肮脏的道路,即直接破解了 PHPUnit_Extensions_Selenium2TestCase_Session 和 PHPUnit_Extensions_Selenium2TestCase 类的代码。 在 PHPUnit_Extensions_Selenium2TestCase 中插入了一个静态 $_instance 可用于检查是否存在测试失败条件。在 PHPUnit_Extensions_Selenium2TestCase_Session 中拦截了 stop() 方法并查询了 TestCase 的状态。像魅力一样工作,但脏脏脏脏。

          PHPUnit_Extensions_Selenium2TestCase:

          private static $_instance;
          public static function getInstance() { return self::$_instance; }
          ....
          public function __construct($name = NULL, array $data = array(), $dataName = '')
          {
              self::$_instance = $this;
              ....
          }
          

          PHPUnit_Extensions_Selenium2TestCase_Session:

          public function stop()
          {
              if ($this->stopped || $this->hasFailedTests()) {
                  return;
              }
              ....
          }
          
          private function hasFailedTests()
          {
              $status = PHPUnit_Extensions_Selenium2TestCase::getInstance()->getStatus();
              return $status == \PHPUnit_Runner_BaseTestRunner::STATUS_ERROR
              || $status == \PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE;
          }
          

          【讨论】:

            【解决方案6】:

            这里有一个更清洁的解决方案。覆盖与会话创建有关的所有类。会话类是会话关闭的地方,因此需要重写 stop() 方法。

            TODO:添加参数以控制行为,是否以及何时保持浏览器窗口打开。

            重写 5 个类:PHPUnit_Extensions_Selenium2TestCase、PHPUnit_Extensions_Selenium2TestCase_Driver、PHPUnit_Extensions_Selenium2TestCase_Session、PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Isolated、PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Shared。 创建了 2 个引导文件,1 个用于共享浏览器会话,1 个用于隔离浏览器会话。 显示 1 个示例测试。

            OkxSelenium2TestCase:

            namespace OKInfoTech\PhpUnit\Selenium;
            
            abstract class OkxSelenium2TestCase extends \PHPUnit_Extensions_Selenium2TestCase
            {
                private static $_instance;
                public static function getInstance() { return self::$_instance; }
            
                public function __construct($name = NULL, array $data = array(), $dataName = '')
                {
                    self::$_instance = $this;
                    parent::__construct($name, $data, $dataName);
            
                    $params = array(
                        'host' => 'localhost',
                        'port' => 4444,
                        'browser' => NULL,
                        'browserName' => NULL,
                        'desiredCapabilities' => array(),
                        'seleniumServerRequestsTimeout' => 60
                    );
                    $this->setUpSessionStrategy($params);
                }
            
                protected function setUpSessionStrategy($params)
                {
                    parent::setUpSessionStrategy($params);
                    if (isset($params['sessionStrategy'])) {
                        $strat = $params['sessionStrategy'];
                        switch ($strat) {
                            case "isolated":
                                self::$browserSessionStrategy = new OkxSelenium2TestCase_SessionStrategy_Isolated;
                                break;
                            case "shared":
                                self::$browserSessionStrategy = new OkxSelenium2TestCase_SessionStrategy_Shared(new OkxSelenium2TestCase_SessionStrategy_Isolated);
                                break;
                        }
                    } else {
                        self::$browserSessionStrategy = new OkxSelenium2TestCase_SessionStrategy_Isolated;
                    }
                    $this->localSessionStrategy = self::$browserSessionStrategy;
                }
            }
            

            OkxSelenium2TestCase_Driver:

            namespace OKInfoTech\PhpUnit\Selenium;
            
            class OkxSelenium2TestCase_Driver extends \PHPUnit_Extensions_Selenium2TestCase_Driver
            {
                private $seleniumServerUrl;
                private $seleniumServerRequestsTimeout;
            
                public function __construct(\PHPUnit_Extensions_Selenium2TestCase_URL $seleniumServerUrl, $timeout = 60)
                {
                    $this->seleniumServerUrl = $seleniumServerUrl;
                    $this->seleniumServerRequestsTimeout = $timeout;
                    parent::__construct($seleniumServerUrl, $timeout);
                }
            
                public function startSession(array $desiredCapabilities, \PHPUnit_Extensions_Selenium2TestCase_URL $browserUrl)
                {
                    $sessionCreation = $this->seleniumServerUrl->descend("/wd/hub/session");
                    $response = $this->curl('POST', $sessionCreation, array(
                        'desiredCapabilities' => $desiredCapabilities
                    ));
                    $sessionPrefix = $response->getURL();
            
                    $timeouts = new \PHPUnit_Extensions_Selenium2TestCase_Session_Timeouts(
                        $this,
                        $sessionPrefix->descend('timeouts'),
                        $this->seleniumServerRequestsTimeout * 1000
                    );
                    return new OkxSelenium2TestCase_Session(
                        $this,
                        $sessionPrefix,
                        $browserUrl,
                        $timeouts
                    );
                }
            }
            

            OkxSelenium2TestCase_Session:

            namespace OKInfoTech\PhpUnit\Selenium;
            
            class OkxSelenium2TestCase_Session extends \PHPUnit_Extensions_Selenium2TestCase_Session
            {
                public function stop()
                {
                    if ($this->hasFailedTests()) {
                        return;
                    }
                    parent::stop();
                }
            
                private function hasFailedTests()
                {
                    $status = OkxSelenium2TestCase::getInstance()->getStatus();
                    return $status == \PHPUnit_Runner_BaseTestRunner::STATUS_ERROR
                    || $status == \PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE;
                }
            }
            

            OkxSelenium2TestCase_SessionStrategy_Isolated:

            namespace OKInfoTech\PhpUnit\Selenium;
            
            class OkxSelenium2TestCase_SessionStrategy_Isolated extends \PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Isolated
            {
                public function session(array $parameters)
                {
                    $seleniumServerUrl = \PHPUnit_Extensions_Selenium2TestCase_URL::fromHostAndPort($parameters['host'], $parameters['port']);
                    $driver = new OkxSelenium2TestCase_Driver($seleniumServerUrl, $parameters['seleniumServerRequestsTimeout']);
                    $capabilities = array_merge($parameters['desiredCapabilities'],
                        array(
                            'browserName' => $parameters['browserName']
                        ));
                    $session = $driver->startSession($capabilities, $parameters['browserUrl']);
                    return $session;
                }
            }
            

            OkxSelenium2TestCase_SessionStrategy_Shared:

            namespace OKInfoTech\PhpUnit\Selenium;
            
            class OkxSelenium2TestCase_SessionStrategy_Shared extends \PHPUnit_Extensions_Selenium2TestCase_SessionStrategy_Shared
            {
            
            }
            

            bootstrapIsolated.php:

            require_once dirname(dirname(dirname(__DIR__))) . '/vendor/autoload.php';
            
            spl_autoload_register(
                function ($class) {
                    static $classes = NULL;
                    static $path = NULL;
            
                    if ($classes === NULL) {
                        $classes = [
                            'okinfotech\phpunit\selenium\okxselenium2testcase' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase.php',
                            'okinfotech\phpunit\selenium\okxselenium2testcase_driver' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_Driver.php',
                            'okinfotech\phpunit\selenium\okxselenium2testcase_session' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_Session.php',
                            'okinfotech\phpunit\selenium\okxselenium2testcase_sessionstrategy_isolated' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_SessionStrategy_Isolated.php',
                            'okinfotech\phpunit\selenium\okxselenium2testcase_sessionstrategy_shared' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_SessionStrategy_Shared.php',
                        ];
                        $path = dirname(dirname(dirname(dirname(__FILE__)))) . '/vendor/';
                    }
            
                    $cn = strtolower($class);
            
                    if (isset($classes[$cn])) {
                        require $path . $classes[$cn];
                    }
                }
            );
            
            use OKInfoTech\PhpUnit\Selenium\OkxSelenium2TestCase;
            OkxSelenium2TestCase::shareSession(false);
            

            bootstrapShared.php:

            require_once dirname(dirname(dirname(__DIR__))) . '/vendor/autoload.php';
            
            spl_autoload_register(
                function ($class) {
                    static $classes = NULL;
                    static $path = NULL;
            
                    if ($classes === NULL) {
                        $classes = [
                            'okinfotech\phpunit\selenium\okxselenium2testcase' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase.php',
                            'okinfotech\phpunit\selenium\okxselenium2testcase_driver' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_Driver.php',
                            'okinfotech\phpunit\selenium\okxselenium2testcase_session' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_Session.php',
                            'okinfotech\phpunit\selenium\okxselenium2testcase_sessionstrategy_isolated' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_SessionStrategy_Isolated.php',
                            'okinfotech\phpunit\selenium\okxselenium2testcase_sessionstrategy_shared' => 'okinfotech/phpunit-selenium/PHPUnit/Extensions/OkxSelenium2TestCase_SessionStrategy_Shared.php',
                        ];
                        $path = dirname(dirname(dirname(dirname(__FILE__)))) . '/vendor/';
                    }
            
                    $cn = strtolower($class);
            
                    if (isset($classes[$cn])) {
                        require $path . $classes[$cn];
                    }
                }
            );
            
            use OKInfoTech\PhpUnit\Selenium\OkxSelenium2TestCase;
            OkxSelenium2TestCase::shareSession(true);
            

            Selenium02Test:

            class Selenium02Test extends OkxSelenium2TestCase
            {
                public static function setUpBeforeClass()
                {
                }
            
                public static function tearDownAfterClass()
                {
                }
            
                public function setUp()
                {
                    $this->setHost('...');
                    $this->setPort(4444);
                    $this->setBrowser('chrome');
                    //$this->setBrowser('firefox');
                    $this->setBrowserUrl('...');
                }
            
                public function tearDown()
                {
                }
            
                public function testPageExists()
                {
                    $this->url('/');
                    // test if browser window stays open when test fails
                    $this->assertTrue(false);
                }
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2019-09-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2023-02-05
              相关资源
              最近更新 更多