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

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

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

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

Hisashi SOGA
PRO

December 12, 2020
Tweet

More Decks by Hisashi SOGA

Other Decks in Technology

Transcript

  1. でしか きない問題に
    早く気が付けるように、
    僕は Laravel Dusk
    で CI
    する
    2020.12.12
     @sogaoh
    25 min Regular Session [Track4-4-A] @ PHP Conference Japan 2020
    1 / 35

    View Slide

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

    View Slide

  3. This talk for
    リリース に、 不⾜のため
    切り すことになりたくない開発者
    で きるデグレードのたびに
    ビジネスサイドから められたくないQA
    担当者
    「 え万 」でありたい へ
    3 / 35

    View Slide

  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

    View Slide

  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

    View Slide

  6. でしか きない問題たち
    こんなこと、ありますか
    6 / 35

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  10. 構成
    local internal DNS
    frontend backend
    ELB ECS
    webfront(nginx)
    ECS
    appfront
    ECS
    webback(nginx)
    ECS
    appback
    RDS
    10 / 35

    View Slide

  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

    View Slide

  12. Login (2)
    _ _
    > 翻 間 ってる <
     ̄Y^Y^Y^Y^Y^Y^Y^Y^

    の ⽰チェックがやりきれていない
    とはいえ、 ⼒で 羅的に を点 するのには 界が
    あり、⼀ は 械翻 を 恒久的 的 に使うケースも さ
    れている現場が そう
    12 / 35

    View Slide

  13. Login (3)
    _ _
    > サムネイルの が <
     ̄Y^Y^Y^Y^Y^YY^Y^Y^

    をよく⾒るまで、有 期 の指 時に +
    符 を れる必
    があることに気付けなかった
    を正しく
    していなかった
    Amazon S3
    バージョン 3
    での の署 付き URL - AWS SDK for
    PHP
    Laravel
    ファイルストレージ の ファイル 性
    13 / 35

    View Slide

  14. その他
    webpack
    のビルドが わらない...
    NODE_OPTIONS
    の max-old-space-size
    を したり
    UV_THREADPOOL_SIZE
    を使ってみたり
    AWS
    ⽤が い...
    Blue/Green
    デプロイで 働していない の ECS

    desiredCount
    を制 しようとしてみたが datadog-agent
    container
    が schedulingStrategy : "REPLICA"
    をサポートして
    ないので踏み切れていない( うまく使いたい)
    ecspresso
    14 / 35

    View Slide

  15. 平和を めて CI
    を てる
    プロダクトと、いっしょに。
    15 / 35

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  20. Laravel Dusk

    CI
    に せる
    思いつきからのチャレンジだった
    20 / 35

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  24. CI
    に せた 果
    ⾃動でブラウザテストが
    回せるようになった
    ログイン前の
    動しない
    問 せが来ない
    (
    ログインできない)
    ログイン の
    ある ⾯が500
    エラー
    翻 間 ってる
    (
    サムネイルの が )
    早く できることが
    えた
    範囲が がった
    なぜ失敗 を える
    ようになった
    24 / 35

    View Slide

  25. (Dusk Examples)
    ⽣デモは 念して動 です
    題材は です
    (Dusk Test
    を )
    Snipe-IT
    という OSS

    fork
    して し⼿を えたもの
    はじめに状況 を簡単にします
    25 / 35

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  29. それではごらんください (1)
    https://youtu.be/TCt6wnf5C-k
    29 / 35

    View Slide

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

    View Slide

  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

    View Slide

  32. まとめ
    プロダクトに む落とし は 知れず、
    動かしてみないとわからないことがたくさんある。
    それを 回する⼿ の1つとして 択したのが
    Laravel Dusk
    。けっこうオススメできる。
    CI
    を んでプロダクト⼀式の構 を掴むことは、
    ⾃ の⼒にもチームの⼒にも⼤いになる。
    32 / 35

    View Slide

  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

    View Slide

  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

    View Slide

  35. お気づきの点あれば

    まで
    @sogaoh
    Discord  Ask the Speaker
    へも
    お気軽にどうぞ -> #track4-4-a-laravel-dusk
    (End)
    35 / 35

    View Slide