2014
Apr
12

当你在开发一个大型的专案时,往往会因为需求复杂,或是年代久远,没有人记得当初某些功能是怎么完成的,而造成新人不敢修改,老人一改就把旧功能改坏掉,一个好的自动化测试工具在这种状态就非常的重要,除了程式必需撰写的 Unit test 之外 ,通常我们还要加上 E2E 测试,例如使用 Selenium。

Selenium 是一个用来模拟真人的自动化测试工具,它可以操作网页浏览器,自动连结网页,输入资料,然后自动点击 Form Post 按钮等等各种强大的功能,另外他们支援多个浏览器,能够帮前端工程师抓到 CSS/JS Error。

Selenium 是 Server 端的工具,另外我们还必需使用一个 Client 端来传送指令给 Selenium ,这个工具我们统称为 WebDriver。

如何使用 Selenium 与 WebDriver

接下来我会一步一步教你如何安装 Selenium ,并且写一段简单的 PHP 来进行测试。

安装 Java

Selenium 是用 Java 写成的,所以你一定要在你的作业系统中安装 Java,请先至下面这个 Java 官网下载 Java 并安装。

启动 Seleniun

首先我们得先下载 Selenium 这套软体,你可以从这个网址下载 http://docs.seleniumhq.org/download/ ,下载回来是一个 Java Jar 档,启动的指令如: java -jar selenium-server-standalone-2.39.0.jar

另一个下载点 http://selenium-release.storage.googleapis.com/index.html

成功启动 Selenium 后,你可以使用 telnet localhost 4444 , 或是打开 Browser 连上这个网址 http://127.0.0.1:4444/wd/hub ,Selenium 预设会使用 4444 Port 来接收指令,如果你看到的画面如下,就代表 Selenium 已经启动成功!

Facebook WebDriver

WebDriver 就是一个用来控制 Selenium 动作的 Library ,称之为 Driver 因为他就像网卡一样,网卡是用来控制网路传输,而 WebDriver 是用来控制 Selenium,这里我使用的 WebDriver 是从 Facebook Git 上抓来下的,你可以在 https://github.com/facebook/php-webdriver 这里下载得到。

接著我们写一小段程式,呼叫 Selenium 打开 Firefox Browser 并且连上 Google 首页

Selenium HelloWorld
  1. <?php
  2. require_once "./php-webdriver/lib/__init__.php";
  3. $capabilities = array(
  4. WebDriverCapabilityType::BROWSER_NAME => 'firefox'
  5. );
  6. $seleniumUrl = 'http://localhost:4444/wd/hub';
  7. $driver = RemoteWebDriver::create($seleniumUrl, $capabilities, 5000);
  8. $driver->get("http://www.google.com.tw/");
  9. sleep(5);
  10. $driver->close();

程式有正确执行的话,你应该会看到你的电脑打开了 Firefox ,并连上Google 首面 ,我有故意在程式中加上 sleep 5 秒,这是怕 selenium 一执行完毕,就会自动关闭 Browser ,这样会来不及确认是否有连到 Google。

"capabilities" 这个参数是用来指定基本设定,例如上面的范例中我指定了 Browser = firefox 。

自动打动网页,并点击连结的范例

这是稍复杂一点的范例,功能是连上我开发好的页面,并且点击一个连结,然后等待 Browser 载入页面完成后,再继续执行接下来的指令。

Example
  1. $capabilities = array(WebDriverCapabilityType::BROWSER_NAME => 'firefox');
  2. $seleniumUrl = 'http://localhost:4444/wd/hub';
  3. $host = "http://www.puritys.me";
  4.  
  5. $driver = RemoteWebDriver::create($seleniumUrl, $capabilities, 5000);
  6.  
  7. $driver->get($host . "/docs-blog/article-49");
  8.  
  9. $url = $driver->getCurrentUrl();
  10. error_log( "url = " . $url);
  11. //change url and wait
  12. $elm = $driver->findElement(
  13. WebDriverBy::cssSelector('.nav-box a:nth-of-type(1)')
  14. );
  15.  
  16. $elm->click();
  17. // wait for at most 10 seconds until the URL is 'http://example.com/'.
  18. // check again 500ms after the previous attempt.
  19. $driver->wait(10, 500)->until(function ($driver) {
  20. if ($driver->getCurrentURL() === 'http://www.puritys.me/news') {
  21. error_log("Document is complete");
  22. return true;
  23. } else {
  24. return false;
  25. }
  26. });
  27.  
  28. error_log("test");
  29. $driver->close();

设定视窗的尺寸,长宽

Example
  1. $driver = RemoteWebDriver::create($seleniumUrl, $capabilities, 5000);
  2. $manage = $driver->manage();
  3.  
  4. $window = $manage->window();
  5. $dimension = $window->getSize();
  6.  
  7. $height = $dimension->getHeight(); //取得视窗的高
  8. $width = $dimension->getWidth(); //取得视窗的宽
  9.  
  10. $newSize = new WebDriverDimension(100,200); // 设定视窗的宽高 = 100x200
  11. $window->setSize($newSize);

如何将视窗最大化

平常我们在使用 Selenium 时,最好都将 Window 视窗调成最大化,避免 Selenium 因为 Element 不在画面上而选不到,最大化的方式很简单,使用 maximize 即可。

Example
  1. $manage = $driver->manage();
  2. $window = $manage->window();
  3. $window->maximize();

取得视窗位置与移动

Example
  1. $position = $window->getPosition();
  2. echo $position->getX();
  3. echo $position->getY();
  4.  
  5. //移动视窗
  6. $position->move(200, 0);
  7. $window->setPosition($position);

Selenium Protocol

WebDriver 不管开发者是谁,功能如何强力,他的 Server 一定还是 Selenium ,所以你只要了解 Selenium 所支援的功能,就能猜出 WebDriver 大概要怎么使用了,也可以知道 Selenium 所支援的 API 有哪一些。

其它相关

driver 能够使用的 method ,可以在 php-webdriver/lib/remote/RemoteWebDriver.php 中找到,例如 findElement 这个 Method 。

下面这个连结是 Selenium 如何操作 Browser 的 source code ,有一大部分的程式是用 JavaScript 写成的,可以看这边的程式,去了解 selenium 的实作方式。


相关文件




目前回應 Comments(2 comments)

  • pure 2017/11/08

    您好,
    因您文章受用良深,請教您一問題如附檔視訊,
    https://drive.google.com/file/d/1IpDs-O3F9jNniXJT3qfa9dmlRKbDmO2p/view?usp=sharing
    環境為FF54&SideeX is an extended version of Selenium IDE,
    CLICK指令可點到輸入欄位之ID,可是相同欄位相同ID,TYPE指令卻是未見任何動作,也就是未自動打字,WHY?
    麻煩您了
    [email protected]

    Reply

    Admin

    你的附檔我無法打開,可能是特殊符號被瀘掉了,你可以試試用短網址。

    TYPE 是很舊的語法了,你可以改用 sendKeys 看看

     

  • whhone 2014/05/23

    ```
    $capabilities = array(
    WebDriverCapabilityType::BROWSER_NAME => 'firefox'
    );
    ```

    可以改寫為

    ```
    $capabilities = DesiredCapabilities::firefox();
    ```

    簡潔一點。

    Reply

    Admin

    感謝提供這個方式。
    不過你的方式,會變成沒辦法用變數來指定 Browser。
    我的文章內容只是一個簡單的 Sample ,真正在使用時,firefox 會是存在一個變數裡,透過變數值來改變 Broswer。
    $capabilities = array(
    WebDriverCapabilityType::BROWSER_NAME => $brower
    );

回應 (Leave a comment)