Photoruction工事中!

Photoructionの開発ブログです!

playwrightを使ってWEBのE2Eテストを自動化してみた 〜導入編〜

こんにちは!株式会社PhotoructionでQAエンジニアをしています内田です。 Photoruction Advent Calendar 2021の13日目の記事です。

手動で実行していた最低限のリグレッションテストを自動化してみたのでその記録です。

目次


  1. 自動化しようとした背景
  2. 自動化してみた結果所感
    1. スムーズに導入できなかったよ
  3. 導入までの道のり
    1. ツール選定
    2. 自動テスト実装
      1. 実装詳細
  4. まとめ

自動化しようとした背景


  • 毎回同じテストの実施が面倒なのでなんとかしたい(これが1番)
  • テスト工数削減

の目的で自動化を検討しはじめました

自動化してみた結果所感


playwrightの導入はスムーズにできました!

が、テスト実装がスムーズできませんでした・・・(詳細は次の記事へ)

導入までの道のり


ツール選定

世の中には自動テストツールやSaaSがたくさんありますが、playwrightを選んだ理由は下記です

  • 自動テストの導入・実装が簡単なこと
    • テストコード自動生成機能があること
  • 手動で実行した場合と比較してコストが安くなること
  • 好きなときにテストをたくさん実行できること

自動テスト実装

インストール

$ npm i -D @playwright/test
$ npx playwright install

configファイル作成します。(なくてもOKです) テストの各種詳細を設定できます。 詳細は公式ドキュメントを参照ください。 以下おすすめの設定です。

// playwright.config.js

const config = {
    use: {
        browserName: 'chromium',
        video: 'on', 
        acceptDownloads: true,
        actionTimeout: 10000,
    },
    timeout: 40000,
    testDir: './testcase',
    expect: {
        toMatchSnapshot: { threshold: 0.2 }
    },
    maxFailures: 10
};

テストファイル作成

弊社サービスの写真機能の表示切り替えが有効かを確認するテストをサンプルで記載します。 表示切り替えボタンをクリックすると、写真一覧の表示がタイル表示⇔リスト表示に切り替わる機能です。 手動で操作すると以下の操作になります。

操作手順としては以下になります。 ①ログインする ②テスト対象ページをひらく ③切り替えボタンをクリック ④切り替えボタンを再度クリック テストコードは以下です。

//testcase/photo.test.js

const { test, expect } = require('@playwright/test');
const path = require('path');

test.beforeAll(async ({ browser }) => {
    let context = await browser.newContext();
    let page = await context.newPage();
    {{ログイン処理}} ・・・手順①
    // ログイン情報を保存
    await page.context().storageState({ path: path.join({{保存先のパス}}, 'strageState.json') });
        {{対象の画面への遷移など事前準備をしておく}} ・・・手順②
    await context.close();
});

test.describe('写真機能', () => {
    test('表示形式が変更できるか', async ({ page }, testInfo) => {
        await page.waitForSelector('#photo_list >> .photo'); // 写真の要素
        await page.click('#change_display'); ・・・手順③
        expect(await page.screenshot()).toMatchSnapshot([testInfo.title, {{実行環境情報}} ,'表示形式リスト.png']);
        await page.click('#change_display'); ・・・手順④
          await page.waitForSelector('#photo_list >> .photo'); // 写真の要素
        expect(await page.screenshot()).toMatchSnapshot([testInfo.title,  {{実行環境情報}}, '表示形式タイル.png']);
    })
});

テスト実行

$ npx playwright test

※テスト初回実行時のみ、キャプチャのゴールデンファイル(正とするファイル)が生成されます

実行結果

こんな感じの出力になります configで指定したフォルダ配下に.webmの拡張子でキャプチャビデオが生成されています キャプチャビデオはこんな感じです。 test()で囲った部分から操作キャプチャが開始されます。

まとめ


playwrightを導入すること自体は簡単でした。 目的であった手動テスト工数削減も少しずつですが達成できています。 今後は自動テスト項目数を増やしたり、メンテナンスしやすいコードにしたいと考えています。 機会があればCIでのテスト実行方法も記事化したいです。

この記事の続きはこちら kojichu.photoruction.com

   

株式会社フォトラクションでは一緒に働く仲間を募集しています www.wantedly.com

corporate.photoruction.com

gatherで「ちょっと、いいですか?」ができる空間を作った話

こんにちは!株式会社フォトラクションでWebエンジニアをしている田中喜規です! Photoruction Advent Calendar 2021の12日目の記事です。

 

2020年からテレワーク環境が続いていますね。

 

これまでのようにオフィスに出社ができない状況だと、社内のコミュニケーションの絶対量は少なくなってしまいますよね。

おそらく、どの会社でも、こうした悩みや課題があるのではないでしょうか。

 

今年から、PhotoructionのWebエンジニアチームでは、gather.town(以下gatherと省略)というツールを使って、チームのコミュニケーションを促進しようと頑張っていました!

 

 

目次

 

gatherとは?


ポケモンドラクエを彷彿とさせる、レトロなUIで、さまざまなスペースを選択し、複数人のユーザーがチャットやビデオ通話ができるサービスです。

 

出社時と同じ感覚を得られる

Zoomやgoogle.meetは、URLリンクから参加できる人全員が一律同じ空間で、会話ができるものとなっていると思います。いわゆる、「Web会議ツール」ですよね。

 

gatherは、Web会議だけではなく、もっと用途が広いです。

Photoructionでは、以下のように、社員1人1人が部屋を作って、作業。

 

用がある時に、他メンバーの部屋を訪ねるようなイメージです。 「オンラインオフィスサービス」として利用してます。

f:id:photoruction_tech_blog:20211203104027p:plain

(私田中の自室です笑。宇宙船内で、ソロキャンプをしています)

パーソナルスペース

gatherでは、以下の状況で会話に参加ができます

  • 一定の距離感にいるか
  • パーソナルスペースにいるか
  • パブリックスペース(大部屋など、全員にアナウンスできる場所)

 

パーソナルスペースは、Zoomやgoogle.meetのように、同じ空間にいるメンバー全員に会話が聞こえるということはなく、オフラインの出社と同じ感覚で、ある一定の距離感の範囲内でないと会話が聞こえない仕組みとなっています。

 

実際のオフィスで、会議室を利用して打ち合わせを行う要領で、メンバー複数人で会話が可能です。打ち合わせが終われば、そのまま、自室に帰って各々の業務に戻る形で運用しています。

f:id:photoruction_tech_blog:20211203104441p:plain

ちょっと、いいですか?ができる空間を作りたい


元々、弊社のWebエンジニアチーム内の課題として、コミュニケーションが希薄になっていることが課題の1つとしてありました。

 

現在Photorucitonのエンジニアチームは、完全リモートでの働き方となっています。

定例やPJごとのミーティングがない限りは黙々と、業務を進めていくことになります。

勿論それはそれで利点になっているのですが、チーム全体でものづくりをしている意識や、困ったときに、助け合いができるような連帯感が薄いことに課題感がありました。

 

オフィスワークでよくある、隣のメンバーへの「ちょっと、いいですか?」ができれば、それだけで問題が解決することも、リモートワークでは時にはgoogle.meetで開催をセッティングし、slackで質問内容を考え、送信することが必要になります。

 

また、日々のちょっとしたやり取りから、メンバー間の関係性ができて、より良い職場環境となることも、リモートワーク環境以前では、当たり前のように生まれていたと思います。

 

そんな、「ちょっと、いいですか?」ができる環境づくりに適しているツールとして、gatherを活用していく運びになりました。

gather内でやったこと


用途は多岐に渡り、さまざまな楽しみ方ができます!

  • ランチ会(Webチーム内で週一)
  • bug bash(Photoructionのバグを社内で見つける月一イベント)
  • オンライン飲み会(不定期)

bug bashの時の様子

f:id:photoruction_tech_blog:20211203104512p:plain

 

無人島で、オンライン飲み会を開催(パブリックスペースがなく、密になりながら乾杯)

f:id:photoruction_tech_blog:20211203104536p:plain

実際、効果はあったか?


田中の独断と偏見だと、かなり働きやすくなったと思いました!

話しかけにいっていいんだ!って安心感を得た部分があり、「聞くハードル」が下がったように思います。

 

また、slackで何か問題が流れてて、gather内でその件について話をしていたりすると、

それを聞きつけて、他メンバーが心配して、覗きにくる場面もあったので、「コロナ前のオフィスワーク」にかなり近い雰囲気、連帯感も感じられました。

 

Webエンジニアチームに関わらず、他部署のチームも気軽に話しかけに来てくださることもよくあるので、間違いなく、コミュニケーションは増えたと思います!

 

コミュニケーションの問題なので、ツールを導入して解決!ということはないですが、解決のひとつのきっかけになるかもしれないので、個人的にはおすすめです笑。

 

株式会社フォトラクションでは一緒に働く仲間を募集しています 

 

PMの私がチームとの向き合い方で大切にしていること

はじめに

株式会社フォトラクションでプロダクトマネージャー(PM)をしています千葉由孝と申します。

Photoruction Advent Calendar 2021の11日目の記事です。 私は、非IT企業から転職して開発経験もないままPMを任されました。その後、まもなく新規サービスの立ち上げに携わることになります。そんな怒涛のような経験の中で、プロジェクトで発生する問題の向き合い方やチームメンバーとの向き合い方がチームを構築する上で特に大切だと感じました。自分の経験と学んだことを整理して書いてみましたので何かの参考になったらうれしいです。

 

自己紹介


少し私の自己紹介をします。私は前職で、事務所ビルやマンションなどの大型物件の施工管理を担当していました。いわゆる現場監督です。

突然ですが、建設現場で働く職人さんはめちゃめちゃかっこいいのって知っていますか?

自分たちが作ったものに対するプロ意識が非常に高く、使う人のことをいつも考えています。その妥協しない仕事振りはとても魅力的でした。こういう人たちが日本の建設業を支えていると思うととても誇らしい気持ちになります。また、建設業は建物や道路など生活の基盤を作る重要な産業です。

魅力がたくさんある一方で、現場監督の仕事は書類と格闘する長時間労働の日々でした。紙図面を持ち歩き、毎日現場で検査を行ったりと、職人さんが帰ってから夜遅くまで大量の書類作成に追われます。そんな日々を過ごすうちに、建設業で働く人々をもっと楽にする方法はないのかと考えるようになりました。そして、現場で培った経験を活かしかゆいところに手が届くプロダクトを作りたいという思いで転職しました。

建設業のことばかり書いてしまいましたが、私はそんな建設業が大好き人間です。この情熱でPMとして今日まで活動してきました。

 

チームを構築するために大切にしていること


私は、建設業のドメイン知識は自信がありましたが、それだけでは良いプロダクトを作ることはできません。PMの仕事はビジネス、テクノロジー、UXの領域が必要になります。ですがこの広い領域のスキルを一朝一夕で身に着けることは当然ながら難しい。そのため、スキルや知識がある人に協力を得たり、スキルを補完し合う関係性をチームで構築していくことが大切になります。

そのために私が意識していることは以下の2点です。

1.問題が発生したら自分ごと化してチームメンバーに共感し行動する

2.相手との目線合わせや役割の理解を大切にする

 

1.問題が発生したら自分ごと化してチームメンバーに共感し行動する


どのプロジェクトもそうだと思いますが、進めていく中で、大なり小なり様々な問題が発生します。チームの問題を解決に導くのもPMの役割です。私は、チームメンバーが直面する問題を人任せにせず、自分の問題として捉え、当事者意識も持つようにしています。

その上で、対応するメンバーの置かれた状況や気持ちを理解するところから行動を起こすようにしています。自分で解決できそうなら静観して見守ります。困っていたら一緒に手伝います。もしくは他のメンバーを巻き込みチームで解決するように支援をします。メンバーの気持ちに共感し、その人が力を発揮しやすい解決策を考えることも大切だと思います。

この大切さに気づいたのは、あるプロジェクトで起きた出来事がきっかけでした。担当エンジニアは実装方法について悩んでいたのですが、自分の領域外だと思い、エンジニアに任せっきりにしてしまいました。エンジニアは課題を抱えたまま、時間が経ち、リリースの延期など大きな問題に発展することになりました。私の当事者意識が欠けていたことが、課題の放置に繋がってしまったのだと思います。

 

2.相手との目線合わせや役割の理解を大切にする


PMの仕事は開発からビジネス領域まで多岐にわたるので、他部署の人と会話や議論をする機会が多くあります。私が意識しているのは、その人がどういう目線でプロダクトについて話しているのかを理解することです。

時には、さらに進んでその人の思考のプロセスをトレースするくらいその部署の人になりきることを意識しています。少し過剰かもしれませんが、それくらい意識しないと他人を理解することが難しいからです。

例えば、営業の人であれば、どういう伝え方が顧客に刺さるのか、顧客の業務がどのくらい改善されるのか、競合他社との違いや優位性は何なのかといったことを考えているかもしれません。

エンジニアであれば、実装する機能を顧客がどのように使ってくれるのか、実装にモダンな技術が使われているのかといったことを考えているかもしれません。(あくまで一例なのでみんなそうというわけでなく、目線が違うということが伝わればありがたいです。)

また、その人を理解するには、どんな業務をやっているのか役割を理解することも大切です。

以前は、他部署の方と話すときになかなか理解してもらえず苦労していたことが多かったですが、相手の役割や目線の理解し、準備をしっかりして相手目線で話すことで、共通理解を作りやすくなったと感じています。

 

まとめ


PMになって1年半余りの経験を通して、プロジェクトの問題の向き合い方、チームメンバーや関係者との向き合い方について記載しました。

不確実なプロダクト開発の中で、日々起こる問題を乗り越えていけるチーム作りが必要ですし、そのためには、関係者の協力を集め、必要なスキルを補完し合う関係性を構築していくことが大切だと感じています。

これからも建設業で働く人々に役立つプロダクト作りに邁進していきます。

読んでいただきありがとうございました!

 

 

株式会社フォトラクションでは一緒に働く仲間を募集していますhttps://corporate.photoruction.com/careers/ https://www.wantedly.com/companies/photoruction/projects

カスタマーサクセス・サポートを経験したプロダクトマネージャーの強みと苦労について

こんにちは!株式会社フォトラクションでPMグループリーダーをしている市橋です。 Photoruction Advent Calendar 2021の10日目の記事です。

本記事では、カスタマーサクセス(CSM・サポート)を経てプロダクトマネージャー(PM・PdM)にキャリアチェンジした私が考える、ユーザーに近いポジションからプロダクトマネージャーになったことによる強みと苦労している点ついて簡単にまとめています。

同じようにカスタマーサクセスやカスタマーサポート(以降、CSとします)または他の職種から、プロダクトマネージャー(以降、PMとします)へのキャリアチェンジを考えている方の参考になれば嬉しいです。

目次

私の簡単な経歴


私は建築系の学科を卒業後、大手建設コンサルタント企業で道路設計をしていました。

建設業界は労働人口が減少しており、今後さらなる生産性や魅力の向上が求められています。

そんな中、「建設の世界を限りなくスマートにする」というミッションを掲げてアプローチしている弊社で、業界で働く人達がスマートに働けるようにサポートしたいと思い、2019年末にCSMの立ち上げメンバーとして入社しました。

フォトラクションのCS


フォトラクションのCSは、photoructionを導入いただいている企業の方が、よりphotoructionを使いこなしていただけるために、以下のようなことをしています。

  • 導入いただいた企業様への操作説明会の実施
  • 各企業様との月次定例会を開催し、利用状況の確認や今後より活用できるようにするためのアクションプランの策定
  • 利用状況を計測し、使えている方・使えていない方それぞれの要因分析
  • 問い合わせ対応・サポートサイトの作成

PMへのキャリアチェンジを考えたきっかけ


日々photoructionをご利用いただいている方と接していく中で、「こんなことができなくて困ってるんだよね」や「この部分が使いづらいんだよね〜」と言ったご意見を聞いていくうちに、

「こんな機能だったら使いやすいのに」「自分だったらどうやって改良していくだろう」という考えを抱くようになっていきました。

もともと、ものづくりが好きだった(学生自体は建築の模型づくりが好きだったり、自宅の家具をDIYしたり、プログラミングを勉強して簡単なサイトをつくってみたりしていた)こともあって、

photoructionを最大限使っていただけるようにサポートするよりも、使いやすいサービスを作ることでphotoructionユーザーの方々に貢献したいと思うようになりました。

2021年の初めにその思いを当時の上司に伝えてみたところ、「いいんじゃない?市橋くんに向いているかもね。やってみなよ!」とすんなり後押ししてもらえました。(大感謝です!)

その後、2021年3月からCSと兼務する形でPMグループに異動しました。

強み1 : 機能やユーザーの使い方を一番把握している


使いこなしてもらえるようにサポートするため、また、使い方に関するお問い合わせに対して適切に答えるためには、サポートする側が一番使い方を熟知している必要があります。

使い方を熟知するためには、文字通りすべての画面・すべてのボタンを確認しました。

この画面ではどんな挙動をするのか、これは何のための機能なのか、ユーザーの課題を解決するためにはどのように操作するのがいいのかを徹底的に確認します。

嬉しいこと(?)に、photoructionには多種多様な機能があるため、すべての機能を把握するためには日々触り倒して体に染み込ませる必要があります。(稀にお客様からのお問合せで存在を知る機能もあったり、、、)

PMとして新機能を企画する際には、既存の機能との親和性や機能追加することによる影響などを正しく把握する必要があります。

最前線でユーザーと向き合ってきたおかげで、PMに転向してからは既存仕様の理解にあてる時間はほぼなし。開発メンバーから仕様や既存の使い方を確認された際にも即時に返答することができています。

強み2 : 定量調査の経験を企画に活かすことができる


CSとしてユーザーの利用状況を正しく把握するためには、定例会でのヒアリング内容(定性データ)に加えて、アクティブ率などの定量的なデータも活用する必要があります。

私が入社した当時、アクティブ率やデータ量の推移は逐一エンジニアに確認しないと取得できない状況だったため、自分たちで取得できるような仕組みをつくることにしました。

Google Analyticsを用いたアクティブ率の算出や、SQLを書いてデータベースに蓄積されたデータの取得をしながら、利用状況確認用のダッシュボードを作成しました。

(私がCSから異動したあとの今でも、KPIとして活用されています)

私がPMになった時点では、企画段階で定量データを確認する習慣がありませんでした。

仕様検討時に、既存ユーザーの活用状況や蓄積データ量を確認しておくことで、企画精度の向上や開発メンバーに説明する際にも納得感のある説明を行うことができます。

私がPMグループになってからは、社内で非エンジニア向けのSQL勉強会を主催し、PMグループのメンバー全員がデータを見るクセを付けられるように動いています。

また、photoructionの開発組織では、今後ユーザーの行動ログ解析ができるような体制をつくっていく動きをしています。

今後はより精度の高い定量データや、ユーザーインタビューによる定性的なデータなどを活用して、より利用していただいている方々のためになるようなサービス開発をしていきたいと思っています。

苦労 : 開発に関する知識が不足している


photoructionのPMグループは、開発する機能の企画部分(プロダクトマネジメント領域)と、企画した機能をリリースまで持っていく部分(プロジェクトマネジメント領域)を担っています。

企画の部分については、建設業に関するドメイン知識(私は道路計画が専門だったので、建築の施工についての知識は十分ではありませんが)と、CSで培ったユーザーとプロダクト理解の部分でカバーしています。

ただ、プロダクトマネージャー界隈で有名なThe Product Management Triangle でも記されているとおり、PMに求められるスキル・知識はユーザー・ビジネス・開発というとても広い領域で求められます。

特に、プロダクト開発やUI/UXデザイン領域については0からのスタート、かつ、プロジェクトマネジメント部分も任されていることもあってとても苦労しています。

PMという立場上、実装する上での実装難易度の想定であったり、エンジニアからの技術的な提案を受ける際にも、素早く適切な意思決定をしないといけません。

今の開発チームのメンバーは、私が開発領域の知識が少ないことを考慮して、分かりやすい表現を使っていただいていますが(大感謝)、素早く質の高い意思決定をするためには、開発に関する知識がどうしても必要になってきます。

まとめ


前述のとおり、世間一般的に言われるプロダクトマネージャーとして必要なスキル領域はとても広く、実際にやってみるとものすごく難しく感じます。

ただ、最初からすべてのスキルを持っている人はそうそういないのと、色々なバックグラウンドを持ったPMがチームにいたほうが、不足している部分をお互いに補えるので強いチームになれると思います。

現在のPMグループは私を含めて3名在籍しています。

建設業界出身という共通点はありますが、持っているドメイン知識領域はそれぞれバラバラですし、スキル面でも得意不得意な領域はそれぞれ異なっています。

そのおかげで、不足している部分をお互いで補うことによって、チームとしてプロダクト開発に臨めています。

私にPMとして期待されていることは、CS出身者である強みを生かして、photoructionを利用していただいている方の気持ちを一番理解しているPMになることだと思っています。

今、開発畑以外のところで活躍している方々で、PMへの転向を考えている方は、「いいプロダクトをつくりたい」という気持ちと「自分がプロダクトをつくる上で活かせることはなにか」を考え続けることが一番大事だと思います。

最後まで読んでいただきありがとうございました!

Photoruction Advent Calendar 2021の投稿はまだまだ続きます。

他の記事も是非読んでみてください!

 

株式会社フォトラクションでは一緒に働く仲間を募集しています

corporate.photoruction.com

www.wantedly.com

LaravelプロジェクトにViteを用いてVue + Composition API + TypeScript環境を構築

こんにちは!株式会社フォトラクションでWebエンジニアをしています南風原はえばる)です。 Photoruction Advent Calendar 2021の9日目の記事です。

導入

現在、担当している案件のフロントエンドがほぼリプレイス並みの開発というタイミングもあり、技術スタックを新しく見直しました。

開発環境はViteを用いてVue.js + Vue Composition API + TypeScriptで機能開発を行っています。

今回は環境構築までの流れを書いていこうと思います。

 

その前に、現状のPhotorucutionのフロントエンド事情を軽く説明します。

プロダクトの約7割はBackbone.js、jQueryで実装されており、画面の表示はHandlebars.jsというテンプレートエンジンとLaravelのbladeファイルを用いて実装されています。

3年くらい前から新機能の開発はVue.jsで開発していく流れにはなっていますが、まだまだレガシーコード満載な状況です笑

今後さらにフロントエンドの開発環境が良いものとなるように一緒に改善に取り組んでいけるエンジニアを絶賛募集中です!

Viteとは

ViteはVue.jsの開発者であるEvan You氏が開発しているノーバンドルで高速に動作するビルドツールになります。

「ヴィート」と読むそうで、フランス語で「高速」の意味らしいです。(このツールを知った当初は、バイトって読んでました笑)

「高速」というだけあって、プロジェクトの作成も一瞬。ビルド時間もあっというまで開発体験がめちゃくちゃいいです。

Vue.js以外にも、ReactやPreactのビルドもサポートしているそうです。

vitejs.dev

環境構築編

[前提] 既存プロジェクトの大体のディレクトリ構成になります。

root/
 ├ app/
 ├ bootstrap/
 ├ config/
 ├ database/
 ├ public/
 │ └ js/
 │   └ dst/
 ├ resources/
 │ └ assets/
 │   └ js/
 │    └ app/
 │ └ lang/
 │ └ views/
 ├ package.json

1. Viteを使って新しくプロジェクトを作成

既存プロジェクトで使用しているパッケージとは分離するために、新しいディレクトリを作成しViteをインストールします。(メッセージの指示に従って環境のセットアップをしていく)

$ mkdir resources/assets/js/app/[newProject]
$ cd resources/assets/js/app/[newProject]
$ npm init vite@latest

2. Viteで作成した新プロジェクトに移動しビルド実行

$ cd [newProject]/
$ npm install
$ npm run dev

3. Viteプロジェクトのビルド時に生成されたファイルの出力先を変更

vite.config.js 内にビルド時のファイル出力先を既存プロジェクトのファイルパスになるようにします。

build: {
  outDir: '../../../../../public/js/dst/[newProject]'
},

4. scssファイルのインポート設定

vite.config.js 内にコンポーネント共通で参照するscssファイルのパスを追加します。

css: {
    preprocessorOptions: {
      scss: {
        additionalData:
          `@import "./src/assets/scss/variables.scss";
          @import "./src/assets/scss/common.scss";`,
      }
    }
  }

5. 既存プロジェクト(Laravel)にViteプロジェクトを読み込むヘルパー関数を作成

<?php

use GuzzleHttp\\Client;
use Illuminate\\Support\\HtmlString;

function vite_assets($path, $fileName): HtmlString
{
    $devServerIsRunning = false;
    if (config('app.env') === 'local') {
        try {
            $client = new Client();
            $res = $client->get("<https://localhost:3000/{$fileName}>");
            $devServerIsRunning = true;
        } catch ( \\Exception $e ) {
        }
    }
    // ローカルサーバに接続できた場合
    if ($devServerIsRunning) {
        return new HtmlString(<<<HTML
            <script type="module" src="<https://localhost:3000/@vite/client>"></script>
            <script type="module" src="<https://localhost:3000/{$fileName}>"></script>
        HTML);
    }
    // その他の環境ではコンパイルしたjsを返す
    $manifest = json_decode(file_get_contents(public_path("{$path}/manifest.json")), true);
    return new HtmlString(<<<HTML
        <script type="module" src="/{$path}/{$manifest[$fileName]['file']}"></script>
        <link rel="stylesheet" href="/{$path}/{$manifest[$fileName]['css'][0]}">
    HTML);
}

※ローカルサーバー(https://localhost:3000/)で開発する際はlocalhostへのアクセス許可が必要になります。

LaravelのbladeファイルにVueコンポーネントをマウントする方法

既存機能の一部分に新しく作成したVueコンポーネントを表示したいパターンが有るかと思います。

その場合の方法を紹介します。

import FeatureContent from '@/pages/FeatureContent.vue'

// 任意の要素(DOM)の変化を監視する
const observer = new MutationObserver(records => {
  records.forEach(mutation => {
    const target = (mutation.target as any).getAttribute('id')

    switch (target) {
      case 'feature_content': {
        const app = setFeatureContentApp()
        vue = app
        break
      }
    }
  })
})

const featureApp = document.getElementById('feature_app')

if (featureApp) {
  observer.observe(featureApp, {
    attributes: true,
    subtree: true,
    attributeFilter: ['class'],
  })
}

// Vueコンポーネントを任意のDOMにマウントする
const setFeatureContentApp = () => {
  const featureContentElm = document.getElementById('feature_content')
  if (!featureContentElm) return
    return new Vue({
      render: (h) => h(FeatureContent),
    }).$mount('#feature_content')

bladeファイル

<div id="feature_app">
  <div id="feature_menu">
	<!-- 既存View -->
  </div>
  <div id="feature_content" /> ← 新Vueコンポーネントがマウントされる
</div>

まとめ

Backbone.jsで作成された既存機能をVue.jsにリプレイスしていく場合、全てを一から作り直すというのは時間と開発コストがかかります。

上記のような方法で、既存機能への影響を最小限に抑えながら少しずつリプレイスをしていくことが可能だということを今回担当している案件を通して学べました。

これから先、UI/UX含めフロントエンドをどんどんアップデートしていき、ユーザへより一層価値の高いサービスを提供できるようなプロダクトを作っていきたいものです。

ぜひ、一緒にフロントエンド開発を盛り上げていただける方をお待ちしております!

 

株式会社フォトラクションでは一緒に働く仲間を募集していますhttps://corporate.photoruction.com/careers/

corporate.photoruction.com

www.wantedly.com

Photoructionリリースするまでのテストについて(今ある課題と今後の取り組み)

こんにちは!株式会社フォトラクションでQAグループのリーダーをしている塩谷です。 Photoruction Advent Calendar 2021の8日目の記事です。

 

本日はPhotoructionを開発していく中でどのように品質を担保しているのか広めたいと思い、リリースするまでのテスト業務について記事にしてみました。

目次


1.はじめに
2.リリースまでのプロセス
3.開発環境でのテスト
4.リリース環境でのテスト
5.課題と今後

はじめに


私の経歴とフォトラクションのQAグループについてご説明いたします。

 

私は、大学卒業後に某SIer企業に入社いたしました。そこでは仕様策定や評価業務など様々なプロジェクトに従事し、プロダクト開発における上流工程〜下流工程の経験とスキルを積みました。

フォトラクションに入社する直前にはプロジェクト管理者として評価プロジェクトの管理を行っており、その経験が今に繋がっていると感じています。

 

2020年5月に縁があってフォトラクションに入社することになり、その際にCEOの中島からはQAグループを作って欲しいというミッションが与えられました。

当時のフォトラクションにはQAグループが存在しておらず、開発における評価業務はエンジニアがテスターにテストを依頼するという形をとっていました。

ゼロからQAグループを作ることになったので手探り状態でしたが、身の回りの細かいことからコツコツと進めていくことで今のQAグループが出来上がってきたと思います。

リリースまでのプロセス


Photoructionが開発されてからリリースされるまでのプロセスについてご説明いたします。

現在おおよそ1ヶ月に1回新規機能のリリースを行なっており、その際は下図のような開発フローを採用しております。

リリースまでには大きく分けると開発フェーズとリリースフェーズの2つのフェーズが存在しています。

  1. 開発フェーズ
    各開発のフィーチャーブランチで実装を行い、開発環境を作成してテストするフェーズになります。実装〜テスト・各種レビューまで行い開発フェーズが終了します。
  2. リリースフェーズ
    リリースブランチを作成して各フィーチャーをマージしたリリース環境でテストするフェーズになります。 バグが発生したらその都度改修を行い、バグの改修が完了したらリリースフェーズが終了します。

f:id:photoruction_tech_blog:20211202151623p:plain



開発環境でのテスト


開発環境のテストでは、単体テスト結合テストに位置付けられるテストを実施します。

各開発案件にアサインされているQAエンジニアがテストケースを準備し、テスターにテスト実施を依頼します。

テストケースの内容は企画書・仕様書から機能的な確認項目を作成し、QAグループ内のレビュー、PM・エンジニアとのレビューを経て完成します。

それぞれの開発に対して環境を準備してテストすることで開発毎に品質を確保した上でリリース環境にマージしリリースフェーズに臨みます。

各開発についてリリースターゲットはあらかじめ計画していますが、開発環境でのテストをパスできない場合は、リリースターゲットの変更など対策を行います。

リリース環境でのテスト


リリース環境のテストでは、各開発のテストケース再走行とリリース前テストを実施します。

テストケースを再走行する目的は、マージ後の予期せぬデグレの検出となります。

Photoructionは機能的にも実装的にも複雑化しており、各開発をマージした後に予期せぬバグが発生することがあります。

そのため、マージ後の環境でテストケースを再走行することでバグ流出を防ぐように取り組んでいます。

テストケースの実施とバグの改修が完了したら、リリース前の最終テストを実施します。

リリース前テストは開発内容によらず固定のテストケースを実施しており、

内容は全機能の基本的な動作の確認になります。

以前はリリース前テストは実施していませんでしたが、リリース物に対して総チェックを行うべきとの考えからリリース前テストを実施することにしました。

導入した当初は開発に関わるものそうでないものなど様々なバグを検出していましたが、徐々にバグ検出数が減少し、品質が向上してきていると考えています。

全てのテストをパスしたらリリースされます。

課題と今後


フォトラクションのQAグループでは、様々な課題を抱えておりますが、

当然ながら最も重要な課題は市場へのバグ流出を防ぐことだと考えています。

「リリース環境でのテスト」の項でもご説明した通り、リリース環境では各開発の2サイクル目のテストを実施しております。

マージによるデグレリスクを低減させることができれば、同じテストを2サイクル実施するのではなく、別の観点でのテストを実施することで今まで防げなかったバグの流出を防げる可能性が出てきます。

デグレの低減についてはQAグループだけの取り組みでは、改善させることが難しいので開発部門と連携をしながら改善に取り組んでいます。

また、リリース前テストなど定型的なテストについては、自動テストの導入に取り組んでおり、自動テストでまかなえるテスト工数の分だけ別のテストを導入することができます。

自動テストは誰でも実行できるようにすることで、例えばエンジニアが任意のタイミングで実行し早期にデグレなどのバグを検出できる効果も期待できます。

他にも発生したバグ分析やバグの発生数を減らす施策の検討などQAグループとして課題は多く残っている状況ですが、QAグループがリリースされる前に最後までPhotoructionを触っているので”最後の砦”とという自覚を持ち、地道にコツコツと品質を上げていけるようにこれからも努力を続けていきたいと思います。

 

 

今回の記事を通してフォトラクションも品質を向上できるように考えているということが少しでも伝われば幸いです。

ありがとうございました。

 

株式会社フォトラクションでは一緒に働く仲間を募集しています

 

 

Vueのシングルファイルコンポーネント(SFC)を生Javascriptアプリで使おう!

株式会社フォトラクション WEBチーム所属 ジョンです!
Photoruction Advent Calendar 2021の7日目の記事です。

Vueのシングル・ファイル・コンポーネントをSPAではないプロジェクトに使える方法を紹介したいと思います。

目次



フォトラクションでは、アプリケーションの改善を常に行っています。それの一つの計画としては今のアプリケーション内に古く書かれているBackbone.jsとjQueryを最もモダンなフレームワーク、Vue.jsに書き直すことです。

だが一つ問題があり、レガシーコードを書き直しながら新しい機能を増やすことも大事で私たちのリソースをコードの書き直しだけに無駄に使うのがふさわしくない。そのため、Backbone.jsやjQueryで書かれているコードにも新しい機能を追加することもよくあるのです。ソースコードをすべてVue.jsに書き直すついでにBackbone.jsやjQueryをこれ以上増やしたくないので、新しい機能もVueで開発したかったです。

なお、Vueにはいろいろ書き方があります。その一つはSFCを使わずに直接Vueのインスタンスを作ることです。もちろんこのような書き方にしても問題ないですが、VueのSFCのメリットを得られなくなる上に管理もしにくくなります。

<!DOCTYPE html>
<html>
    <head>
        <title>俺のものすごいアプリ</title>
    </head>
    <body>
        <div>
            <!-- 既存コード -->
        </div>
        <div id="my-vue-component">
            <other-component />
        </div>

        
        <script
            src="https://code.jquery.com/jquery-3.6.0.min.js"
            integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
            crossorigin="anonymous"
        ></script>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
        <script>
            $(document).ready(() => {
                ...既存コード
            });

            Vue.component('other-component', {
                data() { ... },
                template: '...'
            });
    
            new Vue({
                el: '#my-vue-component',
                template: '...',
                data() { ... },
                methods; { ... }
            });
        </script>
    </body>
</html>


では、早速始めましょう!

前提条件

Node.js - npmからVueやwebpackなどをダウンロードするため、Vueのシングル・ファイル・コンポーネントはそのままJavaScriptに使うことができないため、コンパイルする必要があります。

シングル・ファイル・コンポーネント(Single-File Component)

<template>
    <button>
        <other-component />
        <slot />
    </button>
</templaet>

<script>
import OtherComponent from './OtherComponent.vue';

export default {
    component: {
        OtherComponent
    },
    data() {
        return { ... };
    },
    methods: { ... }
};
</script>

<style scoped>
button {
    padding: 1rem 2rem;
}
</style>

Vueのシングル・ファイル・コンポーネントは基本的に.vueという拡張子が付いています。この.vueファイルにはHTML、JavaScriptCSSをまとめてバンドルすることができます。Vueでシングル・ページ・アプリケーション(SPA)を作ったことがある人には見慣れたコードになると思います。このファイルはSPAを作るときの.vueファイルと全く同じのため、他のコンポーネントやライブラリーをインポートすることはできますし、JavaScriptの代わりにTypeScriptを使うこともできますし、SASSなどを使うこともできます。

ローダーのスクリプト

先ほど作ったSFCを使えるために、ローダースクリプトを作ります。ローダースクリプトはVueコンポネントをアプリケーションにマウントさせるためのスクリプトになります。これがないとSFCを使用できません。

import Vue from "vue"; 
import MyComponent from "../components/MyComponent.vue";

const el = document.querySelector('#some-element'); 
new Vue(MyComponent).$mount(el);

VueでSPAを開発したことがある方は.vueファイルのようにこれも見慣れたコードになっていると思います。Vueのシングル・ページ・アプリケーションのindex.jsに書かれているものと同じです。ここで何をやっているのかというと、まずVueとプロジェクトに使いたいコンポーネントをインポートします。そして、new Vue(MyComponent)で新しいVueのインスタンスを作り、コンポーネントをパラメータとして渡します。それから、.$mount(el)でアプリケーション内の好きな場所にマウントします。

コンパイル

コンポーネントとローダースクリプトを完成したら、コンパイルする必要があります。コンパイルするためにはNode.jsが必要です。Node.jsはまだインストールしていない方には先にインストールしてください。Node.jsをインストールした後次へ進んでください。

Nodeで既に開発している場合

もしNodeですでに開発をしている場合はnpmから必要なパッケージのみインストールしてください。自分のプロジェクトにすでにインストールされているパッケージはインストールしなくていいです。プロジェクトにインストール済みのパッケージはpackage.jsonに確認できます。


まずは、vuevue-loadervue-template-compilerをインストールします。

npm install -D vue vue-loader vue-template-compiler


次はwebpackをインストールします。

npm install -D webpack webpack-cli


最後は.vueの中にあるCSSなどのためのローダーをインストールします。

npm install -D @babel/core babel-loader css-loader vue-style-loader

今回はシンプルにしたいため、SASSなどを使わないですが、もしSASSが必要であればsass-loaderなどをインストールする必要があります。


次は、webpack.config.jsを修正します。


webpackが使われていないプロジェクトにはこのファイルが存在していない可能性あります。であれば、プロジェクトのrootwebpack.config.jsのファイルを作成してください。

const { dirname } = require("path");
const VueLoaderPlugin = require("vue-loader/lib/plugin");

module.exports = {
  entry: {
    "favorite-cat": "./vue/loaders/favoriteCatLoader.js",
  },
  output: {
    filename: "bundle.js",
    path: __dirname,
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: "vue-loader",
      },
      {
        test: /\.js$/,
        loader: "babel-loader",
      },
      {
        test: /\.css$/,
        use: ["vue-style-loader", "css-loader"],
      },
    ],
  },
  plugins: [
    new VueLoaderPlugin(),
  ],
};

webpack.config.js確認

  1. webpack.config.jsはすでにあるプロジェクトには上記の内容が自分のwebpackコンフィグに存在しているかどうか確認してください。
  2. module.exportsmodule.ruleの順番が大事なので、webpack.config.jsを修正するときに注意をしてください。


新しいコンポーネントやローダースクリプトを追加するときに、module.exportsentryに追加しなければなりません。

module.exports = {
  entry: {
    "comp1": "./loaders/ComponentLoader1.js", 
    "comp2": "./loaders/ComponentLoader2.js",
    "comp3": "./loaders/ComponentLoader3.js",
  },
 ...
}

プロジェクトのrootpackage.jsonを開いて、下記を追加してください。

"scripts": {
    "build": "webpack --config webpack.config.js --mode development"
},


プロジェクトに初めてNodeを使った場合にはwebpack.config.jsみたいにpackage.jsonも存在していない可能性があります。その場合は、下記を実行し、プロジェクト情報を入力してください。

npm init

そのあとは上記のpackage.jsonファイルの編集を行ってください。


最後にはビルドをします。

npm run build


上記のコマンドを実行したら、プロジェクトのrootbundle.jsが生成されます。そのbundle.jsをHTMLの中にインクルードします。

<html>
    <body>
        ...
        <script src="bundle.js" defer></script>
    </body>
</html>


そのあと、HTMLにコンポーネントのマウント先を作ります。
ロードスクリプト#some-elementコンポーネントをマウントしようとしているため、<div id="some-element"></div>を追加すれば、Vueコンポーネントはこのdivの中にマウントされます。

まとめ

自分のプロジェクトはVueのシングル・ページ・アプリケーションではなくてもVueのシングル・ファイル・コンポーネントを使えます。上記でいろいろやりましたが結局3つのステップで済むことができます。

1. Vueコンポーネントを作成
2. ローダースクリプトを作成
3. ビルド

今までのスパゲッティコードを何とかしたいけど、今のプロジェクトをSPAに書き換えることができない人は是非やってみてください!


株式会社フォトラクションでは一緒に働く仲間を募集しています
corporate.photoruction.com
www.wantedly.com