PDF Testing Guide
A sample PDF is most useful when it is tied to a clear test case. This guide shows how to test retrieval, upload validation, browser rendering, text extraction, visual output, email attachments, and automated workflows using predictable synthetic fixtures.
Start with the behavior, not the filename
Teams often collect a folder full of random PDFs and reuse whichever file is easiest to find. That works until a bug appears. A 20 MB scanned contract, a password-protected statement, and a one-page text PDF exercise very different parts of a document workflow. If you do not know which file property matters, the same test can pass one day and fail the next for reasons unrelated to your code.
A better approach is to define one expected behavior and choose the smallest fixture that can prove or disprove it. Use a tiny text PDF for upload acceptance, a selectable-text file for extraction, a visual fixture for thumbnails, and a one-page file for print or signing flows. Once the simple case is stable, add edge cases deliberately.
| Goal | Recommended fixture | Primary assertion |
|---|---|---|
| Basic download | sample.pdf | The final response is a PDF and the downloaded bytes are the expected fixture. |
| Small-file upload | small-sample.pdf | The form accepts a valid PDF well below the size limit. |
| Text extraction | sample-text.pdf | Native text can be found, copied, or parsed without OCR. |
| Rendering / thumbnail | sample-with-images.pdf | Visual blocks render without cropping, blank output, or unexpected scaling. |
| Single-page preview | one-page-sample.pdf | Viewer, iframe, print, or signing UI handles one predictable page. |
1. Test the download path
A successful click is not enough. A browser can show a download animation even when the server returned the wrong content after a redirect. For a reliable download test, check the final URL, status, content type, filename behavior, and—when reproducibility matters—the file hash.
Manual checklist
- Open the direct file URL in a new tab.
- Confirm the browser renders a PDF instead of an HTML error page or login screen.
- Download the file and confirm the extension remains
.pdf. - Repeat in at least one second browser if your product supports multiple browser engines.
- If your application follows redirects, verify the final request still resolves to the intended file.
Command-line smoke check
curl -I https://samplepdf.org/files/sample.pdf
curl -L https://samplepdf.org/files/sample.pdf -o sample.pdf
shasum -a 256 sample.pdf
The current repository fixture sample.pdf is 843 bytes with SHA-256 f1054db56eaef90249677915b7604f075faf01756529f85dfdc1660b8f27b88d. If that hash changes after a deployment, investigate whether the file was intentionally regenerated.
2. Test an upload form in layers
Upload bugs are easier to diagnose when client validation, network transfer, server validation, storage, and post-upload preview are treated as separate stages. A single “upload failed” message hides which layer is responsible.
.pdf? Is the size rule shown before transfer? Is an invalid extension rejected with a useful message?Start with small-sample.pdf to prove the happy path. Then add separate negative fixtures for an oversized file, a non-PDF renamed to .pdf, an encrypted PDF, a malformed PDF, and a document with many pages. Keeping those cases separate makes failures interpretable.
3. Verify PDF type by content, not extension alone
A filename ending in .pdf is not proof that the content is a PDF. Basic validators can inspect the first bytes for the PDF header signature and then hand the file to a real parser for structural validation. The synthetic core fixtures generated by this project begin with the standard %PDF-1.4 signature.
This distinction matters in security and reliability testing. An HTML error page saved as report.pdf may pass a naive extension check but fail immediately in a PDF viewer. Conversely, a valid PDF served with a generic content type may be rejected by a strict API even though a browser opens it.
4. Test browser preview and embedded viewers
Browser PDF behavior is not identical across Chrome, Safari, Firefox, Edge, mobile browsers, and embedded webviews. A good viewer test checks both rendering and the surrounding UI.
- Does the first page appear without a blank frame?
- Can the user zoom and scroll without the page jumping?
- Does an iframe respect the container width on mobile?
- Does the download action still work when the PDF is embedded?
- Are browser or security headers blocking the frame?
- Does print preview show the correct page count and orientation?
Use one-page-sample.pdf when debugging layout because it removes multi-page navigation from the test. Use sample-with-images.pdf when you want visible blocks that make clipping, scaling, or blank rendering easier to spot.
5. Separate text extraction from OCR
Native PDF text extraction and OCR are different problems. A PDF can contain selectable text objects, raster images of text, or a mixture of both. If you test OCR with a native-text fixture, an OCR engine may appear successful even when the real scanned-document path is never exercised.
sample-text.pdf is designed for native text checks: search, copy, parser output, and conversion. A text extractor should find the embedded text without needing OCR. For OCR testing, add a dedicated image-only scanned fixture and assert the recognized text separately.
Useful extraction assertions
- Expected phrases are present.
- Text order is stable enough for the consuming workflow.
- Unicode characters are not replaced by garbled glyphs.
- Whitespace normalization does not merge unrelated words.
- The parser does not return an empty string for a native-text PDF.
6. Test visual rendering with an intentional fixture
The visual sample uses simple vector blocks instead of a copyrighted photograph or third-party artwork. That makes it useful for checking whether a renderer preserves visible regions, page boundaries, and basic color blocks without introducing licensing or privacy concerns into a test asset.
For production-grade visual QA, compare the rendered output against a known baseline image and allow a small tolerance for anti-aliasing differences between rendering engines. Large changes—missing blocks, clipped edges, blank pages, rotated output, or an incorrect page size—should fail the test.
7. Use hashes when the fixture must stay stable
A SHA-256 hash is useful when a test depends on exactly the same bytes over time. Store the expected hash next to the test case. If the fixture is intentionally regenerated, update the hash in one controlled change and record why. If the hash changes unexpectedly, stop treating the fixture as stable until the cause is understood.
| File | Bytes | SHA-256 |
|---|---|---|
sample.pdf | 843 | f1054db56eaef90249677915b7604f075faf01756529f85dfdc1660b8f27b88d |
small-sample.pdf | 820 | 65adae5a24baddea47d07dfcad10572f184334d091b8ae7d5f1d4dc09a3538a7 |
one-page-sample.pdf | 827 | 4aa90a0e0533ae6faa548c80f144b88839370532e0c5e0e1c773b12de34d7f52 |
sample-text.pdf | 848 | 4529bbf3bb9d154aa6a4626642849b2b6fbaab660d85c65500cffa7ba9e7dd72 |
sample-with-images.pdf | 945 | e5825bb4824ef77e6196eb7b11816d31cae178328ea13102db31eb18e9f8e9b3 |
8. Build a small automated regression test
You do not need a large framework to catch basic regressions. A lightweight browser test can verify that the page is reachable, the download link points to a PDF, and the direct file request succeeds. A separate parser test can inspect the downloaded fixture.
test('sample PDF download is reachable', async ({ page, request }) => {
await page.goto('https://samplepdf.org/sample-pdf-download/');
const link = page.getByRole('link', { name: /download sample pdf/i }).first();
const href = await link.getAttribute('href');
expect(href).toMatch(/\.pdf$/);
const response = await request.get(new URL(href, page.url()).href);
expect(response.ok()).toBeTruthy();
const bytes = await response.body();
expect(bytes.subarray(0, 5).toString()).toBe('%PDF-');
});
Keep this test narrow. Browser automation should prove the user-facing path. Parser tests should prove document structure. Security scanning should prove the file is acceptable under your own security policy. Mixing every concern into one test makes failures harder to understand.
9. Add edge cases only after the baseline passes
The core fixtures on samplepdf.org are intentionally simple. They are not a comprehensive PDF conformance suite. Once your baseline works, add fixtures that target the features your product actually supports: multi-page documents, large files, embedded fonts, annotations, forms, encryption, digital signatures, rotated pages, unusual page sizes, image-only scans, damaged cross-reference tables, or incremental updates.
For each edge case, write down the expected outcome. “The app should handle this PDF” is vague. “The app should reject an encrypted PDF with an actionable password-protected-file message before upload completion” is testable.
10. Do not test with real private documents
Using a customer's invoice or an employee's resume because it is convenient creates unnecessary privacy and security risk. Synthetic fixtures make bug reports easier to share and reproduce. They also reduce the chance that screenshots, CI logs, support tickets, or demo recordings accidentally expose personal information.
When a bug only reproduces with a complex real document, create a sanitized or synthetic reproduction that keeps the relevant PDF feature while removing private content. That becomes a much better long-term regression fixture.
A reusable PDF test matrix
| Stage | Happy-path assertion | Failure example | Next diagnostic |
|---|---|---|---|
| Download | Final response returns intended PDF bytes | HTML error saved as .pdf | Inspect redirects, status, content type |
| Upload | Valid small PDF is accepted | Rejected as unknown file | Inspect client/server MIME and signature checks |
| Storage | Retrieved bytes match uploaded bytes | File truncated or replaced | Compare byte length and hash |
| Preview | First page renders | Blank iframe | Inspect viewer errors and frame/security headers |
| Text | Expected native text extracted | Empty or garbled output | Inspect text layer, fonts, parser |
| Visual | Visible blocks match baseline | Cropping or missing region | Inspect page size, scale, renderer |
| Correct one-page output | Extra blank page | Inspect paper size, margins, orientation |
Choose the next file
For a fast download and HTTP-path check, use Sample PDF Download. For structural details, use Sample PDF File. For test-goal selection, use Sample PDF for Testing. For native text behavior, use Sample PDF Text. For visual rendering, use Sample PDF With Images.