Upgrade to Pro — share decks privately, control downloads, hide ads and more …

本番でしか起きない問題に早く気が付けるように、僕は Laravel Dusk で CI する

7e3cdbf62ad6e34cf379443678b1b378?s=47 Hisashi SOGA
December 12, 2020

本番でしか起きない問題に早く気が付けるように、僕は Laravel Dusk で CI する

sogaoh's Regular Session (25 min) [Track4-4-A] for PHP Conference Japan 2020 (2020/12/12). 今も開発が続いている新サービス。リリースのたびにトラブルが発生してしまう状況をなんとかしようと取り組んできた Laravel Dusk の CI への導入などに関して話します...

7e3cdbf62ad6e34cf379443678b1b378?s=128

Hisashi SOGA

December 12, 2020
Tweet

Transcript

  1. でしか きない問題に 早く気が付けるように、 僕は Laravel Dusk で CI する 2020.12.12

     @sogaoh 25 min Regular Session [Track4-4-A] @ PHP Conference Japan 2020 1 / 35
  2. AGENDA でしか きない問題 平和を め CI を てる Laravel Dusk

    を CI に せる まとめ・Appendix 料は 開してあります -> [ ※'21/02 まで] https://kutt.it/cpvRco ※1. 履歴が するため、シークレットウィンドウでご ください(Chrome を 奨) ※2. ところどころのオレンジの はリンクになっています ※3. スペースで のページに みます([o] でOverview が⾒れます) 2 / 35
  3. This talk for リリース に、 不⾜のため 切り すことになりたくない開発者 で きるデグレードのたびに

    ビジネスサイドから められたくないQA 担当者 「 え万 」でありたい へ 3 / 35
  4. ⾃⼰ @sogaoh : Hisashi SOGA Freelance '19/02 〜 Web Enginieer[PHP]

    '12 〜 former Java,C development '20/09 '20/07 (15 )  '20/04 にContribute(1 ) エンジニアの成 を 援する 2 July Tech Festa 2020 Covid19Radar '20/02 当⽇スタッフ '20/01 コアスタッフ '19/12 LT PHPerKaigi2020 SRE NEXT 2020 PHP Conference Japan 2019 Several communities belonging 4 / 35
  5. の活動 央 @sogaoh 2 件 えてる #sto #codeforjapan 【NPO の

    をIT で える、 しいキャリアへの挑戦】ソーシ ャル・テクノロジー・オフィサー 件 (10 ⽉) sto-c4j- 20201025.peatix.com @PeatixJP より 1 0:51 - 2020 年10 ⽉25 ⽇ 央さんの他のツイートを⾒る 【NPO の をIT で える、 しいキャリアへの挑戦】ソーシャル… IT や のスキルを活かして 題に挑む しいキャリアの 択… sto-c4j-20201025.peatix.com 央 @sogaoh スクラップ はじめました #zenn Amazon Linux WorkSpaces で個別の作業 を作り むzenn.dev/sogaoh/scraps/… 3:59 - 2020 年11 ⽉22 ⽇ 央さんの他のツイートを⾒る Amazon Linux WorkSpaces で個別の作業 を作り… zenn.dev 央 @sogaoh 2 ヶ⽉ぶりの、つづきです。 #mackerelio #esa_io 10 ⽉の わりに間に った。。 Pubs/Mackerel Ambassador (sogaoh) blogs/GoogleAnalytics で 得したアクティブユーザー を 期的にMackerel サービスメ トリックに する (3) - esa-pages.io esa- pages.io/p/sharing/6641… 3 14:46 - 2020 年10 ⽉31 ⽇ 央さんの他のツイートを⾒る Pubs/Mackerel Ambassador (sogaoh) blogs/GoogleAnalytics で … このエントリは [@sogaoh](https://twitter.com/sogaoh) の Macker… esa-pages.io 央 @sogaoh #datadog でログからエラー 知時に、ファイルパスなどのエス ケープ のあるところは %word だと思うように Grok パーサ ーが作⽤しない。 %data にすると期待 りに作⽤し た。docs.datadoghq.com/ja/logs/proces… 9:47 - 2020 年10 ⽉19 ⽇ 央さんの他のツイートを⾒る パース Grok プロセッサーを使⽤してログをパースする docs.datadoghq.com 5 / 35
  6. でしか きない問題たち こんなこと、ありますか 6 / 35

  7. Login 前 (1) _ _ > 動しない <  ̄Y^Y^Y^Y^Y^Y^  ̄

    snipe it より use Adldap\Adldap; use Adldap\Models\User as Adld use Adldap\Query\Paginator; use Adldap\Schemas\Schema; use App\helpers\Helper; use App\Models\User; i \ \  プロダクション がLinux なので、⼤ ⼩ が ⼀ していないとオートロードが失敗するが、 開発 がMac/Windows なので開発時は気づかない phpcs-psr4-sniff: クラスがPSR-4 に しているかチェックする ツールを作った - Qiita 7 / 35
  8. Login 前 (2) _ _ > 問 せが来ない <  ̄Y^Y^Y^Y^Y^Y^Y^Y^

     ̄ snipe it より MAIL_DRIVER=smtp MAIL_HOST=${MAIL_PORT_587_TCP_ MAIL_PORT=${MAIL_PORT_587_TCP_ MAIL_USERNAME=${MAIL_ENV_USERN MAIL_PASSWORD=${MAIL_ENV_PASSW MAIL_ENCRYPTION=${MAIL_ENV_ENC ${ AWS ECS タスク 義に MAIL_ENCRYPTION が されてなかった... 開発 では ⽤との 別の で別のSMTP サービス を⽤いていた... ( ではうまくいっていた) Mailgun 8 / 35
  9. Login 前 (3) _ _ > ログインできない <  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y  ̄

    [ {"comment": "( イメージです)"}, { "name": "APP_BACK_HOST", "value": "prod app back.local" }, { "name": "APP_ENV", "value": "production" }, { 時に (ECS) タ スクセットへのルーティングが⾏われるが、( おそらく) 上 の front nginx が DNS をキャッシュしていて、back nginx の IP ア ドレスを れ替わったものに えていなかった ( 項に の構成 ) AWS CodeDeploy での Blue/Green デプロイ 9 / 35
  10. 構成 local internal DNS frontend backend ELB ECS webfront(nginx) ECS

    appfront ECS webback(nginx) ECS appback RDS 10 / 35
  11. Login (1) _ _ > ある ⾯が500 エラー <  ̄Y^Y^Y^Y^Y^Y^Y^Y^Y

     ̄ drwxr xr x - own grp conf g drwxr xr x - own grp database .rw r r 1.0k own grp package.jso .rw r r 1.2k own grp phpunit.xml drwxr xr x - own grp public .rw r r 809 own grp README.md drwxr xr x - own grp resources drwxr xr x - own grp routes .rw r r 563 own grp server.php drwxrwxrwx - own grp storage 、フレームワークに必 なディレクトリが消えてしまっ ていた。 処 としてディレクトリを作成し、 的にパ ーミッションをフルコントロール(777) に して回 ( デプロイ時に 切にオーナー・パーミッションを する・ 必 なディレクトリへの書 を⾏うのが良さそう) 11 / 35
  12. Login (2) _ _ > 翻 間 ってる <  ̄Y^Y^Y^Y^Y^Y^Y^Y^

     ̄ の ⽰チェックがやりきれていない とはいえ、 ⼒で 羅的に を点 するのには 界が あり、⼀ は 械翻 を 恒久的 的 に使うケースも さ れている現場が そう 12 / 35
  13. Login (3) _ _ > サムネイルの が <  ̄Y^Y^Y^Y^Y^YY^Y^Y^  ̄

    をよく⾒るまで、有 期 の指 時に + 符 を れる必 があることに気付けなかった を正しく していなかった Amazon S3 バージョン 3 での の署 付き URL - AWS SDK for PHP Laravel ファイルストレージ の ファイル 性 13 / 35
  14. その他 webpack のビルドが わらない... NODE_OPTIONS の max-old-space-size を したり UV_THREADPOOL_SIZE

    を使ってみたり AWS ⽤が い... Blue/Green デプロイで 働していない の ECS の desiredCount を制 しようとしてみたが datadog-agent container が schedulingStrategy : "REPLICA" をサポートして ないので踏み切れていない( うまく使いたい) ecspresso 14 / 35
  15. 平和を めて CI を てる プロダクトと、いっしょに。 15 / 35

  16. はじめから Test graphql-playground と 同じことを Feature テスト protected function graphql(

    string $query, array $variables = ): TestResponse { $data = [ 'query' $query, 'variables' \json_encode($va ] + $data; return $this post('/graphql', $d } を に抽 クラスを作成 想 果(JSON) を み る共 を して assertJson Laravel 5.7+GraphQL(Test )-Qiita $response = $this graphql($query); $response assertStatus(Response HTTP_OK) assertJson($expected); ⼒graphql ・ ⼒json をループで回す( 易にケース ) 16 / 35
  17. Test DB を使う Repository の Unit テスト (CRUD も に)

    protected function setUp(): void { parent setUp(); $appEnv = conf g('app.env'); if (!self $migrated) { $this artisan('migrate:fresh self $migrated = true; } } setUp で migrate を1回だけに 制し DatabaseSeeder ⾏ ・更 は Test 了時に rollback して を 例 発⽣の も finally で rollback して 現 必 に じて tearDownAfterClass で truncate なども 17 / 35
  18. CI を作る docker-compose.yml を 紐 き、CI を える snipe it:

    #image: snipe/snipe it:develop build: context: ./ dockerf le: Dockerf le.dusk env_f le: - ./.env.docker compose volumes: - ./storage:/var/ /html/sto - ./tests/Browser/screenshots / j / / / 個々 のPC スペックで Unit Test がやり切れない(メモリ⾜り ない)問題がCI の発 プロセスは でほぼ えてあった Makefile - make ci up - docker compose exec -T appback make vendor からの開発 簡 が重 局⾯で活きる 18 / 35
  19. A :CI の 期 ⾏ 事項は、 UTC で すること curl

    -X POST \ user $(USER_ID) $(APP_PASSWORD) \ header 'Content type: application ' data '{"type":"pipeline_schedule" "target": {"type":"pipeline_ref_t "selector" {"type":"custom","patt "cron_pattern": "0 15 0 ? * MON,T }' https: api.bitbucket.org/2.0/repo を⾒て、 指 のスケジュールは API で することを知り、 などを 査 で 現できそう があり、可 そう Scheduled pipelines | Bitbucket Cloud | Atlassian Documentation API ドキュメント GitHub Actions では schedule イベント GitLab にも Pipeline schedules API 19 / 35
  20. Laravel Dusk を CI に せる 思いつきからのチャレンジだった 20 / 35

  21. Dusk とは e2e テストツールの1つ ブラウザの⾃動操作を 現 protected function driver() {

    $options = (new ChromeOptions) a return RemoteWebDriver create( ' ', ' ', DesiredCapabilities chrome() ChromeOptions CAPABILITY, $o ) ); } http: localhost:9515 http: selenium:4444/wd/hub standalone の ChromeDriver を使⽤する( みの Selenium compatible ドライバも使⽤可 ) 利⽤が簡単なブラウザの⾃動操作∕テストAPI を提供 composer require dev laravel/dusk  にDusk をインストールしてはいけません composer install no dev 21 / 35
  22. CI を backend テストに えて frontend ビルドも必 に FROM docker:stable

    # Install Browser RUN apk add update udev chromium # Install fonts RUN apk add no cache curl fontcon # Add python pip & bash, node npm RUN apk add no cache py pip \ フロントエンドのビルドができるように、Dockerfile へ node.js と npm のインストールを ⽰ができるように Font と を に をインストールして locale を さらに念の為 "Locales alpine 3.9" alpine-pkg-glibc chromium と driver もインストール 22 / 35
  23. 必須データの e2e テスト成立に必 な データをSeeder で class BrowserTestDataSeeder extends {

    public function run() { DB beginTransaction(); try { $this call([ DuskTestDataSeeder class, ]); DB commit(); } (\ i $ ) { CI の 動-> バックエンドのアプリケーション配 -> Migration ・Seeder ⾏(データ ) フロントエンドのアプリケーション配 (JS ビルドを む) これらを⾏ったうえで、php artisan dusk を ⾏ 23 / 35
  24. CI に せた 果 ⾃動でブラウザテストが 回せるようになった ログイン前の 動しない 問 せが来ない

    ( ログインできない) ログイン の ある ⾯が500 エラー 翻 間 ってる ( サムネイルの が ) 早く できることが えた 範囲が がった なぜ失敗 を える ようになった 24 / 35
  25. (Dusk Examples) ⽣デモは 念して動 です 題材は です (Dusk Test を

    ) Snipe-IT という OSS を fork して し⼿を えたもの はじめに状況 を簡単にします 25 / 35
  26. 々な操作の再現 (1) ID ・パスワードを ⼒して、ログインする $browser visit('/login') type('username', BrowserTes type('password',

    BrowserTes press('Login') waitForText('Snipe-IT Demo' assertSee('Snipe-IT Demo') assertSee('Dashboard') assertSee('Recent Activity' assertSee('Assets by Status assertSee('Asset Categories 26 / 35
  27. 々な操作の再現 (2) プロフィールを する Admin (User Name) を click し

    サブメニューを ⽰ $browser driver f ndElement( WebDriverBy xpath($userMenuX ) click(); $browser waitForText('Edit Your Prof Edit Your Prof le ⾯へ $browser driver f ndElement( WebDriverBy xpath($editProf ) click(); $browser waitForText('Gravatar Email assertPathIs('/account/prof Language を Japanese に 更して $browser driver f ndElement( WebDriverBy xpath($languageX ) click(); $browser driver f ndElement( WebDriverBy xpath($japaneseX ) click(); $browser press('Save') waitForText(' プロファイルを 27 / 35
  28. 々な操作の再現 (3) Navigation を 開し、サブメニューを 択 左上の navigation を click

    してサブメニューを ⽰ $browser driver f ndElement( WebDriverBy xpath($navigatio ) click(); $browser waitForText('Requestable') assertSee('Settings'); Settings Manufacturers $browser driver f ndElement( WebDriverBy xpath($settingsX ) click(); $browser waitForText('Manufacturers' $browser driver f ndElement( WebDriverBy xpath($manufactu ) click(); Asset Manufacturers ⾯へ $browser waitForText('Support Email' assertPathIs('/manufacturer assertSee('Asset Manufactur ; 28 / 35
  29. それではごらんください (1) https://youtu.be/TCt6wnf5C-k 29 / 35

  30. それではごらんください (2) https://youtu.be/pujAkC49gYE refs: Dusk (5.8) -> の 得∕ 30

    / 35
  31. B :reCAPTCHA の 破 ( 例) #Submit ボタンを script で

    assertSee('E-mail Address') assertDisabled('#agreeSubmit') keys('#interimEmail01', Const EMAIL, '{tab}','{tab}') script('window.scrollTo(0, 500);'); ボタンを ⾯内に ま reCAPTCHA 策 $browser script( "document.querySelector('#agreeSubmit').disabled = ''" ); $browser press('[type="submit"]') 31 / 35
  32. まとめ プロダクトに む落とし は 知れず、 動かしてみないとわからないことがたくさんある。 それを 回する⼿ の1つとして 択したのが

    Laravel Dusk 。けっこうオススメできる。 CI を んでプロダクト⼀式の構 を掴むことは、 ⾃ の⼒にもチームの⼒にも⼤いになる。 32 / 35
  33. Appendix (1) Flex Plan は 3 months 5000 を超えると$0.80 /

    1000 emails PSR-4: Autoloader - PHP-FIG Flexible Pricing & Email Delivery Plans - Email API Service | Mailgun TLS |Cuenote FC nginx の 前 決について - Qiita Nginx のDNS 前 決とS3 やELB へのリバースプロキシ Cloud Diagrams - GitPitch Documentation Diagrams · Diagram as Code ShellScript の代わりにPython タスクランナーFabric&Invoke を活⽤する技 - 74th - BOOTH Amazon ECS - (Datadog) Agent をデーモンサービスとして ⾏ ecspresso Advent Calendar 2020 33 / 35
  34. Appendix (2) ->  UnitTest を 率的に作り・回す Laravel 開発での⼿間を なくするMakefile

    作戦 Snipe-IT Free open source IT asset management GitHub Solved: What is wrong to create pipeline schedule ? - Atlassian Comunity Free Online Cron Expression Generator and Describer - FreeFormatter.com laravel5.5 でdusk がうごかへんねん - Qiita Dockerfile に apt, apt-get, source コマンドを書く時のTips Complex Selectors in Dusk Laravel Dusk on Homestead | by Mike Smith | Medium Laravel Dusk テストコード作成時の った場 の 処 | LaptrinhX Selenium webdriver メソッド~PHP~ - Qiita 34 / 35
  35. お気づきの点あれば  まで @sogaoh Discord  Ask the Speaker へも

    お気軽にどうぞ -> #track4-4-a-laravel-dusk (End) 35 / 35