Testing guides

Testing a desktop app: files, paths and the operating system

A desktop app lives on a real file system, and that is where most of its bugs are. Names a platform forbids, paths that are too long, two names that look the same, a file another program has open. Each section below pairs one of these with a file you can use to test it.

1. Names the operating system treats differently

A file created on one platform may be impossible to create, or quietly renamed, on another.

NameWhat happensTest file
CON.txt, NUL.txtReserved device names on Windows. Cannot be created there, whatever the extension.Filename edge cases
trailing-dot.txt.Windows removes a trailing dot or space, so the saved file has a different name from the one asked for.Filename edge cases
question?name.txtLegal on macOS and Linux, forbidden on Windows along with < > : " \ | *.Filename edge cases
report.pdf.exeWindows hides known extensions by default, so it shows as report.pdf.Filename edge cases
Right-to-left override in a nameDisplays in a different order from how it is stored, disguising the real extension.Filename edge cases

All 26 names are in one archive: the Filename Compatibility pack. Extract it on each platform you ship to and compare what arrives.

2. Paths: length, case and separators

Too long for Windows

Many Windows APIs stop at 260 characters unless long paths are enabled in the system and the app opts in. Extract a deep tree and try to open the innermost file.

Path over 260 characters

Case-only differences

Windows and macOS are case-insensitive by default, Linux is not. Two folders named Docs and docs collide on the first two.

Case-colliding folders

Separators and awkward folders

A backslash is a separator on Windows and an ordinary character elsewhere. Reserved names and trailing spaces break folders as well as files.

Separator confusion · Awkward folder names

3. Two names that look the same

"café" can be stored as one character (NFC) or as "e" followed by a combining accent (NFD). They render identically. APFS treats them as the same name, older HFS+ volumes stored the decomposed form, and Windows and Linux keep whatever bytes they are given. An app that compares names byte for byte sees duplicates, or cannot find a file the user can see. Test with both forms: nfc-café.txt and nfd-café.txt, and folders in non-Latin scripts. Normalization, explained.

4. Opening files it did not write

Text from other programs arrives in every encoding and line ending there is.

FileWhat it tests
UTF-16 LE and UTF-16 BEWhat Notepad and PowerShell have written for years. Opening it as UTF-8 shows spaced-out garbage.
UTF-8 with BOMAn invisible first character that breaks parsers and header matching.
Latin-1Legacy encoding; not valid UTF-8, so a strict decoder fails and a lenient one shows mojibake.
CRLF and no trailing newlineLine counting, editing and saving back without changing every line.
A very long single lineEditors and viewers that assume lines are short.

5. Saving without losing work

Save atomically

Write to a temporary file in the same folder, then rename it over the original. Writing in place means a crash or a full disk mid-save destroys the file the user already had.

Read-only and locked files

On Windows, a file another program has open often cannot be renamed or deleted. Test saving over a read-only file and over one open in another app; the error must say which.

Full disk

Fill a small disk image or USB stick and save. The app should report it and keep the original, not leave a zero-byte file behind.

Kill it mid-save

End the process while a large save is running. On restart, the old file or the new one should open, never a half-written mix.

6. Big, broken and disguised files

Size

Open files from 0 bytes to hundreds of megabytes and watch memory. Loading a whole file to show its first page is the usual culprit.

Size ladder · 0 bytes

Damaged

A truncated PDF or a PNG with a bad checksum should produce a clear message, not a crash or a frozen window.

Truncated PDF · Bad CRC

Disguised

A file whose extension lies. Decide by the bytes, not the name, before handing it to a parser. Check a file's real type.

Executable named .jpg

7. The rest of the machine

Network drives

Open and save on an SMB share. Everything is slower, and file-change notifications can be late or missing, so an app that watches files may not notice edits.

Sleep and resume

Close the lid in the middle of a download or sync. Connections and timers do not survive; the app has to notice and recover.

Install and update

Unsigned or un-notarized apps are warned about or blocked by Windows SmartScreen and macOS Gatekeeper. Test the download a user actually gets, on a clean machine.

Questions

What should I test in a desktop app that I would not in a web app?

The file system: path limits, reserved names, case and Unicode rules, locked files, network drives and encodings.

What is the Windows 260 character path limit?

Many Windows APIs refuse longer paths unless long paths are enabled and the app opts in. Test with a deeply nested folder.

How do I test file saving safely?

Save to a temporary file and rename it over the original, then test full disks, read-only files and killing the app mid-save.

Why does my app see two files with the same name on macOS?

Usually Unicode normalization: the same name stored as NFC and NFD. Compare normalized names.

Keep going

Filename Compatibility pack Filename compatibility → File systems →

More from Learning

Guides and references for test data, file handling and AI evals. All free, no sign-up. See the full hub.

Synthetic data for AI evalsWhat you can download, what you buildRAG test corpusDocuments with extraction trapsJSONL for evalsThe format, and ten ways it breaksMock API for agentsRecords, pagination, failures on demandSafe test dataReserved domains, IPs, numbers & cardsSynthetic PIIFake people that reach nobodyTest card numbersEvery brand, declines, 3D SecureTest phone numbersReserved US, UK and Australian rangesReserved IP addressesDocumentation ranges and SSRF casesExample domains.test, .invalid, example.com, and trapsQA test stringsUnicode, emoji, injection & edge casesFilename compatibilityWhat breaks across Windows, Mac & LinuxFile systemsPOSIX, NTFS, APFS, ext4, SMB, NFS, NASFile signaturesMagic numbers that identify every formatCharacter encodingsUTF-8, UTF-16, BOM & normalizationUpload validationThe checklist, with a file for each checkMIME typesThe right Content-Type for every extensionHTTP status codesEvery code and when you actually see itDates & timesISO 8601, epoch, Excel serials, DSTHTTP headersContent-Type, Disposition, Range, CORSRegex cheat sheetSyntax, flags and ready-made patternsGenerate files (CLI)Make test files on any OSCrypto & certificatesSSL/PEM, hashing, encryptionWeb app testingWhat to test, with a file for each caseMobile app testingPickers, photos, flaky networksCLI testingArguments, pipes and exit codesLarge file upload testingDefault limits, 413s and exact sizes1 GB test file1 GB and 2 GB, with SHA-25610 GB test fileMake one locally in secondsDownload speed test files10 MB to 2 GB of random data