Photoruction工事中!

Photoructionの開発ブログです!

PyMuPDFでPDFを操作する⓶

こんにちは!株式会社Photoructionでエンジニアとしてインターンをしている渡邉圭太郎です。 Photoruction Advent Calendar 202220日目の記事です。

はじめに

自分たちのチームでは、PDFを扱って画像解析を行うことが多いです。以前まではpdfminerを使用していましたが、日本語ドキュメントの豊富さなどから現在はPyMuPDFというライブラリを使用しています。本記事はPyMuPDFを使ったPDFのベクターファイルの取得方法を紹介します。

PDFのベクターファイルとは

PDFのファイル形式には大きわけてラスターファイルとベクターファイルの二つが存在します。それぞれの特徴としては以下の通りです。

ラスターファイル

ラスターファイルとは、色のついた小さい正方形であるピクセル(画素)を大量に組み合わせた画像で、写真などの高精細な画像を形成できます。ピクセル(画素)数が多いほど高画質になり、少ないほど低画質になります。画像のピクセル数は、ファイル形式によって異なります。(https://www.adobe.com/jp/creativecloud/file-types/image/comparison/raster-vs-vector.htmlから引用)

ベクターファイル

ベクターファイルは、数式、直線、曲線を使用して、グリッド上の固定点により画像を表示します。ベクターファイルにはピクセルはありません。ベクターファイルは、数式によってシェイプ、境界線、塗りの色を表現し、画像を構築します。 ベクター画像はサイズが変わっても数式により再計算できるため、品質に影響を及ぼすことなく拡大縮小できます。(https://www.adobe.com/jp/creativecloud/file-types/image/comparison/raster-vs-vector.htmlから引用)

要するにベクターファイルは矩形や文字情報が画像としてではなく格納されています。これはPyMuPDFを使用すると簡単に取得できるのです。

PDFの読み込み

PyMuPDFの読み込みについては、11日目の酒井さんの記事をぜひ参考にしてください!

図形の取得

# PDFファイルパスの読み込み
pdf_path = input()

# 1ページ目の要素を取得
document = fitz.open(pdf_path)
page = document[0]

# 図形の取得
paths = page.get_cdrawings()
line_list, rect_list, quad_list, curve_list = [], [], [], []
for path in paths:
    items = path['items']
      for item in items:
          if item[0] == 'l':
              line_list.append([item[1], item[2]])
              # pdfにlineを追加する場合
              # page.draw_line(line[0], line[1], color=(1, 0, 0))
          elif item[0] == 're':
              rect_list.append(item[1])
          elif item[0] == 'qu':
              quad_list.append(item[1])
                    elif item[0] == 'c':
                            curve_list.append(item[1])

テキストの取得

# PDFファイルパスの読み込み
pdf_path = input()

# 1ページ目の要素を取得
document = fitz.open(pdf_path)
page = document[0]

# テキストの取得
words = page.get_text_words()

text_info = []
coordinates_list = []
for w in words:
    x1, y1, x2, y2 = w[:4]
    x1, y1 = fitz.Point(x1, y1) * page.rotation_matrix
    x2, y2 = fitz.Point(x2, y2) * page.rotation_matrix
    x1, y1, x2, y2 = min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2)
    if x1 == x2:
        x1 -= 0.1
        x2 += 0.1
    if y1 == y2:
        y1 -= 0.1
        y2 += 0.1
  
    text_info.append({'text': w[4], 'coordinates': [x1, y1, x2, y2]})

おわりに

PyMuPDFでは他にもPDFを編集したりする操作も可能となっています。もし気になる方はチェックしてみてください!

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

Datadogを触ってみた

はじめに

  • Photoructionでエンジニアをしております。北原です。

前提

  • 環境は、EC2です

目的

  • そろそろ弊社も監視しないとやばいよね?という流れからsentryかdatadogどちらにするかってなりdatadogになりました

以下個人的な考え

  • できる範囲で言うとsentryでできることはdatadogでも大概できます。(大概ね大概)
    • じゃ最初からdatadog一択じゃんてなるかもしれませんがまぁ目的として何を監視したいかで変わると思います。
    • アプリケーションモニタリング&エラートラッキングだけでいいやってなるならsentryだけで問題なく、またメトリクスはawsを使用しているならaws wayで行くぜ!でもいいと思います
    • datadogはできることが膨大にあります。お金もたくさんかかります。あくまで手段なので何をどのように把握したいのかas is / to beなので理想状態(目的)が何かをちゃんと把握してから手段として正しいか判断した上で導入することをお勧めします

環境

  • 前提にも書きましたがEC2です。
    • 詳細
      • PHP/Laravelを使用しているのでこれらの設定をしていく

やったこと

datadogの作業開始前に

  • EC2をコマンド操作できる状態にしておいてください
  • datadogにLoginしてください。
    • 14日間は、無料で試せるのでアカウントをお持ちじゃない方はぜひにtryしてみてはいかがでしょうか?

まずは下記ページに遷移します(Integrations > agent > Amazon Linux)

SaaSはよくUIが変わったりしてどこに何があったっけとなるのでこちらの画像は、あくまで参考程度にとどめてください

  • 遷移しましたら画像にも映っていますSelect API Keyをクリックして今回使用するAPI Keyを選択しましょう

①に書いてあります Use our easy one-step install. の箇所の下記コマンドをコピペしましょ

DD_API_KEY="ここに選択したAPI keyが入ります" DD_SITE="datadoghq.com" bash -c "$(curl -L <https://s3.amazonaws.com/dd-agent/scripts/install_script_agent7.sh>)"

EC2上でコマンドを実行しますとinstallが始まりますので終わるまで待機です。

設定fileを書いていきます

  • こちらもdatadogにLoginしている状態ですと基本的には、何を用意すればいいのか書かれてます。
    • Logs > Get started > server > phpにページ遷移しましょう
    • ここに書かれている内容をそのままEC2に内に写経するだけ終わっちゃいます
  • datadog-agent以下にあるdatadog-agent.yamlの該当箇所のコメントをコメントインする
logs_enabled: true
  • これでdatadogは、loggingしてくれるようになります。phpに限ったことではないですが例えばnginxのlogも見たいんよなーって要望があった際にもここをtrueにしておけばあとは、各middleware用の設定fileをよしなにするだけですね
  • laravel.logをdatadogに送ってあげましょ
    • datadogは、 /etc/datadog-agent/conf.d/***.d/以下に設定されます。***の箇所は、middlewareの名称で存在しています
      • 設定file名は、conf.yamlで書くといいでしょう。(多分)
    • datadogは、Laravel用のディレクトリを用意してくれているわけではありませんので今回は/etc/datadog-agent/conf.d/php.d/conf.yamlとしてディレクトリとファイルを作成しましょう

作成したら以下のように記述します

logs:
  - type: file
    path: "/path/to/laravel.log"
    service: php
    source: php
    sourcecategory: sourcecode
        log_processing_rules:
       - type: multi_line
         name: new_log_start_with_date
         pattern: \\[\\d{4}\\-(0?[1-9]|1[012])\\-(0?[1-9]|[12][0-9]|3[01])
  • 上記のように設定してあげればひとまずは問題ないです
    • type: multi_line 以下に関して
      • これを書かないとスタックトレースやら何やらが複数行にわたってdatadog上で表示されて全くもって見づらい状態になりますので書いた方がいいかなと思います。

動作確認

  • 設定fileを書き終えたらdatadog-agentを再起動します。
sudo systemctl restart datadog-agent
  • 再起動終わりましたら、datadogのlogsで確認することが可能になります。
    • 補足しておきますとLaravelのlogの設定次第で表示される内容が異なりますから、スタックトレース見たいなーって思う方は、意図的に発生させてみてください。

参照

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

ゆるラム始めました

Photoruction Advent Calender 2022の18日目の記事です!

こんにちは!CREチームリーダーの田中です。

前回、スクラムマスターとしての半年間の経験の備忘録を書きました。

今回はその後半に当たる記事です。

突然ですが、「ゆるラム」という言葉はご存知でしょうか?

ま、知るわけはないですよね。僕が勝手に作った造語ですから。。

経緯としては、どうせスクラムの勉強をしたのだから、

スクラム開発を行わないチームに、スクラムのエッセンスを取り入れられないかな〜と思い立ちました。

そして、ガッツリしたスクラムフレームワークの文脈には添えない状況で、いかに、

スクラムの良いとこどりをするか、「ゆるラム」を真剣に考えてみようと思います!

前提の違いを考える

まず、スクラム開発の基本的な考えをおさらいしてみましょう。

スクラムは、不確実性をヘッジしていくのが基本思想。

タスクの割り込みが発生する場合は、基本的には次回以降のスプリント(期間内に対応するタスク)に組み込まれます。

安定した進捗を出すためです。(ただ、勿論緊急度が高いタスクが発生した場合は、他のタスクを次回のスプリントに回す形で、スプリント内で対応するようにします。)

一方、弊社のCREチームだと、不具合の一時切り分けがメインタスクになります。

カスタマーサポートのチーム顧客から不具合の報告を受け、CREチームに原因究明を依頼します。

当然、顧客に対して不具合に関しての説明が求められますので、それまで取り組んでいるタスクよりも優先度を高めて、一時調査

をし→原因突き止めたら、報告。そして、対応の優先順位を決め、改修。

こんなフローになっています。

スクラム開発に比べたら、割り込みタスクを翌週翌々週に調整していくことが難しいのが現状かなと思います。

つまり差分は

  • スクラムチーム:不確実性をいかに増やさず、減らすか
  • CREチーム:不確実性が増えていく可能性がある中で、いかに減らすか

を考えていかねばなりません。

表現として、矛盾してるような気もしますが、それでも向き合っていかないといけません笑

スクラム開発から転用できそうな考え方

  • こまめなコミュニケーションを取り合えるようにする
  • 検査→適応できる(要するにPDCAを回せる)
  • スコープを区切るのは大事

転用できるイベント

  • デイリースクラム(進捗の共有、悩みの解消、コミュニケーションの促進)
  • レビュー(検査や知財共有)
  • レトロスペクティブ(振り返りの場づくり)

逆に転用できないこと

  • プランニング(後述の通り、差し込み計画を立てても意味がない。だって予測できないから)
  • リファインメント(仕様の検討をメインで行わないため)

具体的なアクション

  • デイリースクラム
    • 週一の定例→デイリーを毎日に変更
    • 細かい改善ができるようにということと、コミュニケーション量増進が目的
  • レトロスペクティブ
    • 隔週でKPTを設ける
    • 短期的なタスクの追われる中でも、中長期的な視野を持って日々の業務に取り組むことを忘れないために重要
  • レビュー
    • 日々対応した不具合隔週でレビュー
      • それを題材に仕様理解、コード理解を深める
    • レビューというより勉強会の意味合いが強い

まとめ

以上が、スクラムチームのスクラムマスターから、

CREリーダー就任2ヶ月ほどで着手している「ゆるラム」施策です。

上記に限らず、良さげなイベントに関しては、積極的に取り組んでいこうと思います

(アドカレ1日目の南風原さんのこの記事とかとか)

CREはもぐら叩きのようなもん

出てきたもぐらをすぐ叩くのもそうだし、

次に出てきた時に、すぐボコボコにできるように、可視化できる状態にしなければならない

結局大事なこと

ゴールとしては、

  • いかに早く、調査対応やデリバリーをするか
  • チームとしての生産性を高めること
  • 学びのサイクルを構築すること

になるかなと

まだ、試行錯誤の段階ですが、こんな感じで、「ゆるラム」を進めていきます!!

P.S.

ここまで書いてやっと気づいたけど、スクラムの語源から考えると、

「ゆるラム」ってめっちゃ弱そうよね。。

CameraXのmlkit-visionを使ってみた

はじめに

Photoructionでは工事現場の写真撮影をメイン機能としてさまざまな機能があり、その写真撮影機能では現在Camera2を使ってカメラの制御をしています。

昨今では、Camera2の代わりにCameraXがstableで出始め、Camera2と比べ出来ることにもメリットデメリットがありますが、そろそろPhotoructionでもCameraXへの移行を進めようと考えています。

通常の写真撮影とは別の機能として、QRコードリーダーを実装する案件があったため、これを気にQRコードリーダーをCameraXで実装することになりました。

実装はcameraXの1.1.0をベースに実装しましたが、本記事執筆段階では1.2.0がstableとなり、1.3.0はalphaが出始めています。

今回は1.2.0で追加されるmlkit-visionへの置き換えを見ていこうと思います。

結果

今回1.1.0から1.2.0になることでMlKitAnalyzerを利用でき、そこにscannerをセットするだけでMlKitを使えるのでとても簡単になったと感じました。

ただし、1.1.0以前で既にImageAnalysis.Analyzerを作成済みで、特にそこのロジックをいじる予定もない場合は1.2.0への移行を急ぐ必要はないのかなと感じました。

それよりもCameraControllerを使用することで1.1.0でもカメラ周りの設定がより簡潔に行えることがわかりました。

準備

以下のライブラリ設定が現在です。

// camerax
implementation 'androidx.camera:camera-core:1.1.0'
implementation 'androidx.camera:camera-camera2:1.1.0'
implementation 'androidx.camera:camera-lifecycle:1.1.0'
implementation 'androidx.camera:camera-view:1.1.0'
// mlkit barcode scanning
implementation("com.google.mlkit:barcode-scanning:17.0.2")

まずbuild.gradleのcameraxライブラリのアップデートを行ない、mlkit-visionを追加します。公式ドキュメントはこちらです。

// camerax
implementation 'androidx.camera:camera-core:1.2.0'
implementation 'androidx.camera:camera-camera2:1.2.0'
implementation 'androidx.camera:camera-lifecycle:1.2.0'
implementation 'androidx.camera:camera-view:1.2.0'
implementation 'androidx.camera:camera-mlkit-vision:1.2.0-beta02'
// mlkit barcode scanning
implementation("com.google.mlkit:barcode-scanning:17.0.2")

camerax系は全て1.2.0にします。 mlkit-visionのみ1.2.0-beta02までしかでていません。 barcode-scanningはmlkit-visionがあっても必要です。

cameraX1.1.0の実装

startCamera()

プレビュー画面の設定からバーコード解析の設定、カメラの起動を行います。

private var cameraProvider: ProcessCameraProvider? = null
private fun startCamera() {
    val cameraExecutor: ExecutorService = Executors.newSingleThreadExecutor()
    val cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext())
    if (cameraProvider != null) {
        cameraProvider?.unbindAll()
    }
    cameraProvider = cameraProviderFuture.get()
    val surfaceProvider = binding.previewView.surfaceProvider
    val preview = Preview.Builder().build().apply {
        setSurfaceProvider(surfaceProvider)
    }
    val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
    val imageAnalysis = ImageAnalysis.Builder().build().apply {
        setAnalyzer(cameraExecutor, BarcodeAnalyzer())
    }
    cameraProviderFuture.addListener(
        {
            cameraProvider?.unbindAll()
            cameraProvider?.bindToLifecycle(
                viewLifecycleOwner,
                cameraSelector,
                preview,
                imageAnalysis
            )
        },
        mainThreadExecutor()
    )
}

ImageAnalysis.Analyzer

このクラスでバーコード解析を行います。

バーコード以外のMLKitも同じようにAnalyzerを実装するだけで、解析ができます。

一度に読み込んだバーコードをList\<Barcode>で取得し、Barcodeクラスにはフォーマットやデータ、PreviewView上のバーコードの位置情報などさまざまな情報が入っています。

今回は取得したBarcode情報をOverlayViewなどのカスタムビューへの出力の実装はしていませんが、実装してあげることでプレビュー上で認識したバーコードに被せて枠を表示したりできます。

class BarcodeAnalyzer :
    ImageAnalysis.Analyzer {
    override fun analyze(imageProxy: ImageProxy) {
        val mediaImage = imageProxy.image
        if (mediaImage != null) {
            val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
            BarcodeScanning.getClient().process(image)
                .addOnSuccessListener { barcodes ->
                    barcodes.forEach { it.format }
                    // バーコード情報の受け取り
                    // barcodesからデータを取り出して使用
                }
                .addOnCompleteListener {
                    imageProxy.close()
                }
        }
    }
}

cameraX1.2.0(mlkit-vision:1.2.0-beta02)

startCamera()

1.2.0(mlkit-vision:1.2.0-beta02)ではCameraControllerを使用し、mlkit-visionのMLKitAnalyzerを使用することで簡潔に実装できます。

なお、CameraControllerは以前から使用できます。

private var barcodeScanner: BarcodeScanner? = null
private lateinit var cameraController: LifecycleCameraController
private fun startCamera() {
    cameraController = LifecycleCameraController(requireContext())
    cameraController.cameraSelector = DEFAULT_BACK_CAMERA
    cameraController.bindToLifecycle(viewLifecycleOwner)
    binding.previewView.controller = cameraController
    barcodeScanner?.close()
    barcodeScanner = BarcodeScanning.getClient()
    cameraController.clearImageAnalysisAnalyzer()
    cameraController.setImageAnalysisAnalyzer(
        mainThreadExecutor(),
        MlKitAnalyzer(
            listOf(barcodeScanner),
            CameraController.COORDINATE_SYSTEM_VIEW_REFERENCED,
            mainThreadExecutor()
        ) { result ->
            // バーコード情報の受け取り
            val barcodes = result.getValue(barcodeScanner!!)
            // barcodesからデータを取り出して使用
        })
}

MlKitAnalyzerにlist型でbarcodeScannerを渡しているので、他のScannerを複数セットし、結果のresultのgetValueでそれぞれのScannerを元にデータを取得することができ、より短い記述で複数のMlKitを利用できるようです。

余談

ちなみに1.1.0で使用しているBarcodeAnalyzerはImageAnalysis.Analyzerであり、1.2.0-beta02で使用しているMlKitAnalyzerもImageAnalysis.Analyzerなので、 1.1.0でもCameraControllerを使用することで以下のようにstartCameraを実装できるようです。

private lateinit var cameraController: LifecycleCameraController
private fun startCamera() {
    cameraController = LifecycleCameraController(requireContext())
    cameraController.cameraSelector = DEFAULT_BACK_CAMERA
    cameraController.bindToLifecycle(viewLifecycleOwner)
    binding.previewView.controller = cameraController
    cameraController.clearImageAnalysisAnalyzer()
    cameraController.setImageAnalysisAnalyzer(
        mainThreadExecutor(),
        BarcodeAnalyzer()
    )
}

最後に

CameraXは1.0.0から1.1.0になったタイミングでPreviewViewが追加され、プレビュー画面の生成やTextureViewでの実装の場合onSurfaceTextureAvailableなどを考慮しなくて済むようになったため、更にカメラ機能の実装が容易になりました。

ただ、Camera2と比べ超高解像度が扱えないなどまだ不足している点はあるようなので、今後1.3.0やそれ以上になると更にカメラを扱いやすい機能が追加されることに期待したいです。

建設DX展に行ってきました!

はじめに

こんにちは!CREチームリーダーの田中です。

Photoruction Advent Calender 2022の16日目の記事です!

今週末は2022年M-1グランプリですね。

今年はどのコンビがM-1チャンピンになるのか、ドキドキです。

このシーズンになると、過去のM-1グランプリの記憶が蘇りますね!

( ゚д゚)ハッ!

ここは、開発ブログでした汗

そんな戯言はさておき、

建築DX展に行くことになったよ〜!(野田クリ風)。

閑話休題

先日、2022年12月5日〜7日に東京ビッグサイトで開催されていた建築DX展の最終日に、展示者側のスタッフとして参加しました。

以前に来場者として、何度か参加したことはありますが、スタッフ側としては初参戦です。。!

会社の看板を背負って、来場者の方々にPhotoructionの魅力を伝える大切な仕事。ドキ ドキ

エンジニアという職業柄、なかなか実際に現場で働かれている方々の生の声を聞ける機会はないので、内心楽しみにしてました。ワクワク

建設DX展とは

https://www.japan-build.jp/hub/ja-jp/about/kdx.html から引用

弊社Photoructionは、

建設の世界を限りなくスマートにする

というミッションを掲げておりますので、ドンピシャのイベントです。

Photoructionブースはこんな感じ

今回の出展テーマ

各社それぞれのサービスの魅力を伝えるのは勿論、コラボレーションすることでの価値提供が今回のテーマです!

Photoructionは、まさに日頃上記の会社様のサービスを提携することで、サービスとして新しい働き方を体現しようとしていますが、それをオフラインイベントの展示会という形で表現しようとしていて、説明を受けた時、興味深いな〜と思いました。

Photoruction出展ブース

合同スペースの中に、各社のブースがありました。

一番右の水色のブースがPhotoructionです。

セミナーセッション

セミナースペースでは連日以下のスケジュールで実施されました!

多くの会社様に登壇いただきました(中島さんの人脈Σ(゚Д゚)スゲェ!!)

開催レポート

連日総動員で、来場者様にPhotoruction魅力を説明するべく奮闘していました。

私は、最終日の3日目のみの参加でしたが、最終日が一番来場者が多く盛り上がっていました!

特にセミナー後は話を聞いて興味を持ってくださった方が多くいらっしゃいました(セミナー恐るべし!!!)

そんなセミナーは毎回大盛況!

ラストのセミナーはブースから溢れかえっていました。。!

参加してみての感想

トータル20名ほどの来場者の方々とお話させてもらいました。密度の濃い1日でした笑。

一言で言えば、勉強になって面白かったです。

韓国人の方(韓国でphotoructionのような施工管理ツールを作ってるらしい。参考目的)に英語で応対(全然できてない)から始まり、

導入検討されてる来訪者様の熱い目線を向けられながら、プロダクトの説明をしたり(費用感を質問されたら、営業担当の出番なので、即バトンタッチ!)、

実際にPhotoructionを利用されてるお客様から、「要望いいっすか?」と熱いカイゼン要望をいただいたり、

最後には、「昨年の展示会でPhotoructionさんの説明を聞いたことあるんですが、1年前から変わったことありますか?」となんと、1年前からのPhotoructionの進捗を聞いてくださる来場者様とお話しできました(Photoructionの定点観測してるの面白過ぎる!)。

最後に

様々な立場の方々から、多様なFBをいただけて、テンションが上がりました。

実際の業務の一部だとは思いますが、具体的な作業のシチュエーションを聞くことができ、参加出来て良かったと思いました!

来年、定点観測されていた方にまたお会いした時に、今回以上、驚かせられるように引き続き頑張っていこうと思います!

現場からは以上です。終わり〜(マヂラブ風)

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

モバイルリリースとテスト自動化について

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

Photoruction Advent Calendar 2022の15日目の記事になります。

本日は弊社で取り組んでいるモバイルテスト自動化の導入検討について、これまでに調査して分かったことを記事にしたいと思います。

モバイルテスト自動化導入の背景

モバイルテストの自動化を検討するきっかけとなったのは、リリース回数の増加になります。

弊社はandroidiOSそれぞれのアプリをサービス展開しており、以前はそれぞれ月1回程度のリリース回数でした。

しかし現在は、リリーストレインを導入し、毎週リリースをするという計画になっています。(リリース対象やリリースに問題が発生した場合はスキップ)

リリース回数の増加によって、リリース前に行なっているリグレッションテストの工数が増加し、

またテスターリソースが限られていることからリリースまでの時間的猶予がなくなってしまいました。

リグレッションテストは毎回同じ項目を実施するため、自動化することによってリグレッションテストの工数削減と時間短縮を行おうと導入の検討を開始しました。

モバイルテスト自動化ツールについて

モバイルテストの自動化を行う目的はリリース毎に実行するリグレッションテストの工数削減になります。

また多端末での検証やテストミス、エラーの見逃し防止など品質面の向上も見込めます。

これらの目的を達成できるようにモバイルテストの自動化ツール2つについて調査をしています。

1つはAutifyMobileでもう1つはMagicPodになります。

弊社で調査している2つのツールの比較表を記載します。

AutifyMobileのトライアル結果について

AutifyMobileのトライアルを実施しましたので、その調査結果と考察を記載いたします。

調査内容

トライアル期間で実施した内容は、リグレッションテストケースの一部自動化を行いました。

具体的にはアプリ起動からログイン、プロジェクト一覧(弊社サービスのTOP画面)の表示とプロジェクト新規作成になります。

弊社のサービスではプロジェクト一覧からプロジェクトを選択し、プロジェクト詳細で写真や図面を操作することが主な機能になりますが、こちらについてはAutifyMobileと弊社のアプリの間に問題があり、クラッシュが発生してしまうことから調査できませんでした。

考察

トライアルを通して分かったAutifyMobileの良かった点と悪かった点を記載いたします。

まとめ

今回はモバイルテスト自動化について執筆いたしました。

現在はAutifyMobileの調査しかしていないので、MagicPodの調査結果については別の機会にご紹介したいと思います。

AutifyMobileを調査した結果では、操作が簡単ですぐに導入可能なことが大きなメリットと感じましたが、オフラインや横画面・写真撮影など実施できない機能が意外と多いこと、iPadに対応していない、アプリがクラッシュする操作がある・実行時間が長い操作があるなど弊社アプリとの相性が良くないという点が見受けられました。

また、料金が割高で弊社で想定している使用方法では費用対効果が低いと感じました。

自動テストで全てのテストケースをまかなうことはできないため、手動テストと組み合わせて自動テストを有効活用することになると思います。

まだまだ調査段階ではありますので、エンジニアと協力しながら自動テストの有効な活用方法を検討し、自動テストの推進をしていきたいと思います!

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

無料プランでも高機能なCloudflare Zero Trustで遊んでみた

こんにちは、PhotoructionでWebエンジニアをしている田村です。

Photoruction Advent Calendar 2022の14日目の記事になります。

はじめに

こないだ Cloudflare Zero Trust を使っていろいろ試してみたので、このサービスについて紹介したいと思います!

とある案件で「アクセス制御にVPN使うか?」という話になったものがあり(けっきょく使わなかった)、どんなサービスがあるか軽く調べてみたことがこのサービスを知ったきっかけです。

Cloudflare Zero Trustとは

Cloudflare Zero TrustはVPNファイアウォール、プロキシなど便利なツール盛りだくさんのサービスとなっています。 そしてこれがなんと無料(複数プランあり)で、家庭や小さな組織なら十分なクオリティがあります。

https://www.cloudflare.com/ja-jp/products/zero-trust

必要なもの

  • Cloudflareアカウント メールアドレスがあればかんたんにサインアップできます。 プランを選択する際は”Free”でOKです。
  • WARP client Zero Trustに接続するデバイスでインストールしておきます。 スマホアプリはあの有名な1.1.1.1 ってやつですね。

Zero Trustの初期設定など

ダッシュボードはCloudflareとZero Trustの2種類あります。 Cloudflareの中のZero Trustっていう位置づけです。

  • Team domain(Settings > General) 例えばTeam名がtest-2022の場合 Team domainはtest-2022.cloudflareaccess.com となります。

  • Device enrollment(Settings > WARP Client) 初期状態ではLogin methodsとしてOne-time PIN が利用可能となっていますが、これだけだとメールアドレスを持っていれば誰でもログイン可能となってしまいます。 このようなruleを追加することで、ログインできるメールアドレスを制限できます。

WARPクライアント設定

Preferenceから作成したチーム名(test-2022)を設定して認証するとZero Trustクライアントして使用可能となります。

やってみたこと① Googleアカウントで認証

デフォルトで設定されているOne-time PIN以外にもいろいろと認証方式を追加・使用することができます。 今回はGoogleアカウントで認証する方法を試してみました。

  • Google以外にもこれだけのidプロバイダを使用することができます。

Google Cloud ConsoleでOAuth 2.0 クライアント追加

説明は省きますが、 下記の設定画面を開くと詳しい説明が載っていて、親切すぎてもう何も言えません。

Login methods(Settings > Authentication)追加

登録したOAuth 2.0 クライアント情報を入力するだけ。 ページの右サイドはOAuth 2.0 クライアントを設定する手順です!

WARPクライアントでログイン

  • WARPクライアント起動(キャプチャはMac版)

  • Preferenceからチーム名を入力するとブラウザでログインフォーム表示 設定した「TEST Google」(Googleによる認証)が表示されていますね これをクリックするといつものGoogleログインのあのフォームへ進みます

  • Googleでログイン成功するとZero Trustクライアントへ表示が変わります (Device enrollmentで設定したメールアドレスだけがログインできます)

GoogleでZero TrustのTeamにログインすることができました!!

やってみたこと② 特定のDNSへのアクセスをブロックする

Zero Trustに接続している状態のときにみんな大好きGoogleサイトを閲覧できないように設定してみます。

設定はとてもかんたんで、何も考えなくても入力できてしまいますね!

Zero TrustクライアントをONにして Googleにアクセスすると、このような表示のページに切り替わります。

Googleサイトの閲覧をブロックすることができました!!

最後に

いかがでしょうか?

今回紹介したのは多数ある機能の中でもはじめの一歩程度で、

これ以外にも

  • 外部に公開していないネットワークにリモートから参加
  • 外部に公開していないサービスをリモートから利用
  • マルウェアや有害サイトから一括ブロック
  • ユーザーをグループ分けし、グループごとにポリシーの適用範囲や内容を設定可能
  • 操作ログ、アクセスログ

等々いろいろな要望に対応可能で、無料の範囲内でもかなりの高機能なサービスとなっています!

このサービスを使ってみて一番考えさせられたのは、UIがシンプルで使い勝手もとてもよく、ある程度のキーワードをしていれば直感で操作できる点です。 こう言ったところは自社サービス構築でも考慮していきたいところだなと思いました。

また今後も時間を見つけて試してみようと思っており、わかったことは機会をあらためて紹介したいと思います。

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