シリーズ:iOS版『見開きPDFビューア』開発記録
この記事は、ChatGPTと壁打ちしながら作成しました。また、開発時の作業ログと、Gitの変更履歴・ソースコードを調査した結果を含みます。
第2回の記事では、iOS用PDFビューア「MihirakiPDFViewer」を実機のiPadで使いながら、画質や表示、操作を調整した経緯を紹介しました。
今回は、その動作を確かめるために用意したテストPDFと、テストで見つかった問題の話です。PDFに設定された読む方向やページの配置を正しく識別できるか。検索結果の件数は合っているか。大容量PDFでもページを送れるか。確認したいことに合わせて、テストデータも用意しました。
2026年8月21日と9月8日の作業ログを中心に、XcodeとCodexで何を確認し、どのように修正したのかを振り返ります。開発中は実機でも試用していましたが、この記事で紹介する自動テストの結果は、iPad(A16)/iOS 26.5のSimulator上のものです。
図1:iPad(A16)/iOS 26.5のSimulatorで、日本語サンプルPDF『ためし部』第1話を開いた画面。2026年10月21日に、手元の開発ビルド(バージョン1.0.4/build 10)で撮影しました。本文で紹介する8〜9月のテスト実行時の画面ではありません。
自炊した本では、テストデータを公開できない
このアプリでは、PDFのプロパティを正しく識別することが重要です。左綴じか右綴じか、単ページか見開きか、表紙を単独で表示するか。PDFを開くたびに手で設定し直す手間を減らすためにも、文書に入っている情報を読み取れるようにしたいと考えていました。
最初は、自分で自炊したPDFを使って動作を確認していました。ただ、そのデータを一般に公開することはできません。ソースコードと一緒に置き、ほかの人も同じ条件で確かめられるテストデータが必要でした。
そこで、Googleドキュメントを使って、動作の正しさを目視しやすい内容のPDFを作りました。さらに設定用のスクリプトでPDFのプロパティを設定し、読む方向やページ配置の異なるファイルを準備しました。testdata/にあるL2R*.pdfとR2L*.pdfがそれです。
読む方向とページ配置を組み合わせる
PDFの読む方向はViewerPreferences内のDirection、ページの配置はPageLayoutで指定します。testdata/にある組み合わせを一覧にすると、次のようになります。左綴じの列はDirection = L2R、右綴じの列はDirection = R2Lです。表の各PDFは4ページで、内部設定を確認しています。
| PageLayout(内部設定) | 左綴じのPDF(L2R) | 右綴じのPDF(R2L) | 確認する項目 |
|---|---|---|---|
SinglePage |
L2R_Single.pdf |
R2L_Single.pdf |
単ページの配置設定と読む方向 |
OneColumn |
L2R_OneColumn.pdf |
R2L_OneColumn.pdf |
1列の配置設定と読む方向 |
TwoColumnLeft |
L2R_TwoColumnLeft.pdf |
R2L_TwoColumnLeft.pdf |
2列・表紙なしの配置設定と読む方向 |
TwoColumnRight |
L2R_TwoColumnRight.pdf |
R2L_TwoColumnRight.pdf |
2列・表紙ありの配置設定と読む方向 |
TwoPageLeft |
L2R_TwoPageLeft.pdf |
R2L_TwoPageLeft.pdf |
見開き・表紙なしの配置設定と読む方向 |
TwoPageRight |
L2R_TwoPageRight.pdf |
R2L_TwoPageRight.pdf |
見開き・表紙ありの配置設定と読む方向 |
TwoPageRight |
L2R_Cover.pdf |
R2L_Cover.pdf |
表紙ありとしてのページの組み合わせ |
TwoPageLeft |
L2R_NoCover.pdf |
R2L_NoCover.pdf |
表紙なしとしてのページの組み合わせ |
基本となる6種類のPageLayoutと2種類のDirectionの12通りに、表紙の確認用4ファイルを加えた構成です。表紙確認用のL2R_Cover.pdf、R2L_Cover.pdf、L2R_NoCover.pdf、R2L_NoCover.pdfは、「オプション > 表紙設定」をSTANDARDにした場合を前提としたデータです。表中の「表紙あり」「表紙なし」は、アプリの表紙設定がSTANDARDの場合の扱いを示しています。また、OneColumnやTwoColumnの設定を識別できることと、アプリがその連続表示方式を再現することは分けて扱います。
ファイル名だけで判断せず、PDF内部の設定、アプリが読み取った値、実際のページ配置を照らし合わせます。
この12種類のプロパティ識別は、後述する自動テストでも確認しています。
大きなPDFと、検索結果の多いPDFも用意する
以前、別の仕事をしていたときに、負荷テストの重要性を学びました。その経験もあり、このアプリでも、表示設定の確認に加えて、大きなファイルやページ数の多いPDFで動作を確かめたいと考えました。そこで、ChatGPTに次のように依頼しました。
負荷テスト用のPDFファイルを作ってください。
- 100MB超の大きなサイズのPDFファイル
- 1000ページ超のPDFファイル
用意したのが、testdata/load_test_1100_pages.pdfです。今回ファイルを確認すると、1,100ページ、153,434,540バイト(約153MB)あり、依頼した二つの条件を満たしていました。
検索についても、数件見つかるだけでなく、数百件ヒットする場合を確かめるためのPDFを作りました。依頼したプロンプトは次のとおりです。
非常に多くのヒット数(数百件など)が出るワードで検索するためのPDFファイルを作成してください。検索ワードも教えてください。
続けて、英語版も依頼しました。
英語版も作ってください。
作成したのは、testdata/search_test_600_hits.pdfとtestdata/search_test_600_hits_en.pdfです。どちらも30ページで、検索する語によって期待する件数が分かるようになっています。
| 日本語版の検索語 | 英語版の検索語 | それぞれの期待件数 |
|---|---|---|
| 負荷テスト | Load Testing | 600件 |
| LOADTEST600 | LOADTEST600 | 600件 |
| 性能検証 | Performance Check | 300件 |
| 応答速度 | Response Time | 100件 |
今回、PDFから抽出したテキスト内の出現回数が、この表と一致することを確認しました。アプリ上の検索やページ移動については、後述するテストで確かめています。
読む方向・ページ配置、ファイルの大きさ・ページ数、検索結果の多さ。それぞれ確かめたいことを変えて、テストデータをそろえていきました。
図2:代表的なテストPDFの先頭ページと確認する条件。上段は本文が同じで読む方向の設定が異なるPDF、下段は検索件数の確認用PDFと負荷テスト用PDFです。
テストPDFを指定して、何を依頼していたか
作業ログを調べると、テストPDFを用意しただけでなく、ファイル名と期待する動作を示してテストの作成を依頼した記録も残っていました。以下の日付は日本時間です。当時のログでは保存先をTest/と記載していますが、本稿では現在のtestdata/のファイルと対応させて紹介します。
8月21日:左右綴じと表紙の組み合わせ
8月21日には、「オプション > 表紙設定」がSTANDARDの場合を前提に、表紙確認用の4種類のPDFで確認する表示順を指定しています。たとえば、R2L_Cover.pdfでは最初にPage 1、次に左Page 3・右Page 2、最後にPage 4。R2L_NoCover.pdfでは左Page 2・右Page 1から始める、という依頼です。
最初は「テストを追加できるか検討してほしい」と依頼し、その後、PDFをリポジトリに追加してテストターゲットへ関連づけたことも伝えています。
同日には、プロパティの識別について明示的にテストの追加を依頼しています。次は、その冒頭の抜粋です。
テストを追加してください。L2R_Single.pdfを開いたら、PageLayoutをSingle、DirectionをL2Rと認識していること。
続けて、残りのL2R・R2Lのファイル名も挙げ、12種類すべてで正しく認識することを指定しています。ここでのSingleは当時の指示の表記で、PDF内部の設定名はSinglePageです。
対応して追加されたtestRecognizesPageLayoutAndDirectionFromBundledPDFs()は、実行結果でもPassedでした。実行全体は24件中24件成功です。テスト追加は8月22日のコミットにも残っています。
8月21日には、右綴じの見開きで左右が逆転する不具合も報告しています。ただし、PDF名は記録されておらず、特定のテストPDFでの再現とは断定できません。
9月8日:大容量PDFを指定した動作確認
9月8日には、Test/load_test_1100_pages.pdfを名指しして、大容量・多ページの閲覧をテストするよう依頼しています。確認したかったのは、スクロール中に強制終了したり、極端に重くなったりしないかという点です。
指示そのものは「テストしてください」ですが、対応の記録には、任意のPDFを読み込ませるUIテスト用の起動引数と、testLargePDFScrollingDoesNotCrashOrStall()の追加があります。テストでは容量・ページ数を確認してからPDFを開き、30回連続でスワイプしています。
途中でページ表示を取得するテスト側の判定を修正し、再実行後は成功しています。メモリ使用量の数値測定までは行っていません。
9月8日:数百件の連続検索
同日には、日本語版・英語版の検索用PDFと期待件数を挙げ、ハイライト表示やページ移動がスムーズに行えるかをテストするよう依頼しています。
指示に記載したファイル名には誤りがありましたが、実在する日本語版search_test_600_hits.pdfと英語版search_test_600_hits_en.pdfを確認して使っています。
追加したのは、検索件数を確かめる単体テストと、検索語を繰り返し入力しながらページを送るUIテストです。testSearchLoadTestPDFsFindExpectedHitCounts()とtestRepeatedHighHitSearchesKeepViewerResponsive()に成功記録があり、後者はページインジケータが実際に変わることまで確認するよう、判定を強めて再実行されています。
ただし、ハイライト位置をピクセル単位で画像比較したわけではありません。依頼した内容と、テストが実際に判定した範囲は区別しています。
プロパティ識別には「テスト追加」の指示があり、大容量・検索では動作確認の依頼を受けてテストコードが追加されています。
スライダー精度の検証には、未完了の記録もある
30回スワイプの成功後、同じ1,100ページのPDFで、スライダーを使って特定のページを狙って開けるかも確認しています。
この検証では、見開きの番号と物理ページ数の違いや「1,100」の桁区切りに合わせたテスト側の修正が続きました。後続の実行には終了コード65が残り、最終的な合格報告には到達していません。終了コードだけから、アプリ本体の問題だったとも断定していません。
大容量PDFを使うテストでも、確認する操作によって結果は異なります。30回のページ送りに成功したことと、スライダーで正確に移動できることは、分けて扱っています。
同じデータで、期待する結果を確かめる
自炊した本から始めた動作確認も、公開できるPDFを用意することで、読む方向やページ配置、検索件数の期待値を決めて確かめられるようになりました。大容量PDFは、普段の読書だけでは試しにくい条件の確認にも使えます。
データを作るだけでなく、ファイル名と期待する動作を指定してテストを依頼し、その結果を残す。この流れが、後から何を確認したのかを振り返る材料にもなりました。
次の記事では、PDFを開いた後の状態に目を向けます。アプリを起動し直したときのページや設定の復元、外部PDFの取り込みについて、確認できた範囲を紹介します。
ソースコードと本稿の対象
ソースコードはGitHubのtyamada/MihirakiPDFViewerで公開しています。
本稿は、筆者によるテストデータ作成時の説明、2026年8月21日・9月8日の作業ログ、10月20日時点で調査したtestingブランチの91f0853をもとにしています。紹介したアプリのテスト結果は当時のSimulatorでの記録です。
前の記事:第2回:画質・表示・操作の改善
次の記事:第4回:読書位置・設定の復元と外部PDF

