Slide 1

Slide 1 text

Laravel Dusk 使用及研究

Slide 2

Slide 2 text

教授的一點軼事 照片僅供參考,與實際人事物並無關連 如有雷同純屬巧合

Slide 3

Slide 3 text

● 什麼是 Laravel Dusk ● 怎麼配置 ● Dusk 的優缺點 ● 怎麼測試

Slide 4

Slide 4 text

什麼是 Laravel Dusk Laravel Dusk provides an expressive, easy-to-use browser automation and testing API.

Slide 5

Slide 5 text

用 Excel 管理需測試項目

Slide 6

Slide 6 text

● 懶惰 ● 容易忘記事情 ● 有人弄錯時容易發脾氣 關於我

Slide 7

Slide 7 text

自動由電腦進行瀏覽器測試

Slide 8

Slide 8 text

不需要 Selenium 不需要 puppeteer 不需要 testcafe 其實是需要 selenium 的 因為這個套件依賴於 facebook/webdriver 然後 facebook/webdriver 包裝 selenium

Slide 9

Slide 9 text

測試寫進去,bug 找出來,工程師發大財

Slide 10

Slide 10 text

安裝 laravel dusk https://laravel.com/docs/5.7/dusk

Slide 11

Slide 11 text

多數環境下可立刻使用

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

laradock 環境下配置 https://laradock.io/guides/#option-1-without-selenium https://laradock.io/guides/#option2-dusk

Slide 14

Slide 14 text

php artisan dusk:install

Slide 15

Slide 15 text

範例程式碼 class ExampleTest extends DuskTestCase { public function testBasicExample() { $this->browse(function (Browser $browser) { $browser->visit('/') ->assertSee('Laravel'); }); } }

Slide 16

Slide 16 text

php artisan dusk(:fails) $ php artisan dusk PHPUnit 7.4.3 by Sebastian Bergmann and contributors. . 1 / 1 (100%) Time: 905 ms, Memory: 12.00MB OK (1 tests, 1 assertions) $ php artisan dusk:fails PHPUnit 7.4.3 by Sebastian Bergmann and contributors. . 1 / 1 (100%) Time: 948 ms, Memory: 12.12MB OK (1 tests, 1 assertions)

Slide 17

Slide 17 text

Dusk 的優點 和 laravel 的整合很好 多數環境下可立刻使用 測試設置簡易

Slide 18

Slide 18 text

Dusk 的缺點 不支援多瀏覽器 特定環境下設置困難 測試彈性較差

Slide 19

Slide 19 text

全部的 function(54) assertTitle assertTitleContains assertUrlIs assertSchemeIs assertSchemeIsNot assertHostIs assertHostIsNot assertPortIs assertPortIsNot assertPathBeginsWith assertPathIs assertPathIsNot assertRouteIs assertQueryStringHas assertSeeLink assertDontSeeLink assertInputValue assertInputValueIsNot assertChecked assertNotChecked assertRadioSelected assertRadioNotSelected assertSelected assertNotSelected assertSelectHasOptions assertSelectMissingOptions assertSelectHasOption assertValue assertQueryStringMissing assertFragmentIs assertFragmentBeginsWith assertFragmentIsNot assertHasCookie assertCookieMissing assertCookieValue assertPlainCookieValue assertSee assertDontSee assertSeeIn assertDontSeeIn assertSourceHas assertSourceMissing assertVisible assertPresent assertMissing assertDialogOpened assertEnabled assertDisabled assertFocused assertNotFocused assertVue assertVueIsNot assertVueContains assertVueDoesNotContain

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

http://bit.ly/DuskExample

Slide 22

Slide 22 text

tl;dr ● Laravel Dusk 可以用來進行前端整合測試 ● Laravel Dusk 可以很簡單的用 laradock 配置 ● 測試範例在 github 上有 ○ http://bit.ly/DuskExample

Slide 23

Slide 23 text

No content

Slide 24

Slide 24 text

時間還沒到呢 才幾張投影片,你以為撐得完整場?

Slide 25

Slide 25 text

官網上可以看到的事情 建議上官網看

Slide 26

Slide 26 text

演講時間寶貴

Slide 27

Slide 27 text

welcome to the dungeon It's about to get wild!

Slide 28

Slide 28 text

● 什麼是 Laravel Dusk ● 怎麼配置 ● Dusk 的缺點 ● 怎麼測試 ● Laravel Dusk 研究 ○ packagist ○ composer.json ○ 怎麼找出文件上沒說的事情 ○ Dusk 程式碼架構

Slide 29

Slide 29 text

套件的原始碼怎麼挖掘呢?

Slide 30

Slide 30 text

https://packagist.org/packages/laravel/dusk

Slide 31

Slide 31 text

https://github.com/laravel/dusk

Slide 32

Slide 32 text

composer.json ● 宣告套件資訊 ● 宣告套件相依套件 ● 宣告套件開發時相依套件

Slide 33

Slide 33 text

在 composer.json 找到程式進入點 "providers": [ "Laravel\\Dusk\\DuskServiceProvider" ]

Slide 34

Slide 34 text

DuskServiceProvider ● boot() ○ 宣告三個 Route::get() ● register() ○ 環境是 production 時給予警告 ○ 註冊指令 ■ dusk ■ dusk:fail ■ dusk:make ■ dusk:page ■ dusk:component

Slide 35

Slide 35 text

DuskServiceProvider ● boot() ○ 宣告三個 Route::get() ○ 文件上沒說的事情!

Slide 36

Slide 36 text

挖掘原始碼 可以發現很多想像不到的事情 (有些時候幫助很大)

Slide 37

Slide 37 text

Laravel\Dusk\Console\InstallCommand ● handle() ○ 建立資料夾 ○ 處理 stubs ○ 建檔 ○ 回傳完成 ● fire()

Slide 38

Slide 38 text

Laravel\Dusk\Console\(Make|Page|Component)Command ● handle() ○ use Illuminate\Console\GeneratorCommand; ○ 根據 stubs 產生檔案 ■ \Illuminate\Filesystem\Filesystem ■ protected function replaceNamespace(&$stub, $name) ● pass by reference

Slide 39

Slide 39 text

Laravel\Dusk\Console\DuskCommand ● handle() ○ 清除舊資料 ■ @unlink($file->getRealPath());

Slide 40

Slide 40 text

Laravel\Dusk\Console\DuskCommand ● handle() ○ $this->withDuskEnvironment( \Closure $callback) ■ function tap($value, $callback = null)

Slide 41

Slide 41 text

Laravel\Dusk\Console\DuskCommand ● handle() ○ $this->withDuskEnvironment( \Closure $callback) ■ $process = (new Process(array_merge( $this->binary(), $this->phpunitArguments($options) )))->setTimeout(null); ■ return $process->run(function ($type, $line) { $this->output->write($line); });

Slide 42

Slide 42 text

Symfony\Component\Process\Process /** * Process is a thin wrapper around proc_* functions to easily * start independent PHP processes. ● proc_open() ● proc_get_status() ● proc_close() ● proc_terminate()

Slide 43

Slide 43 text

$this->binary() return [PHP_BINARY, 'vendor/phpunit/phpunit/phpunit'];

Slide 44

Slide 44 text

Laravel\Dusk\Console\DuskFailsCommand extends DuskCommand protected function phpunitArguments($options) { return array_unique(array_merge(parent::phpunitArguments($options), [ '--cache-result', '--order-by=defects', '--stop-on-failure', ])); }

Slide 45

Slide 45 text

再看一眼 $ php artisan dusk PHPUnit 7.4.3 by Sebastian Bergmann and contributors. . 1 / 1 (100%) Time: 905 ms, Memory: 12.00MB OK (1 tests, 1 assertions) $ php artisan dusk:fails PHPUnit 7.4.3 by Sebastian Bergmann and contributors. . 1 / 1 (100%) Time: 948 ms, Memory: 12.12MB OK (1 tests, 1 assertions)

Slide 46

Slide 46 text

tl;dr ● Dusk:(install|make|page|component) ○ 建立資料夾 ○ 根據 stub 建檔 ● Dusk ○ 用 Process 物件,透過 php binary 執行 phpunit 進行測試 ○ dusk:fail 就是 dusk 加上三個參數

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

瀏覽器支援呢?

Slide 49

Slide 49 text

Tests\DuskTestCase /** * Prepare for Dusk test execution. * @beforeClass * @return void */ public static function prepare() { static::startChromeDriver(); }

Slide 50

Slide 50 text

Laravel\Dusk\Chrome\SupportsChrome::startChromeDriver static::$chromeProcess = static::buildChromeProcess($arguments); static::$chromeProcess->start(); static::afterClass(function () { static::stopChromeDriver(); });

Slide 51

Slide 51 text

Laravel\Dusk\Chrome\SupportsChrome::buildChromeProcess return (new ChromeProcess(static::$chromeDriver))->toProcess($arguments);

Slide 52

Slide 52 text

Laravel\Dusk\Chrome\ChromeProcess->__construct $this->driver = $driver; if (! is_null($driver) && realpath($driver) === false) { throw new RuntimeException("Invalid path to Chromedriver [{$driver}]."); }

Slide 53

Slide 53 text

Laravel\Dusk\Chrome\ChromeProcess->toProcess if ($this->driver) { return $this->process($arguments); } if ($this->onWindows()) { $this->driver = realpath(__DIR__.'/../../bin/chromedriver-win.exe'); return $this->process($arguments); } $this->driver = $this->onMac() ? realpath(__DIR__.'/../../bin/chromedriver-mac') : realpath(__DIR__.'/../../bin/chromedriver-linux'); return $this->process($arguments);

Slide 54

Slide 54 text

Laravel\Dusk\Chrome\ChromeProcess->process return (new Process( array_merge([realpath($this->driver)], $arguments), null, $this->chromeEnvironment() ));

Slide 55

Slide 55 text

Laravel\Dusk\Chrome\ChromeProcess->onMac return PHP_OS === 'Darwin';

Slide 56

Slide 56 text

為什麼要這樣設計? Tests\DuskTestCase

Slide 57

Slide 57 text

這個梗是要用幾次? 最後一次啦!

Slide 58

Slide 58 text

Dusk 裡面的功能呢?

Slide 59

Slide 59 text

Laravel\Dusk\Concerns\MakesAssertions->assertTitle PHPUnit::assertEquals( $title, $this->driver->getTitle(), "Expected title [{$title}] does not equal actual title [{$this->driver->getTitle()}]." ); return $this;

Slide 60

Slide 60 text

Laravel\Dusk\Concerns trait InteractsWithAuthentication trait InteractsWithCookies trait InteractsWithElements trait InteractsWithJavascript trait InteractsWithMouse trait MakesAssertions trait MakesUrlAssertions trait ProvidesBrowser trait WaitsForElements

Slide 61

Slide 61 text

Laravel\Dusk\Browser public function visit($url) public function visitRoute($route, $parameters = []) public function on($page) public function refresh() public function back() public function maximize() public function resize($width, $height) public function move($x, $y) public function screenshot($name) public function storeConsoleLog($name) public function withinFrame($selector, Closure $callback) public function within($selector, Closure $callback) public function with($selector, Closure $callback) public function onComponent($component, $parentResolver) public function ensurejQueryIsAvailable() public function pause($milliseconds) public function quit() public function tap($callback) public function dump() public function tinker() public function stop()

Slide 62

Slide 62 text

laradock # Dusk Dependencies: RUN if [ ${INSTALL_DUSK_DEPS} = true ]; then \ apt-get -y install zip wget unzip xdg-utils \ libxpm4 libxrender1 libgtk2.0-0 libnss3 libgconf-2-4 xvfb \ gtk2-engines-pixbuf xfonts-cyrillic xfonts-100dpi xfonts-75dpi \ xfonts-base xfonts-scalable x11-apps \ && wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb \ && dpkg -i --force-depends google-chrome-stable_current_amd64.deb \ && apt-get -y -f install \ && dpkg -i --force-depends google-chrome-stable_current_amd64.deb \ && rm google-chrome-stable_current_amd64.deb \ && wget https://chromedriver.storage.googleapis.com/${CHROME_DRIVER_VERSION}/chromedriver_linux64.zip \ && unzip chromedriver_linux64.zip \ && mv chromedriver /usr/local/bin/ \ && rm chromedriver_linux64.zip \ ;fi

Slide 63

Slide 63 text

¯\_(ツ)_/¯

Slide 64

Slide 64 text

No content

Slide 65

Slide 65 text

No content

Slide 66

Slide 66 text

套件程式討論團

Slide 67

Slide 67 text

套件程式討論團

Slide 68

Slide 68 text

@ReccaChaoWebDev

Slide 69

Slide 69 text

努力鑽研 不要瞎忙

Slide 70

Slide 70 text

嘗試撰寫自己的套件

Slide 71

Slide 71 text

No content

Slide 72

Slide 72 text

tl;dr (again) ● 套件訊息可以找 packagist ● packagist 上可以找程式碼的repo,通常是 github ● 套件程式碼內可以看到很多前輩的寫法和架構設計 ○ 見賢思齊 ○ 於不疑處有疑 ● composer.json ● serviceProvider ● handle() v.s. fire() ● 剩下的功能都在原始碼裡面 ○ Assert 實作找 Laravel\Dusk\Concerns\MakesAssertions ○ Browser 功能實作找 Laravel\Dusk\Browser

Slide 73

Slide 73 text

不只是 Dusk 還有千千萬萬的套件程式碼

Slide 74

Slide 74 text

投影片網址

Slide 75

Slide 75 text

這次是真的了