Slide 1

Slide 1 text

PDFの ビジュアル リグレッションテスト terurou 2023-01-21

Slide 2

Slide 2 text

terurou • デンキヤギ代表取締役 • NGKの実行委員を13年ぐらいやってました • 今回は0歳児育児があるので、運営にはノータッチ 1

Slide 3

Slide 3 text

[PR] yagisan-reports 2

Slide 4

Slide 4 text

[PR] yagisan-reportsの状況 • アーリーアクセス版をクローズドで提供中 • まだ正式版を売ってないのに導入実績が増えてきた • 夏頃にはパブリックサービスを開始したいお気持ち • 直近は導入企業(商談中も含む)からの要望を優先対応中 3

Slide 5

Slide 5 text

[PR] 求人は常時やってます • 正社員、学生アルバイト、業務委託、全部可 • フルリモート • Haxe/JS率が高いが、F#とかElixirとか色々ある • あんまり特定の言語がやりたい人に向いた会社ではない • 広義のWeb技術をやってます 4

Slide 6

Slide 6 text

5 ここから本題

Slide 7

Slide 7 text

PDFのビジュアルリグレッションテストをやりたい • デンキヤギは帳票エンジンを作っている • 帳票エンジン≒請求書とかのPDFを生成するやつ • 生成したPDFをテストしたい 6

Slide 8

Slide 8 text

ビジュアルリグレッションテストとは • ビジュアルな • リグレッションテスト 7

Slide 9

Slide 9 text

リグレッションテストとは • リグレッションの発生を検知するテスト 8

Slide 10

Slide 10 text

リグレッションとは • 正確には「ソフトウェアリグレッション」 • 以前は動いていた機能が、機能追加や改修等を経て 期待通りに動かなくなるバグの一種 9

Slide 11

Slide 11 text

ビジュアルリグレッションテストとは(再) • 表示崩れなどの「見た目」のリグレッションの発生を 検知するテスト • 適用例 : Webフロントエンド、アプリ、ゲームなど 10

Slide 12

Slide 12 text

PDFのビジュアルリグレッションテストをやりたい(再) • デンキヤギでは帳票エンジンを開発している • 機能追加によってPDFが期待通りに出力できなくなると、 プロダクトの信用問題になってしまう 11

Slide 13

Slide 13 text

12 以降、「ビジュアルリグレッションテスト」だと長いので、 「VRT(Visual Regression Test)」と表記

Slide 14

Slide 14 text

yagisan-reportsでのVRTの実施状況 • 1年ぐらい前からやっている • 最近も「背景色の塗りつぶしが行われない」バグを検出 • レンダリングシステムの改修があると発生しがち 13

Slide 15

Slide 15 text

PDFに対するVRTのやり方 1. PDFを画像に変換する 2. この画像を「正解画像」と比較する 14

Slide 16

Slide 16 text

yagisan-reports固有のVRT要件 • Node.jsで動くこと(できればWebブラウザでも) • JavaScript環境で動く帳票エンジンなので • Windows, Mac, Linuxで動くこと • 開発環境の制約を減らしたい • 実ユーザー環境に近い方法でPDFを描画したい • [要出典] Edge/ChromeがPDF Viewerのトップシェア? 15

Slide 17

Slide 17 text

[step1] PDF to Image • PDF.jsによる変換 • Firefoxの組み込みビューアー • PDFiumによる変換 • Chromiumの組み込みビューアー • その他、ImageMagickやPopplerなど 16

Slide 18

Slide 18 text

yagisan-reportsでのPDF to Imageの選択 • PDFiumができれば使いたい • ユーザー環境に最も近いはず(要出典) • Chromiumの組み込みエンジンであることが大きい • C++ライブラリなので、どうJavaScript環境で動かすか? • PDF.jsも悪い選択肢ではない • 実績も多く、まず動かせるので、ここから手を付けるのが無難 • Firefoxのシェアが落ちちゃってるのが… • その他の方法ではユーザー環境との乖離が大きそう 17

Slide 19

Slide 19 text

PDF.jsによるPDF to Image • Node.js環境で動かす場合、node-canvasが必要 • HTML Canvas(Canvas API)に描画する仕組み • Cairoに依存してるため、Windowsで使うのがしんどい • WSLを使えば解決するが、開発環境が若干煩雑に • 公式GitHubのサンプルコード • https://github.com/mozilla/pdf.js/tree/master/examples/node/pdf2png • yagisan-reportsでは使っていない 18

Slide 20

Slide 20 text

PDFiumによるPDF to Image • PDFiumのビルド • 有志によるビルド済みバイナリが配布されている • https://github.com/bblanchon/pdfium-binaries • ビルド済みバイナリをNode.jsで起動できればよい 19

Slide 21

Slide 21 text

PDFiumビルド済みバイナリをnode-ffiで起動 • FFIバインディングを書くのが面倒だが動く • が、node-ffiがNode.js v12より新しいバージョンで 動かないという致命的な問題 • Node.js v12のEOLは2022-04-30(もう死んでる) • 現在は使うべきではない方法 • 実はつい数日前までyagisan-reportsではこの方式だった 20

Slide 22

Slide 22 text

PDFiumをWASM(WebAssembly)として使う • PDFiumに多少のパッチを当てれば、Emscriptenで WASMにビルドできる • 前述の有志ビルドバイナリにWASMもある • https://github.com/bblanchon/pdfium-binaries 21

Slide 23

Slide 23 text

PDFiumを自前でビルド • 前述の配布されているビルド済みバイナリが微妙なので、 自前でビルドできるようにした • ビルドオプションが微妙でライブラリとして使い勝手が悪い • ビルドスクリプトと画像化のサンプルをGitHubに公開 • https://github.com/DenkiYagi/pdfium-wasm-build-script • Emscriptenが吐いたコードをそのまま使うのは煩雑なので サンプルコードだけでも見てほしい 22

Slide 24

Slide 24 text

[step2] 画像の比較 • 専用ライブラリが色々あるので割愛 • yagisan-reportsではpixelmatchを使っている • 他にもあるが、Webブラウザでの動作を優先して選択 23

Slide 25

Slide 25 text

現状のVRT環境 • PDFium WASM + JimpでPDFからPNGを出力 • PDFiumだけではBitmapしか出力できないので、 Jimpを使ってPNGに変換 • テスト失敗時に画像を確認したいので、PNGファイルで保管 • 出力したPNGをpixelmatchで比較 • CI環境はAzure Pipelines • プロジェクト管理にAzure DevOpsを使ってるため 24

Slide 26

Slide 26 text

まとめ • 帳票エンジンの開発にはPDFのVRTは必要不可欠 • PDF出力が主要機能であるプロダクトではやるべき • JavaScript環境でのPDF to Imageは結構簡単 • PDF.jsを使う方法が無難でオススメ • 明確なモチベーションがない限り、PDFiumは推奨しない • PDFiumの更新頻度が高い→ビルドの追従を考えると面倒 25