通过Facebook使用phpunit和php-webdrivers测试多个浏览器的代码


Testing your code for multiple browsers using phpunit & php-webdrivers by facebook

我正在使用 facebook for Selenium 的 php-webdrivers 为我的网站实施集成测试。我正在使用phphunit来运行我的测试,并将我的代码包装在phpunitframework_testcase扩展类中:

class WebTest extends PHPUnit_Framework_TestCase
{
    /**
     * @var 'RemoteWebDriver
     */
    protected $driver;
    protected $url='http://example.com';
    protected $screenShotDirectoryPath  =   '/screenshots/';

    /**
     * @BeforeMethod
     */
    protected function setUp()
    {
        try{
            $capabilities = array( WebDriverCapabilityType::BROWSER_NAME=>WebDriverBrowserType::FIREFOX );
            $this->driver = RemoteWebDriver::create('http://localhost:4444/wd/hub', $capabilities, 5000);
        } catch (Exception $e){
            echo $e->getMessage();
        }
    }
    /**
     * @AfterMethod
     */
    public function tearDown()
    {
        $this->driver->close();
    }
    public function testImageUpload()
    {
        $errorSnaps='';
        $myBrowserDriver    =   $this->driver;
        //open the url
        $myBrowserDriver->get($this->url);
        try{
            //get email field in login page
            $emailField =   $myBrowserDriver->findElement(WebDriverBy::id('email'));
            //check if the field is displayed
            if(!$emailField->isDisplayed()) {
                try {
                    $errorSnaps = $this->takeScreenshot();
                    $this->errorLogs[] = "The email input Element is not present, a screen-shot of the error has been placed here --> " . $errorSnaps;
                } catch (Exception $e){
                    $this->errorLogs[]  =   $e->getMessage();
                }
            }
        } catch (NoSuchElementException $nse){
            try {
                $errorSnaps = $this->TakeScreenshot();
                $this->errorLogs[] = "The email field on ".$this->driver->getCurrentURL()." not found , a screen-shot for the error has been placed here -->" . $errorSnaps;
            }catch (Exception $e){
                $this->errorLogs[]=$e->getMessage();
            }
         }
     }

php-webdrivers 文档推荐这种方式来初始化浏览器驱动程序

$capabilities=array(
    'WebDriverCapabilityType::BROWSER_NAME=>WebDriverBrowserType::FIREFOX
);
$this->driver = RemoteWebDriver::create('http://localhost:4444/wd/hub', $capabilities, 5000);

但没有提供一种机制来初始化多个浏览器驱动程序以仅使用单个测试文件运行我的测试意味着考虑到上面的代码,我必须为所有这些浏览器制作不同的副本,并且只有一行代码差异意味着如果我想为 chrome 运行上面的测试,那么我必须将行从

$capabilities=array('WebDriverCapabilityType::BROWSER_NAME=>WebDriverBrowserType::FIREFOX);

$capabilities=array('WebDriverCapabilityType::BROWSER_NAME=>WebDriverBrowserType::CHROME);

并将该代码与上述所有相同的代码保存在不同的文件中,然后运行我的测试套装。如您所见,这不是实现我的测试和代码可重用性的最佳方法。


我遇到了 2 个选项:

  1. 从终端传递参数,发送带有参数(如 phpunit brName=chrome)的浏览器名称并通过 $_SERVER['brName'] 获取它。每次我想为任何其他浏览器运行测试时,我仍然必须输入。
  2. 我在phpunit网站上遇到了下面的TestDecorator类,它看起来像是实现我正在做的事情的更传统的方式,但无法弄清楚如何使用它来运行我的测试。

我应该将代码放在哪里,以便它检测并运行它?每次我尝试运行下面的示例代码时,它都说没有执行任何测试。如果我在下面有示例测试函数,如何使用测试装饰器作为基类运行它 4 次?

样品测试:

public function sampleTest(){
    $this->assertTrue(TRUE);
}

测试装饰器类:

require_once 'PHPUnit/Extensions/TestDecorator.php';
class PHPUnit_Extensions_RepeatedTest extends PHPUnit_Extensions_TestDecorator
{
    private $timesRepeat = 1;
    public function __construct(PHPUnit_Framework_Test $test, $timesRepeat = 1)
    {
        parent::__construct($test);
        if (is_integer($timesRepeat) &&
            $timesRepeat >= 0) {
            $this->timesRepeat = $timesRepeat;
        }
    }
    public function count()
    {
        return $this->timesRepeat * $this->test->count();
    }
    public function run(PHPUnit_Framework_TestResult $result = NULL)
    {
        if ($result === NULL) {
            $result = $this->createResult();
        }
        for ($i = 0; $i < $this->timesRepeat && !$result->shouldStop(); $i++) {
            $this->test->run($result);
        }
        return $result;
    }
}

我没有朝着正确的方向来实现这个场景,我不应该使用 testdecorator 类,但一个更好和更简单的方法将是。

  1. 通过cmd线/终端设置环境变量,例如 export BROWSER_REQUESTED=chrome for (unix) 和 set BROWSER_REQUESTED=chrome for (windows),或者您可以使用以下代码创建一个 .sh 文件 export BROWSER_REQUESTED=chrome && phpunit并通过cmd线运行它。

  2. 创建一个 BrowserFatory 类,该类侦听环境变量并启动所请求的浏览器类型的驱动程序。

创建尽可能多的.sh文件,您需要运行测试的浏览器,我添加了下面的代码以更具描述性。

网络测试.php

class WebTest extends PHPUnit_Framework_TestCase
{
    /**
     * @var 'RemoteWebDriver
     */
    protected $driver;
    protected $url='http://example.com';
    protected $screenShotDirectoryPath  =   '/screenshots/';

    /**
     * @BeforeMethod
     */
    protected function setUp()
    {
        try{
            $this->driver = BrowserFactory::drivers();
        } catch (Exception $e){
            echo $e->getMessage();
        }
    }
}

浏览器工厂.php

class BrowserFactory
{
    public static function drivers()
    {
        switch ($_SERVER['BROWSER_REQUESTED']) {
            case 'chrome':
                return self::createChrome();
                break;
            case "ie":
                throw new Exception('Not implemented');
                break;
            case 'firefox':
            default:
                return self::createFirefox();
                break;
        }
    }
    public static function createChrome()
    {
        putenv("webdriver.chrome.driver=/path/to/chromedriver");
        $service = ChromeDriverService::createDefaultService();
        $service->start();
        return ChromeDriver::start(DesiredCapabilities::chrome(), $service);
    }
    public static function createFirefox()
    {
        // these are just constants defined in bootstrap.php
        $seleniumUrl = isset($_SERVER['JENKINS_URL']) ? TEST_ENV_SELENIUM_SERVER : LOCAL_ENV_SELENIUM_SERVER;
        return RemoteWebDriver::create(
            $seleniumUrl, DesiredCapabilities::firefox()
        );
    }
}

command-line.sh

export BROWSER_REQUESTED='chrome' && phpunit