Wiz テックブログ

Wizは、最新のIoTやICTサービスをお客様に届ける「ITの総合商社」です。

E2Eテストの取り組みについて

はじめまして、フロントエンドエンジニアの菅野です。

今回は、E2Eテスト自動化の取り組みについてお話ししたいと思います。  

E2Eテストとは

End to Endを略してE2Eと呼ばれています。

例えば、

  • CV(コンバージョン)ポイントやログイン機能の動作確認
  • VRT(ビジュアルレグレッションテスト)

など、システム全体が正しく動作するかを確認するものです。

なぜE2Eテストを導入するのかというと、以下のような目的とメリットが挙げられます。

リリース時の確認コストの削減と品質担保

LPや2P~3Pといった小規模なサイトだと確認コストはそんなにかかりませんが、中〜大規模になると人の手で一つ一つ確認していくと時間と手間がかかりとても大変です。

そこで人が手を動かさずに各ページのUIや挙動をチェックすることができればコスト削減が見込まれます。

また、例えばリリース後に表示崩れが起きていたとします。

これまでだとリリースしてから5日後に気づいていたのが、リリース時にテストを実行することで1〜2時間といった短時間で発見でき、品質担保としても有効な手段となります。  

ツールの選定

E2Eテストツールはいくつかあり、

はよく耳にするのではないでしょうか。

他にはマイクロソフト製のPlaywrightというライブラリが2020年5月にリリースされています。

そんな様々なツールがある中で今回選んだのが「TestCafe」です。  

TestCafeとは

アメリカのDeveloper Express Inc.という企業が開発しているE2Eテストツールで、ブラウザテストを自動化するためのフレームワークです。

2016年にリリースされており、比較的新しいツールといえます。

特徴

  • async/awaitの仕様を前提にAPI設計がされている
  • TypeScriptサポート
    • 通常のJSだけでなくTypeScriptで記述したテストコードをそのまま実行できる
  • 構築が簡単
    • SeleniumではWebDriverのクライアントとテストを実行する各ブラウザのWebDriverのインストールが必要だが、TestCafeはnpmでTestCafeをインストールするだけでOK。設定ファイルも必要なくテスト環境が整う。
  • 非WebDriver依存
    • 一昔前のE2Eテストツールは、各種ブラウザベンダ間の差異を吸収し、抽象化して操作するためにWebDriverを使うのが常識でしたが、現在はブラウザ側がサポートするようになり、テストツール側が意識しなくてよくなった。TestCafeもこれを前提に設計されている。
  • BDD(ビヘイベア駆動開発)に則ったテストコード
    • UIテスト手順をメソッドチェーン形式で記述。これにより、ユーザー操作や外部仕様をまるで自然言語のようにコードで表現できる。つまり、テストコードがそのままテスト仕様書となる。
  • サポートブラウザが豊富
  • TestCafeだけでなく、Node.jsすらインストールされていない環境であっても、テストを実行することが可能
    • その場合、TestCafeが出力するURLを対象の環境のブラウザで開くだけでテストが開始される。ただし、TestCafeがインストールされているホストと対象とするデバイスが同一ネットワーク上に存在する必要がある。
  • BrowserStackとの連携をサポート
    • E2Eテストの実行環境は開発マシンとは別に用意しておくことが望ましい。そうすることで開発(実装)と並行してテストを実行しやすくなる。

以上の特徴があり、

  • サポートブラウザが豊富
  • 構築が簡単
  • async/awaitとを含む最新のJS機能とTSをサポート

が大きな選定理由となります(あとTestCafeっていう名前が可愛かった)

テスト項目

  • VRTテスト
  • CVポイント(フォーム)の基本動作確認
  • metaやOGPの取得
  • マークアップチェック

この4項目のテストを行います。

VRTテスト

VRTとは、画像回帰テストと呼ばれており、画面のスクリーンショットをリリース前後で比較することで表示崩れを確認することができるテストです。

TestCafeとreg-cli*1を組み合わせて実装していきます。

  1. まずはTestCafeを使って、指定するページのスクリーンショットを撮影します。
  2. reg-cliを使って差分比較を行います。

reg-cliで生成されたHTMLを見てみると reg-cli

このように差分を確認できるようになります。

おまけ

スクリーンショットが複数枚ある場合は、それぞれを連結させて1枚の画像にすると1枚1枚開いて確認する手間が省けるのでおすすめです。

sharpという画像編集ライブラリを使うと実装できます。

スクリーンショット連結

CVポイント(フォーム)の基本動作確認

フォームが入力〜送信まで問題なく動作するかをチェックします。

バリデーションや様々なパターンを想定してテストが実行できると良いですが、テストケースがかなりのボリュームになり、コストがかかり過ぎてしまう可能性もあるので、どこに重点を置くかを決めてテストケースを絞るのが現実的かなあと思います。

fixture('FormTest Start');
  .page('https://example.com');
  test('必須項目を入力し送信', async (t: TestController) => {
    const dataTarget = await Selector('[data-target-input]');
    const name = dataTarget.withAttribute('name', 'name');
    const mail = dataTarget.withAttribute('name', 'email');
    const phone = dataTarget.withAttribute('name', 'phone');
    const submitBtn = await Selector("button");

    await t
      .typeText(name, 'テスト名前')
      .typeText(mail, 'test_sample@gmail.com')
      .typeText(phone, '0312345678')
      .click(submitBtn.withExactText('送信'))
}); 

   このように直感的に書けるので分かりやすいのではないでしょうか。  

metaやOGPの取得

ページを一つ一つ開き、デベロッパーツールや拡張機能を使ってmeta情報を確認するのはとても面倒です。

スクリーンショットを撮るタイミングで各ページのmeta情報を取得し、jsonに吐き出すことで確認コストを削減します。

og:imageは外部のOGP確認ツールにアクセスし、スクリーンショットを撮影します。

テキスト情報だけでなくog:imageを視覚的に確認できるようにしています。  

{
 "meta": [
  {
   "page": "/",
   "title": [
    {
     "text": "株式会社Sample",
     "最大29文字程度": true
    }
   ],
     "description": [
    {
     "text": "株式会社Sampleのdescriptionが入ります。",
     "最大110字程度": true
    }
   ],
   "keyword": [
    {
     "text": "株式会社Sample,サンプル,sample,北海道,東京,大阪,福岡",
     "5〜6個程度": false
    }
   ],
   "og:title": "株式会社Sample",
   "og:url": "https://example.com/",
   "og:image": "https://example.com/img/ogp.png?1603865417442",
   "og:site_name": "株式会社Sample",
   "og:description": "株式会社Sampleのog:descriptionが入ります。",
   "canonical": "",
   "robots": null
  }
 ]
}

ogp確認スクリーンショット

マークアップチェック

テスト実行時にチェック用のCSSを挿入し、スタイルが当たった状態のスクリーンショットを撮影してマークアップチェックを行います。 ディレクターやデザイナーはソースコードをあまり見慣れていないため、視覚的に確認できるようにすることで、マークアップについてもチーム全体で意識を持ち、品質担保を目指すことができます。

markupチェック

  • ul,olの子要素にli以外のタグが入っている
  • dlの子要素にdt,dd,div以外のタグが入っている
  • imgタグのaltがないもしくは空
  • リンクにname属性もしくはhref属性にjavascriptが使われている
  • target="_blank"がついている場合にrel="noopener"

といった項目がチェックできるようになっています。


以上、4つの項目のテストを実行し、チェックを行っています。

実案件での使い方

コーポレートサイトと新卒採用サイトでは新規コンテンツ制作時や複数ページに及ぶ修正が発生した際に必要なテストを実行し、結果をSlackでプロジェクトチームに共有して確認を行っています。 最近だとmetaを変更したのでjsonを共有して確認に使用してもらいました。

slack_共有

今後やりたいこと

Qiitaに詳しい実装方法は書いており、それを参考にWiz cloudにも導入してもらっていますが、他の案件にもスムーズに取り入れてもらえるようドキュメントを鋭意制作中です。

これで完成ではなく、アップデートして継続できるE2Eテストにしていけたらと思います!

最後に

Wizではエンジニアを募集中です!

興味のある方、ぜひご覧下さい。

careers.012grp.co.jp

*1:VRTのためのコマンドラインインターフェイスです。 画像は別途用意する必要がありますが、アサートする画像を指定するだけで現在の画像と以前の画像を比較し、差分のHTMLを作成してくれます。

Gatsby v3リリース 差分ビルド検証

先日、(2021年3月3日) Gatsby v3.0がリリースされました。 Introducing Gatsby 3.0 – Faster in Every Way that Matters

いくつかの変更がありますが、特に気になった項目が

V3 for Content Editors: Faster build times on any service

(あらゆるサービスでのビルド時間の短縮) です。

Faster build times on any service

項目を大胆に丸々引用します。

Last year Gatsby introduced a breakthrough in static site generation with Incremental Builds. Instead of a content update kicking off a full rebuild of your entire site, we enabled a new feature that only updated pages that had new content to display. This dropped build times for sites from multiple minutes to under 10 seconds in many cases. Content editors were especially excited. With Incremental Builds, a Gatsby project now enabled the same rapid workflow and seamless feedback loop as the all-in-one CMSs they were familiar with using. An editor could fix or add content to a page and see change live in less than a minute. However, Incremental Builds was initially only available in Gatsby Cloud. We heard from the community that you wanted this key feature to be enabled in Gatsby open source, so the content editors you support could enjoy fast builds no matter what CI/CD service you choose. Today, with Gatsby v3 we’re thrilled that Gatsby open-source now has Incremental Builds enabled by default, anywhere you decide to run your project!

日本語訳です。

昨年、ギャツビーはインクリメンタルビルドによる静的サイト生成のブレークスルーを導入しました。 コンテンツの更新によってサイト全体の完全な再構築が開始される代わりに、新しいコンテンツが表示されるページのみを更新する新機能が有効になりました。 これにより、多くの場合、サイトのビルド時間が数分から10秒未満に短縮されました。

SSGといえば、変更が一箇所だけであってもプロジェクト全体をビルドしないといけないので、 どうしても再構築に時間がかかっていました。
これは画期的な機能です。

コンテンツ編集者は特に興奮していました。インクリメンタルビルドにより、Gatsbyプロジェクトは、使い慣れたオールインワンCMSと同じ迅速なワークフローとシームレスなフィードバックループを可能にしました。編集者は、ページにコンテンツを修正または追加して、変更を1分以内にライブで確認できます。

その通りですね。データ変更が多いプロジェクトであればあるほどこの機能は素晴らしいものになります。

ただし、インクリメンタルビルドは当初GatsbyCloudでのみ利用可能でした。コミュニティから、この重要な機能をGatsbyオープンソースで有効にして、サポートするコンテンツエディターが、選択したCI / CDサービスに関係なく高速ビルドを楽しめるようにしたいとのことでした。

インクリメンタルビルド機能は私も実際にプロダクトに導入したかったのですが、 GatsbyCloudという有料プランでしかサポートされておらず(一部無料プランもあり)、断念していました。

今日、Gatsby v3では、Gatsbyオープンソースで、プロジェクトを実行することにした場所で、デフォルトでインクリメンタルビルドが有効になっていることに興奮しています。

つまり、その素敵なインクリメンタルビルド機能オープンソースGatsbyで無料で使えるようになった!!
ということです。これはすごい!!

検証

本当に私が想像していた(待ち望んでいた)差分ビルドなのでしょうか。
試してみるのが一番ですね。

Gatsbyプロジェクトの準備

検証用にGatsby + Contentful + Netlifyでサクッとアプリを作成しました。 参照: JAMstack Gatsby + Netlify + Contentfulの構成を試してみた

インクリメンタルビルドの為の各種設定

Netlifyにプラグインを追加します。 参照: 【Netlify x Gatsby.js】ビルド時間を短縮!差分だけビルドする機能(Incremental Builds)を導入するテスト!

Netlify上でPluginsを選択し、Gatsby cacheをインストールします。

f:id:iricocco:20210304201453p:plain
Netlify

また、package.jsonnpm run build--log-pagesというオプションを追加します。
これによって、どのページがアップデートされたのかがログで吐き出されるようになります。

  "scripts": {
    "develop": "gatsby develop",
    "start": "gatsby develop",
    -"build": "gatsby build",
    +"build": "gatsby build --log-pages",
    "serve": "gatsby serve",
    "clean": "gatsby clean"
  },

そして、contentfulなどで情報を更新してみてください。
今回トップページのみに影響のある範囲のデータを編集したところ、 トップのみが更新されているのがわかるかと思います。
404ページなどは更新されていません!! f:id:iricocco:20210304201722p:plain 期待する挙動が得られています。

一体どういう仕組みなのか

www.gatsbyjs.com

HTML生成時に、入力しているものをトラックしている、と書かれています。 主な追跡対象は以下です。
・どのテンプレートが使われているか
・ページクエリの結果
・ページテンプレートで使用されている静的クエリの結果
・フロントソースコード
このトラックに紐づくコードに変化があった時、そのHTMLを更新するという仕組みのようです。

上記で示した例は簡易的なリポジトリでしたが、ページ数が多いプロダクトでは、build時間が激変すること間違いなしです。

懸念点

検証していないのでまだ確かではありませんが、VercelでGatsbyのこの機能が使えるか怪しい...と思っています。

Gatsby Incremental builds · Discussion #5001 · vercel/vercel · GitHub

少し前ですが、このようなissueが挙げられていました。
VercelはNext.jsと同じチームなので、手厚くGatsbyをサポートするのはなかなか難しいのかな、と思ったり...
今後時間を作って調べてみたいです。

現在Wizでは一部プロダクトにNext.jsが使われていますが、更新の頻繁なサイト、ページ数の多いサイトにはGatsbyという選択肢もありかも、と今回のアップデートで思いました。

最後に

Wizではエンジニアを募集しております。 興味のある方、ぜひご覧下さい。

careers.012grp.co.jp

AOP、Laravelのライブラリ紹介

AOPとは

AOPAspect Oriented Programming)とは、コンピュータプログラムの特定の振る舞いを「アスペクト」と呼ばれる機能単位として分離して記述し、プログラム中の様々な対象に適用出来るようにする手法です。既存のオブジェクト指向プログラミング言語や開発環境に補助的に投入されることが多いです。

背景

オブジェクト指向プログラミングでは、お互いに関連するデータ(属性)とそれらに対する操作の集合でオブジェクトをプログラムの基礎単位として記述して行きますが、ロギング(Logging)のような様々なオブジェクトで共通して現れますが単一のオブジェクトやメソッドなどとして切り出して定義することが出来ないような横断的な機能(横断的関心事)が存在する場合があります。

例えばissueBookとreturnBookの2つのメソッドをもつクラスLibraryServiceの例を見てみましょう。仕様としては、パラメーターと返却値をログに記録することです。ここで、ロギングは、アプリケーションに実装したい横断的関心事です。

<?php
class LibraryService {
    public function issueBook(int $memberID, int $bookID): bool {
        \Log::info("Executing method issueBook($memberID, $bookID) of LibraryService");
        
        $status = false;
        
        // Business logic to issue a book from Library
        \Log::info("Returning from method issueBook of LibraryService : $status");
        
        return $status;
    }
    public function returnBook(int $memberID, int $bookID): bool {
        \Log::info("Executing method returnBook($memberID, $bookID) of LibraryService");
        
        $status = false;
        
        // Business logic to return the issues book
        \Log::info("Returning from method returnBook of LibraryService : $status");
        
        return $status;
    }
}

ここで、ライブラリに新しい本を追加する必要があるため、LibraryServiceに別のメソッドaddBookを記述します。メソッドaddBookを作成するときは、パラメータと返却値をログに記録する必要があります。したがって、addBookメソッドのコードは次のようになります。

<?php
    public function addBook(int $bookID): bool {
        \Log::info("Executing method addBook($bookID) of LibraryService");

        $status = false;
        // Business logic to return the issues book

        \Log::info("Returning from method addBook of LibraryService : $status");
        
        return $status;
    }

上記のような従来のアプローチの欠点:

  • パラメーターと返却値をログに記録する同様のロジックは、複数のメソッドに分散されているため、冗長なコードが作成されます。これにより、メンテナンスが非常に困難になります。
  • アプリケーションロギングの要件を変更すると、LibraryServiceの複数のメソッドのコードが変更されます。
  • LibraryServiceに新しいメソッドを追加すると、新しく追加されたメソッドでログコードが再度書き換えられます。したがって、既存のロギングロジックを再利用することはできません。
  • LibraryServiceの主な責任は、ロギングではなく、ライブラリのさまざまな操作を提供することです。LibraryServiceにロギングするコードを保持することはお勧めできません。

AOPは、上記の全ての欠点を克服するアプリケーションのロギングの関心(Concern)(および他のすべての横断的関心事)を実装するのに役立ちます。AOPは、横断的関心事をアプリケーションの主要なビジネスロジックから分離し、さまざまなアプリケーションオブジェクトに適切に織り込みます。

横断的関心事(Cross Cutting Concerns)

どのエンタープライズアプリケーションでも、主要なビジネスロジックに加えて、対処する必要のある多くの関心事項があります。これらの関心は、アプリケーション全体および複数のアプリケーション層に広がっています。このような関心事項は、ロギング、トランザクション処理、パフォーマンスモニタリング、セキュリティなどがあります。これらの関心事項は、アプリケーションの横断的関心事として知られています。

f:id:FattyRabbit:20210226171047p:plain

AOPは、アプリケーションの横断的関心事を実装して、それらをメインのビジネスロジックから分離し、その結果、アプリケーションが疎結合になるようにします。

用語

Aspectアスペクト

アスペクトとは、ロギング、パフォーマンス監視、トランザクション処理など、アプリケーションに実装したい関心(横断的関心事)のことです。

Advice(アドバイス

アドバイスは、アスペクトの実際の実装です。アスペクトは概念であり、アドバイスは概念の具体的な実装です。

Join Point(ジョインポイント)

ジョインポイントは、アスペクトを適用することができるプログラムの実行中の位置やタイミングです。メソッドの実行前/実行後、例外をスローする前、インスタンス変数を変更する前/後などです。

Point cut(ポイントカット)

ポイントカットは、アスペクトが適用される結合ポイントを示します。アドバイスはポイントカット式に関連付けられ、ポイントカット式に一致する結合ポイントに適用されます。

その他

Target、Proxy、Weaving

Laravelのライブラリ

Laravelでよく使っているのが以下の物です。

github.com

PHPフレームワークのBEAR.Sundayのパッケージの一つであるRay.AOPをLaravel向けにラッパーしたライブラリです。Ray.AOPはLaravel以外でも利用可能です。

TransactionalやLogExceptions等既に使えるモジュールもあるし、新たにAOPのモジュールを追加することも可能です。

個人的な印象

個人的にはJavaのSpringBootで初めてAOPを経験したので、Laravel(Php)のPointCutの設定方法の違いを感じました。

Laravel-Aspectでは新しくアスペクトを作成する時もアノテーションを作成してそのアノテーションを対象になるクラスやメソッドに付け、インターセプター(MethodInterceptor)が取得しジョインポイントやポイントカットを判断する方法をとっています。

qiita.com

ですが、SpringBootではアスペクトにジョインポイントやポイントカット定義をアスペクトのメソッドにアノテーションで定義しています。

qiita.com

Laravelの機能との差

Laravelと似ている所は特定の層やイベントに限っていることでAOPとは差があります。

Middleware

LaravelのMiddlewareはControllerに利用させるためにHTTPリクエストに対して処理を追加する

Listener, Observer, Subscriber

特定のイベントを捕捉する仕組み

まとめ

AOPは以下の理由と利点があります。

  • 補助的に投入することで主要なビジネスロジックと分離
  • アプリケーション層に関係なく使用

最後に

Wizではエンジニアを募集しております。 興味のある方、ぜひご覧下さい。

careers.012grp.co.jp

GatsbyJsでWordPressをHeadless CMSとしてサイト構築deployまで試してみました。

f:id:thunder_fury:20210226181958p:plain

はじめに

皆さんこんにちは、フロントエンドエンジニアのWooです。
GatsbyJsでWordPressをHeadless CMSとして使用した構築方法や個人的に考えたメリットやデメリットをお話ししたいと思います。

WordPressのメリットとしてはサイト構築が楽でプラグインインストールで実装も簡単にできる便利なツールですが、サイトが多少重くてセキュリティ面でも不正な操作や攻撃を受けやすいのでバージョン管理やプラグインのバージョン管理などが大変です。

GatsbyJsで構築をするとWordPressのバージョン管理は行わなくて良くて、サイトもSSG(Static Site Generator)仕様なので非常に早いサイトを構築することができます。

WordPressが構築されている前提で、進めていきたいと思います。

GatsbyJsとは何か

GatsbyJsはReactベースの静的サイトジェネレーターです。
WordPressは、記事の「閲覧時」に動的にサイト内容が生成されますが、GatsbyJsは「ビルド時」にHTMLやCSSなどがあらかじめ生成されていることが特徴で、WordPressと比べてビルド時にhtmlを用意しているのでサイトが非常に早くなるメリットがあります。つまり、SSG(Static Site Generator) 仕様ということです。

GatsbyJs公式サイトは速度だけではなくサイトのセキュリティ補完もできると書かれています。 www.gatsbyjs.com

Security by default
Gatsby’s serverless rendering generates static HTML at build time. No server and no reachable database equals no malicious requests, DDOS attacks, or accidental exposure. A Gatsby site’s attack surface is nonexistent.

上記の内容を翻訳した内容です。

デフォルトのセキュリティ
Gatsbyのサーバーレスレンダリングは、ビルド時に静的HTMLを生成します。サーバーや到達可能なデータベースがないことは、悪意のある要求、DDOS攻撃、または偶発的な露出がないことを意味します。Gatsbyサイトの攻撃対象領域は存在しません。

WordPressのセキュリティの改善もできそうです。

GatsbyJs導入install

$ npx gatsby-cli gatsby new [project名]

ローカルサーバー起動

$ cd project名
$ gatsby develop

無事ローカルサーバーが起動できました。 f:id:thunder_fury:20210226123304p:plain

ローカルサーバーが立ち上がったところでページのレンダリングを確認をしてみると、GatsbyJsはマウスホバーをする時点でプリフェッチ (prefetch)と呼ばれる処理が走り、ページのdataが先に通信されるので早いなあと思いました。🤔

f:id:thunder_fury:20210226133314g:plain

WordPressと連動

GatsbyJsにはいろんなプラグインが存在していてWordPressと繋ぐのはgatsby-source-wordpressが一番簡単だったので自分はgatsby-source-wordpressをインストールしました。

$ npm i gatsby-source-wordpress

インストールが終わりましたらgatsby-config.jsに設定する必要があります。

module.exports = {
plugins: [
 ...省略...
  {
      resolve: `gatsby-source-wordpress`,
      options: {
        baseUrl: `〇〇〇〇.com`, // ワードプレスURL
        protocol: `https`,
        hostingWPCOM: false,
        useACF: true,
        // fetchしたいcontent
        includedRoutes: [
          "**/posts",
          "**/media",
        ],
      },
    },
 ...省略...
 ]
}

今回はpostsとmediaだけフェッチを行い、titleとアイキャッチの画像を取得したいと思います。 他にも習得できるkeyは存在しております。

  • "**/categories" カテゴリー
  • "**/pages" 固定ページ
  • "**/tags" タグ
  • "**/users" ユーザー情報(記事を書いた人の情報など)

GraphiQLからシミュレーションをしてみたらWordPressの最初の記事Hello Worldが取得されているのが分かります。

f:id:thunder_fury:20210227144451p:plain

GatsbyJs側の処理

config設定

const Promise = require("bluebird")
const { resolve } = require("path")
const path = require(`path`)

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions
  return new Promise((resolve, reject) => {
    const wpPosts = path.resolve("./src/templates/blog-post.js")
    resolve(
      graphql(`
        {
          allWordpressPost(sort: { fields: [date] }) {
            edges {
              node {
                slug
              }
            }
          }
        }
      `).then(result => {
        if (result.errors) {
          reject(result.errors)
        }
       const posts = result.data.allWordpressPost.edges
       // { node }で記載のgraphqlデータを習得することができます。
        posts.forEach(({ node }) => {
          createPage({
            path: node.slug,
            component: path.resolve(`./src/templates/blog-post.js`),
            context: {
              slug: node.slug,
            },
          })
        })
      })
    )
  })
}

記事一覧ページ

記事リストを展開表示する処理は下記です。 自分はtopに表示したかったのでpages/index.jsに記載をしました。 もし、別ページにしたい場合はディレクトリーのpagesの中にファイルを追加して別ページに記載することも可能です。

import React from "react"
import { Link, graphql } from "gatsby"
import Layout from "../components/layout"
import SEO from "../components/seo"

export const Index = ({
  data
})  => {
  const posts = data.allWordpressPost.edges
  return (
    <Layout>
      <SEO title="home" />
      <h1>My WordPress Blog</h1>
      <h4>Posts</h4>
      <ul>
        {posts.map((post, index) => {
          return (
            <li key={post.node.slug}>
              <img src={post.node.featured_media.source_url} alt="thunder fury"/>
              <Link to={post.node.slug}>{post.node.title}</Link>
            </li>
         )})}
      </ul>
    </Layout>
  )
}

export const pageQuery = graphql`
  query {
    allWordpressPost {
      edges {
        node {
          title
          slug
          featured_media {
            source_url
            title
          }
        }
      }
    }
  }
`
export default Index

f:id:thunder_fury:20210301121433p:plain

記事テンプレート作成

import React from "react"
import Layout from "../components/layout"
import { graphql } from "gatsby"
import styled from "styled-components"

export default ({ data }) => {
  const post = data.allWordpressPost.edges[0].node
  return (
    <Layout>
      <div>
        <h1>{post.title}</h1>
        <Img src={post.featured_media.source_url} alt="thunder fury" />
      </div>
      <div dangerouslySetInnerHTML={{ __html: post.content }} />
    </Layout>
  )
}
export const query = graphql`
  query($slug: String!) {
    allWordpressPost(filter: { slug: { eq: $slug } }) { 
      edges {
        node {
          title
          slug
          content
          featured_media {
            source_url
            title
          }
        }
      }
    }
  }
`

記事ページも問題なく表示されました。

f:id:thunder_fury:20210227145735p:plain

NetlifyでDeploy

f:id:thunder_fury:20210301131500p:plain

Netlifyとは何か

Netlifyは静的なページを無料で作成し、Deployすることができるホスティングサービスです。

特徴としてはHTTPSを提供し、GitHubの特定Repoの特定のブランチがPushされるたびに自動的にビルドのデプロイを行ってくれるという点です。

無料枠としては1チームまで毎月300回Deployができて同時ビルドは一人しかできませんが個人であれば十分使えると思いました。

デプロイ手順

  1. Netlifyに加入する。
  2. GitHub、GitLab、Bitbucketの中から接続するサービスを選択。
  3. 選択したサービスの特定のRepoを選択。
  4. 選択したRepoのBranchを選択。
  5. ビルドスクリプト(例gatsby build)を入力。
  6. 作成されたフォルダ(例/public)を入力。
  7. ビルドとデプロイの実行を見守る。

参考イメージ

f:id:thunder_fury:20210301124130p:plain

f:id:thunder_fury:20210301124647p:plain

f:id:thunder_fury:20210301124627p:plain

3ステップで簡単にDeployができます。

まとめ

WordPressをHeadless CMSとして使えるか試しに環境構築をしてみました。

GatsbyJsはWordPressと簡単に繋げることができ、WordPressのデメリットをGatsbyJsが補完してくれるため、編集者はいつも通りWordPressで管理が出来るようになります。

フロントエンドエンジニアはビューの開発に集中できる印象を受けました。

記事の検索や関連記事表示のサイトの機能は全部自分で用意をしないといけませんが、サイトのパフォーマンスがよくなるので一度チャレンジしてもありかと思いました。


最後になりますが、Wizではエンジニアを募集中です!

色んな案件の経験ができるので興味のある方は是非覗いてみてください↓

careers.012grp.co.jp

gitでpushする前にコミットを整理する

こんにちは。バックエンドエンジニアの河内です。

今回は、コミットを整理する方法のうち、個人的に使用頻度が高いものについて書きます。

前提方針

コミットログを整えるために編集を加えるのは、ローカルリポジトリのコミットだけとします。 逆に言うと、リモートリポジトリにpushされたコミットについては編集を加えないということです。

たとえば、以下リモートリポジトリで(C)が最新の場合、 ローカルリポジトリで編集してよいのは(d)と(e)です。

[リモートリポジトリ]

※ 行頭の(A)などの識別子は説明のため加えており、実際には表示されません

(C) 32096c2 コミットC
(B) ae4f281 コミットB
(A) 6dcd4ce コミットA

[自分のローカルリポジトリ

(e) 58e6b3a コミットe ← 編集してもよい
(d) 3c36383 コミットd ← 編集してもよい
(C) 32096c2 コミットC
(B) ae4f281 コミットB
(A) 6dcd4ce コミットA

各行頭の識別子に関し、ローカルのコミットログについてはアルファベット小文字で表現しました。 後述の事例でも区別のため、そのルールで表記します。

よくある事例とその対処

最新のコミットに対して

(1) 最新のコミットのメッセージを間違えた

以下のコミットログを見てみると…「官僚」ではなく「完了」のような気がします。

(d)はローカルリポジトリのコミットなのでまだ間に合います。

git log --oneline

(d) ee17560 事例1用管理画面実装官僚
(C) 32096c2 コミットC
(B) ae4f281 コミットB
(A) 6dcd4ce コミットA

[対処]

git commit --amend

エディタが開くので、メッセージを「官僚」→「完了」と編集し、保存します。

事例1管理画面実装官僚

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#

:

修正できました。

ハッシュ値は変わります。既存コミットは上書き保存され、別物になりました。

git log --oneline

(d) 03a9339 事例1用管理画面実装完了
(C) 32096c2 コミットC
(B) ae4f281 コミットB
(A) 6dcd4ce コミットA

前提方針でリモートリポジトリにpushされたコミットに編集を加えない、としたのは、このようにコミットが上書き保存される操作のためです。

上書きしたコミットを再pushした場合、上書きされる前のコミットをすでにローカルリポジトリに取り込んでいた別の作業者がいたら不整合が発生するので、なんらかのすり合わせ作業が必要となってしまいます。

次の事例に進みます。

(2) 現在の変更点を最新のコミットに含めたかった

git log --oneline

(d) ce9ed66 事例2用管理画面実装完了
(C) 32096c2 コミットC
(B) ae4f281 コミットB
(A) 6dcd4ce コミットA

(d)のコミットのあとindex.phpを編集したが、この内容は(d)に含めたかった…とします。

[対処]

git add index.php
git commit --amend

まず、index.phpをインデックスに登録します。

git add index.php

そして、git commit --amendです。

すると、addした内容が(d)のコミットに含まれる形でコミットログの編集を求められます。 メッセージはこのままでよいので編集せずに保存。

事例2用管理画面実装完了

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#

:

コミットを増やさず保存できました。

git log --oneline

(d) 5d75642 事例2用管理画面実装完了
(C) 32096c2 コミットC
(B) ae4f281 コミットB
(A) 6dcd4ce コミットA

ちなみに、(1)と(2)が同時に起こった場合、(2)でメッセージ編集をすればよいわけなので1回のgit commit --amendでいけますね。

最新のコミットより前のコミットに対して

(3) 最新のコミットの1つ前のコミットのメッセージを間違えた

(1)、(2)は最新のコミットに対しての話でしたが、それより前のコミットとなると別のアプローチをとる必要があります。

今回は、(d)のコミットメッセージを間違えているようです。

git log --oneline

(e) 0e647f2 リファクタ
(d) 7cfd024 事例3用管理画面実装官僚
(C) 32096c2 コミットC
(B) ae4f281 コミットB
(A) 6dcd4ce コミットA

[対処]

git rebase -i 32096c2 ※ 「r, reword」利用

git rebaseを使います。

git rebaseには他のブランチを巻き込む編集も存在しますが、今回は現行のブランチだけを対象とし過去のコミットに対してまとめて編集を加える、-i (--interactive)オプションを使います。

引数には、編集対象の1つ前のコミットを指定します。 今回は(d)の直前の(C)なので、ハッシュ値「32096c2」を指定しました*1

すると、以下のように表示されます。git logの順と違い、上から古い順である(d)、(e)の順で表示されます。

よく見ると、コメント部の「Commands:」にできることが書いています。 今回したいことは、コミットメッセージの編集なので、これには「r, reword」を使います。

(d) pick 7cfd024 事例3用管理画面実装官僚
(e) pick 0e647f2 リファクタ

# Rebase 32096c2..0e647f2 onto 32096c2 (2 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified). Use -c <commit> to reword the commit message.
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

該当コミットの「pick」を「r」もしくは「reword」に置き換えます*2。 今回は短い「r」を使用します。置き換えたら保存します。

(d) r 7cfd024 事例3用管理画面実装官僚
(e) pick 0e647f2 リファクタ

:

すると、そのコミットログの編集を求められます。(1)の時と同様、メッセージ編集〜保存すると反映されます。

事例3用管理画面実装官僚

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#

:

(d)のハッシュ値のほかに、内容としては何も変更のなかったはずの(e)のハッシュ値も変更されています。 対象コミットの後続のコミットすべてのコミットについて、このように変更がなされます。

逆に、「(d)以降」を指定するためにgit rebase -iのオプションに(C)のハッシュ値を渡しましたが、(C)に影響はありません。

git log --oneline

(e) 0dad9a6 リファクタ
(d) 79377c3 事例3用管理画面実装完了
(C) 32096c2 コミットC
(B) ae4f281 コミットB
(A) 6dcd4ce コミットA

(4) 現在の変更点を最新のコミットの1つ前のコミットに含めたかった

(2)と同様、index.phpを編集しましたが、この編集内容は(d)に含めたかったです。メッセージは正しそうです。

git log --oneline

(e) 2092de6 リファクタ
(d) b3fed10 事例4用管理画面実装完了
(C) 32096c2 コミットC
(B) ae4f281 コミットB
(A) 6dcd4ce コミットA

[対処]

git add index.php
git commit
git rebase -i 32096c2 ※ 「f, fixup」利用

同じくgit rebase -iですが、「f, fixup」を使います。 まず、index.phpの編集内容をコミットします。

git add index.php
git commit

このあと(d)に取り込まれるので、コミットメッセージはなんでもよいです。

事例4用管理画面実装完了の作業漏れ

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#

:

(f)ができました。(f)を(d)に取り込みます。

git log --oneline

(f) adfec57 事例4用管理画面実装完了の作業漏れ
(e) 2092de6 リファクタ
(d) b3fed10 事例4用管理画面実装完了
(C) 32096c2 コミットC
(B) ae4f281 コミットB
(A) 6dcd4ce コミットA

git rebase -i 32096c2と打つと編集モードになります。

(d) pick b3fed10 事例4用管理画面実装完了
(e) pick 2092de6 リファクタ
(f) pick adfec57 事例4用管理画面実装完了の作業漏れ

# Rebase 32096c2..adfec57 onto 32096c2 (3 commands)
#
# Commands:

:

含めたいコミット(f)を、含め先のコミット(d)の直下に移動します。そして、(f)の「pick」を「f」に書き換えて保存します。

(d) pick b3fed10 事例4用管理画面実装完了
(f) f adfec57 事例4用管理画面実装完了の作業漏れ
(e) pick 2092de6 リファクタ

# Rebase 32096c2..adfec57 onto 32096c2 (3 commands)
#
# Commands:

:

すると、(f)は(d)に吸収されます。ハッシュ値は、(d)以降のコミットについて変更されています。

git log --oneline

(e) 605cb37 リファクタ
(d) 533f9bb 事例4用管理画面実装完了
(C) 32096c2 コミットC
(B) ae4f281 コミットB
(A) 6dcd4ce コミットA

――上記のフローを理解した上で、少しだけ早い方法を使うこともできます。

[少しだけ早い対処]

git add index.php
git commit --fixup=b3fed10
git rebase -i 32096c2 --autosquash

コミットの時に、含め先のコミット(d)のハッシュ値を--fixupで指定します。 すると、プレフィックスのついたコミットメッセージを持つコミットが生成されます。

git log --oneline

(f) b230d6b fixup! 事例4用管理画面実装完了の作業漏れ
(e) 2092de6 リファクタ
(d) b3fed10 事例4用管理画面実装完了
(C) 32096c2 コミットC
(B) ae4f281 コミットB
(A) 6dcd4ce コミットA

そして、git rebase -i 32096c2のオプションに--autosquashをつけると、コミットの移動と「pick」の置き換えが自動でおこなわれた状態で編集モードに入ります。「pick」の置き換えは「f」ではなく正式な「fixup」となるようですね。

(d) pick b3fed10 事例4用管理画面実装完了
(f) fixup b230d6b fixup! 事例4用管理画面実装完了の作業漏れ
(e) pick 2092de6 リファクタ

# Rebase 32096c2..b230d6b onto 32096c2 (3 commands)
#
# Commands:

:

保存すれば、目的達成です。

(5) 現在の変更点を最新のコミットの1つ前のコミットに含め、メッセージも変更したい。

では、(2)で同時に(1)、(2)の操作をおこなうことを考えたように、(3)と(4)を同時におこないたい場合どうしたらよいでしょうか。もちろん、(3)と(4)を別々におこなうこともできますが、同時にもおこなえます。

[対処]

git add index.php
git commit
git rebase -i 32096c2 ※ 「s, squash」利用

git rebaseでの編集まで(4)と同じ流れです。

コミット。

git add index.php
git commit

メッセージ編集〜保存。

事例5用管理画面実装官僚の作業漏れ

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#

:

(f)ができました。

git log --oneline

(f) 547cd2b 事例5用管理画面実装官僚の作業漏れ
(e) 9a636f7 リファクタ
(d) 16b489d 事例5用管理画面実装官僚
(C) 32096c2 コミットC
(B) ae4f281 コミットB
(A) 6dcd4ce コミットA

(f)を(d)に取り込みます。git rebase -i 32096c2ですね。

含めたいコミット(f)を、含め先のコミット(d)の直下に移動するところまでは(4)と同じです。 ここで、(f)の「pick」を「s」に書き換えて保存するだけです。

(d) pick 事例5用管理画面実装官僚
(f) s 547cd2b 事例5用管理画面実装官僚の作業漏れ
(e) pick 9a636f7 リファクタ

# Rebase 32096c2..16b489d onto 32096c2 (3 commands)
#
# Commands:

:

すると、2つのメッセージが上下に配置された状態で編集モードに入ります。

# This is a combination of 2 commits.
# This is the 1st commit message:

事例5用管理画面実装官僚

# This is the commit message #2:

事例5用管理画面実装官僚の作業漏れ

# Please enter the commit message for your changes. Lines starting

:

上記のまま保存すると、以下のようなコミットメッセージになってしまいます。

事例5用管理画面実装官僚

事例5用管理画面実装官僚の作業漏れ

以下のように編集して保存します。

# This is a combination of 2 commits.
# This is the 1st commit message:

事例5用管理画面実装完了

# Please enter the commit message for your changes. Lines starting

:

すると、(f)は(d)に吸収されメッセージも編集されました。

git log --oneline

(e) 2536867 リファクタ
(d) 35bcb56 事例5用管理画面実装完了
(C) 32096c2 コミットC
(B) ae4f281 コミットB
(A) 6dcd4ce コミットA

まとめ

小分けのコミットを心がけると整理も容易になります。また、逆に整理を意識するとコミットを小分けするよう意識が向きます。

コミットログは今ままで自分が何をしてきたかの歴史となるので、きれいに記せていければよいのかな、と思います。

最後に

Wizではエンジニアを募集しております。 興味のある方、ぜひご覧下さい。

careers.012grp.co.jp

*1:ハッシュ値に限らず、コミットを指し示せればよいのでHEAD^2といった指定でも可。

*2:ここのメッセージを編集しても反映されません。たまに、ついやってしまいます。

輪読会を開催した話とその感想

はじめまして、フロントエンドエンジニアの髙橋です。

 

バーチャルオフィス導入の影響もあり、Wiz社内でのオンラインのLT会もくもく会などイベントが増えてきております。

その一環でWizでは今期から毎週輪読会を行っており、その内容や感想などをご紹介したいと思います!

 

輪読会を開催した目的 

輪読会にはさまざまな効果がありますが、今回の目的は2つです!

 

- インプット / アウトプットの場を設ける

- 技術的なディスカッションをして、みんなで理解を深める

 

増えてきたとはいえ、社内でのこういったイベントはまだまだ少ないと感じています。(勉強会等に参加されている方は多いですが)

内容を理解し、話し合うことでただ「本を読む」以上の効果を期待して開催しました!

 

輪読会の内容

そもそも輪読会とは??

輪読会とは、複数人が同じ本を回し読み、お互いの意見などを話し合う会です!

Wizでは、slackでteam-rindokuというチャンネルを作り、(そのままですね…)

そこでアナウンスやアンケートをとったりしています。

f:id:sotq17:20210218200403p:plain


実際の内容(初回)

■対象書籍
リーダブルコード

■読書予定範囲
2章ずつ (おおよそ1時間)

■進め方
 - 1~2章順番に音読+軽くディスカッション
 - 読んでいて疑問点があれば、それについても話し合う
 - 準備は特に必要なし
 - 本は各自でご用意を

 

書籍は以下の理由でお馴染みのリーダブルコードにしました!

- 読んだことのある人も読み直すことで新しい気づきがあるため

- 読んだことのない人には自信を持って勧められる本のため

- 読んだ後のディスカッションがしやすいため

 

開催に際して、気をつけていること

- なるべく参加ハードルは低くする

自由参加ということもあり、参加ハードルが高ければ集まりづらく、続かない可能性があると思っています。

今回のリーダブルコード輪読会は準備不要にするなど、なるべく気軽に参加してもらえるようにしました!

 

- 最低開催人数を決めておく

開催日時によって参加できる人数にばらつきがあるので、最低このくらい集まったら開催する、といったボーダーを決めています。

そうすることで一定のペースで開催し続けることができたのではないかと思います。

 

感想

良かった点

■より深い理解になった

読書って途中から集中力が切れて、内容が頭に入らない部分が多いと思うのです。(私だけですかね…?)

人に聞かれるのでしっかり読まねば!という意識が働き、集中力を保ったまま読むことができました。一人の時よりも内容がしっかり残っている気がします。

また、難しい箇所が出ても、すぐに質問できるので疑問点が残りづらく、それも輪読会のメリットの一つだと感じています。

 

■ディスカッションでさらに理解が深まる

ディスカッションをすることで、自分とは違う感想を聞くことができたり、新しい発見をしたりと、考えの幅が広がるのではないかと思います!

「コード書いている時、リーダブルコード思い出しました!」

という声もあり、多少なりとも業務に還元できたのでは?と感じています。

 

また、ディスカッション時に脱線して話をしたり、わいわいしながら進められているので個人的には楽しみながら勉強できているので、このディスカッションが最も大切だと感じています。

 

■別の輪読会に派生すること

他のメンバーも useEffectガイド の輪読会を開催してくれるなど別の輪読会に派生しています!(嬉しい…)

個人的にもひとりで読み切るのが辛かったのですごく助かりました。

輪読会という方式が広がっていけば効率良く勉強できそうなので、どんどん広げていきたいですね。

 

課題

まだ探り探り進めているので、いくつか課題もあります。

 

■ディスカッションへの参加について

大体参加者が5人前後くらいで収まっているのですが、

人数が増えてくるとディスカッションに積極的に参加する人/しない人が別れてくる印象がありました。(この辺りはオンラインでやる難しさですね。。)

前回3人しか集まらなかった時は、全員で話ができたので

細かくチーム分けするのも面白いかも知れません。

 

■輪読会のスタイルについて

輪読会にも色々な方法があるようで、

- 担当を決めてまとめて発表するスタイル
- 本を順番に回し読むスタイル
- 問題のみ共有し、事前に読んできて話し合うスタイル

などがあります。

 

リーダブルコードなどの、概念的な読み物の場合は順番に読んでいく方式で良さそうですが、他の読み物の場合どうなのか?など、進め方の課題もまだまだ残っています。

 

おわりに

輪読会を通し、個人的には楽しく、刺激を受けながら勉強できています。

まだまだ課題はありますが、まずは継続して、より良い方式を模索していく予定です!

 

余談ですが、参加者の皆さんに取り扱いたい本のアンケートをとり、興味がある本がいっぱい出てきました。

全て輪読会で扱えないので自分一人でも読んでおきたいと思います…!

 

Wizではエンジニアを募集しております。

興味のある方、ぜひご覧下さい。

https://careers.012grp.co.jp/engineer

 

 

バーチャルオフィスという働き方

はじめに

皆様こんにちは、フロントエンドエンジニアの松本です。

本日はWizクリエイティブチームの働き方についてご紹介したいと思います。

現在、Wizクリエイティブチームの全職種(ディレクター、デザイナー、フロントエンド、バックエンド、ライター)は会社に出社する必要がある場合を除き、基本的にフルリモートで勤務しております。

もちろん出社したい時は出社できるので、かなり柔軟な働き方で働かせて頂いております。

そんな中「バーチャルオフィス」を導入してみて感じたメリットやデメリットに関して共有したいと思います。 

バーチャルオフィスとは?

結論から言うと、ブラウザー上で動作するアバターやバーチャル空間を活用したワークスペースです。

リモートワークで失われたオフィス機能の代替を目的とした、1つの居場所を共有する体験を離れていても実現します。

 

バーチャルオフィスはoViceを導入しています。

oViceを導入する前はSpatialChatやRemoなどのトライアルを試験的に運用していました。

料金体系や機能的な部分を総合して、oViceに至ったと言う感じです。

基本的にバーチャルオフィス空間には、Wizのクリエイティブチームの全職種が滞在しています。

今回はoViceの機能的な部分の説明は割愛します。

イメージしやすいようにざっくり説明すると、以下の画像のようにアイコン同士の距離が近いとお互いの声が聞こえる仕組みになっています。

f:id:yukiji_03:20210215160632p:plain

バーチャルオフィスを導入した経緯

まず最初にフロントエンドチーム内で「気軽に雑談や相談ができるのっていいよね」ということで運用を開始しました。

バーチャルオフィス導入前のリモート環境では、Zoomを使っていました。

Zoomを使っていて課題と感じた部分は以下の3つです。

  • 気軽な相談ができない
  • 雑談の機会が極端に減った
  • 何か用がある時はSlackで連絡 ▶︎ Zoom立ち上げの手順が面倒

上記の理由から「実際のオフィスのように、すれ違って雑談や相談ができるような環境が理想的」ということがきっかけでスタートしました。

バーチャルオフィス活用術  

 弊社での活用例は以下の通りです。

  • 各職種の朝会
  • 1on1面談
  • ちょっとした打ち合わせや会
  • 社内LT会や勉強会、もくもく会など
  • 業務後の雑談など

バーチャルオフィスのメリットとして、実際のオフィスのような1on1ルームや会議室などの「個室」を設ける事ができます。

新たな取り組みとして、バーチャルオフィス上で4月新卒入社のインターン生の教育を行っています。

緊急事態宣言が出ている事もあり、リアル出社が難しい状況でも問題なく教育が行えています。

バーチャルオフィスを導入して良かったところ

良かったと思う主な理由は3つあります。

1. コミュニケーションのハードルが下がった

用がある時しか繋がないZoomに比べて、コミュニケーションのハードルが下がりました。

コミュニケーションがバーチャルオフィス上で完結します。

実際のオフィスのように「近づいて話す」だけで、シームレスにコミュニケーションが取れる環境が非常に気に入ってます。

また、クリエティブチームは東京と福岡が主な拠点なので、プロジェクト内でデザイナーが福岡、エンジニアは東京といった事がよくあります。

バーチャルオフィス導入後は、拠点関係なく全員バーチャルオフィスに滞在しているので、他職種とのコミュニケーションのハードルも下がったと思います。

 

2. コミュニーケーションが増えた

これはコミュニケーションのハードルが下がった事で、単純にコミュニケーションをする機会が増えました。技術的な相談や雑談の機会が増えた事で、リモート環境でも孤独を感じず、リアルなオフィスのように働く事が可能となりました。

 

3. 勉強会などのイベントが活発になった

バーチャルオフィスでライトに集まれるということで、社内での勉強会も活発になりました。

LT会、もくもく会、技術書の輪読会など、社内イベントが活発になったと思います。

バーチャルオフィスの課題

良かったところはあるものの、課題と感じる部分もあります。

  1. 基本アイコンなので顔を見る機会が減る

カメラをオンにする事で顔を見ながら会話する事が可能ではあるものの、アイコンで近づくだけで会話が可能な"シームレスの快適さ"から、音声だけで会話をやり取りする事が多いです。顔を見ながら話した方が良さそうな1on1では、会議室に入ってカメラをオンにしています。

 

  1. 心理的安全性が確保されているのが条件

既存の社員で、お互いの顔と人となりを把握している人同士は良いものの、新入社員の方で、既存社員の顔やキャラクターが分からない状況では、コミュニケーションのハードルが高いと感じました。このような問題を解決すべく、新入社員の方が入社されたタイミングで、一度はカメラをオンにして自己紹介を行う施策を全職種間で行っています。今後も心理的安全性を確保できるような施策を考えていく事は課題だと感じました。

まとめ

バーチャルオフィスを導入する事で、リモートワークで起こりがちなコミュニケーションロスや孤独感などをあまり感じなくなりました。

しかし、新入社員の方など、バーチャルオフィスに慣れていない方へのケアは継続して行っていく必要があると感じています。

また、バーチャル空間の市場がまだまだこれからなので、新機能の追加やUXの向上なども楽しみであります。

最後まで見て頂きありがとうございました。

 

Wizではエンジニアを募集しております。

興味のある方、ぜひご覧下さい。 

https://careers.012grp.co.jp/engineer