顯示具有 PHP 標籤的文章。 顯示所有文章
顯示具有 PHP 標籤的文章。 顯示所有文章

2018年10月17日 星期三

PHP的時間轉換

👉利用 selenium 玩遊戲時,需要設定玩遊戲分鐘數,需要用來換算及執行動作

✅利用 time() 來取得現在時間(秒),在加上要玩的秒數,利用 while 迴圈來控制

// 計算結束時間
$finishTime = time() + (int)$seconds;

while (time() < $finishTime) { 
    $action->moveByOffset(round($startBtnX),
        round($startBtnY)); 
    $action->moveToElement($canvas,
        round($startBtnX), round($startBtnY))
        ->click()->perform(); 
    $tester->wait(Parameters::$waitingTime['short']);
}

因為沒有要求很準確的結束,這樣已經可以滿足需求。


2018年10月2日 星期二

Java Develop Coder 開始 PHP Test Coder 的生活_2018/10/2 Day23

完成了一次的遊戲操作,但是需求是一整天一直玩,接下來處理這部分。

👉PHP 語法
為了重複做一件事情(玩遊戲),使用 while 迴圈實作。

...
while ($counts > 0) {
// 用 selenium 的 action 操控 canvas
$I->executeInSelenium(function (\Facebook\WebDriver\Remote\RemoteWebDriver $webDriver) {
$element = $webDriver->findElement(\Facebook\WebDriver\WebDriverBy::xpath('//div[@id=\'game\']/canvas'));
$action = $webDriver->action();
$action->moveByOffset(Parameters::$decreaseBets['x_offset'],    Parameters::$decreaseBets['y_offset']);
$action->moveToElement($element, Parameters::$gameStart['x_offset'], Parameters::$gameStart['y_offset'])->doubleClick()->perform();
});
// 等候遊戲玩完
$I->wait(Parameters::$waitSeconds);
$counts--;
}
...

等到 counts 減完以後,就會跳出迴圈。

👉Selenium 語法
上面的程式在執行時,第2次(設定跑3次)要點擊時,都會產生沒有反應的狀況,所以在點擊前用moveByOffset先把滑鼠移到其他地方,再回到遊戲開始的按鈕,如此就能正常運作。

👉Codeception 語法
前篇把跟測試無關的輔助方法放在 XxxCest 的類別裡,會讓 Codeception 把它也當成是要執行的測試程式,而造成錯誤,所以就把輔助的動作移到 StepObject 裡,需要使用再呼叫就不會發生誤判的狀況。

用命令列建立 StepObject
php vendor/bin/codecept generate:stepobject acceptance Xxx

然後就會有互動步驟建立 function
php vendor/bin/codecept generate:stepobject acceptance Xxx
Add action to StepObject class (ENTER to exit): stepsOfXxx
Add action to StepObject class (ENTER to exit):
StepObject was created in /tests/acceptance/_support/Step/Acceptance/Xxx.php

接下來到剛剛生成的類別裡寫完方法後,就可以在測試程式裡叫用。
public function playGame(\Step\Acceptance\Xxx $I)
{
$I->waitForElement('canvas', 15);
$I->wait(Parameters::$waitSeconds);
$I->decreaseBets(Parameters::$pressDecreaseButtonTimes);
$I->playGameByGivenTimes(Parameters::$executeTimes);
}

👉Docker
想要同時執行多個相同的測試案例,Codeception 文件提到了 Parallel Execution ,裡面用 Docker 和 Robo 來實現。
先安裝好 Docker Docker-Compose,再依照 Codeception 文件說的把 image 拉回來。
今天還沒辦法從 Docker 執行測試案例。

2018年10月1日 星期一

Java Develop Coder 開始 PHP Test Coder 的生活_2018/10/1 Day22

在進入控制遊戲之前,先記錄一下 monolog。

👉 PHP 的 Logger 框架 Monolog

在專案內建立 Logger 類別,用來取得 logger 並設定。建好類別之後引用執行報錯,[Error] Class 'Jutai\Robot\Utils\RobotLogger' not found,這...不是用 use 就算 import 進來了嗎? monolog 的套件也是用 use 就可以使用,原因是出在有 composer 的幫忙,處理 autoload,這樣就可以不需要在頁面裡用 use 還要加上 require。
基本的用法是在引入類別後,設定 Log 存放位置與級別,就可以開始使用。

use Monolog\Logger;
use Monolog\Handler\StreamHandler;

// create a log channel
$log = new Logger('name');
$log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));

// add records to the log
$log->warning('Foo');
$log->error('Bar');

詳細的使用方法後續再研究。

👉 PHP 語法

🍎解決 use 沒有辦法發現類別問題
namespace 現在當成 Java 的 package 用
use 感覺像 Java 的 import,但是使用自己的類別要再加上 require 或 include (?)
require(reuqire_once) import 的另一半,reuqire_once 會檢查如果有引用過不會再引用,錯誤報 error,不繼續執行
include import 的另一半,錯誤報 warming,程式繼續執行
參考資料
[PHP]include 與 require 的差別
 php中require,include,use的区别
PHP class not found when using namespace

🍎autoload
autoload 在處理引用類別的問題,有 PHP原生的 __autoload()、加強版的 spl_autoload 與 spl_autoload_register 以及使用 composer 依據 PSR-0(2014/10/21宣告棄用)PSR-4 標準來驅動的 autoload。專案裡因為已經使用 composer,所以就採取最後一個解決方案。在 composer.json 加上 autoload 的宣告。

{
    ....
    "autoload": {
        "psr-4": {
            "Jutai\\Robot\\Utils\\": "utils/"
        }
    }
    ....
}

前面是命名空間,後面是對應的資料夾位置,兩個反斜線應該是來逃逸用的。再執行 composer install,就可以直接使用 use 來引用類別。
參考資料
COMPOSER進階原理:PHP命名空間與PSR-0
PHP系列 - Autoload 自動載入
PHP Composer … The Autoloader

👉Selenium 操作 HTML5 canvas

進入遊戲後,要開始操作 canvas,但是由於 codeception 並沒有可以操作 html5 標籤的相關指令,所以只有借用 Selenium 來操作,精確的講,是利用 Facebook 實作 Selenium 的 WebDriver 的套件來操作,而且也不需要另外安裝,它被包含在 codeception 裡。

...
$I->executeInSelenium(function (\Facebook\WebDriver\Remote\RemoteWebDriver $webDriver) {
$element = $webDriver->findElement(\Facebook\WebDriver\WebDriverBy::xpath('//div[@id=\'game\']/canvas'));
$action = $webDriver->action();
$action->moveToElement($element, 1300, 390)->click()->perform();
});
...

程式碼還需要重構,因為需求會是玩一整天的遊戲。而按鈕的位置因為需要利用人工調整,所以也需要用變數替代。
參考資料
Automated Testing of HTML5 Canvas Applications with Selenium WebDriver
请教 Selenium 测试 HTML 5 canvas 问题
【基础7】selenium操作canvas

👉 PHPStorm 快捷鍵

Ctrl+Alt+L → Reformat Code

👉Ubuntu 指令

看 PATH
echo $PATH


2018年9月30日 星期日

Java Develop Coder 開始 PHP Test Coder 的生活_2018/9/28 Day 19

目前需求開發一支可以控制 HTML5 Canvans 遊戲的機器人,現在的構想是用 Selenium 來控制網頁元件,以驗收測試為基礎來寫。

👉解析API傳回的JSON字串

首先,需要先進入遊戲,為了節省登入的步驟,所以以呼叫API的方式來進入遊戲。呼叫後傳回格式如下:

{
  "data": {
    "url": "https://h5c.cqgame.games/1/?token=da05d84ab17d2ed4f184d2f7axxxxxxxx&language=zh-CN"
  },
  "status": {
    "code": 0,
    "message": "success",
    "timestamp": 1038106999
  }
}

裡面的 url 就是進入遊戲的入口,將它擷取放入測試之前的步驟。接下來就要用 PHP 裡跟 JSON 有關的函式。首先利用 file_get_contents() 將 JSON 字串取回來,再利用 json_decode() 解碼。

// 處理 ssl 造成的錯誤
$stream_opts = [
            "ssl" => [
                "verify_peer"=>false,
                "verify_peer_name"=>false,
            ]
];

// 取回 API 返回內容
$data = file_get_contents($this::$api_url, false, stream_context_create($stream_opts));

// JSON解碼,取得 url
$game_url = json_decode($data, true)['data']['url'];

接著就可以前往遊戲畫面。

👉Ubuntu Command

reboot 重開機