Developer testing guide
Structured data testing with CSV and JSON
Structured-data imports fail on dialect, schema, and encoding assumptions. A CSV file that opens in a spreadsheet may break a strict parser, and a JSON payload that parses may still violate the schema, lose number precision, or exceed nesting limits.
Verified . CSV and JSON fixtures are generated locally in the browser; row, field, and schema checks run against generated bytes.
Practical checklist
- Pin the CSV dialect before testing imports.
- Validate JSON against a schema, not just syntax.
- Test encoding and BOM handling explicitly.
- Apply row, depth, and size limits to untrusted data.
Pin the CSV dialect first
Record the delimiter, quote character, escape rule, line ending, and whether the first row is a header before running import tests. Without a pinned dialect, the same file can parse differently across tools, and failures point at the fixture instead of the importer.
Validate JSON beyond syntax
A successful JSON.parse only proves the text is well formed. Check required keys, value types, number ranges, and nesting depth against the schema, and decide how duplicate keys and unknown fields are handled instead of letting the parser decide silently.
Set parser limits and encoding rules
Apply row counts, payload sizes, and nesting depth limits before parsing untrusted data. Confirm UTF-8 handling and BOM behavior separately, because an encoding mismatch can corrupt the first field while the rest of the file looks correct.
Expected results
- CSV imports match the pinned dialect for delimiters, quoting, and headers.
- JSON payloads pass schema checks, not just syntax checks.
- Oversized or deeply nested inputs fail before expensive processing.
Common failure modes
- Assuming one CSV dialect fits every tool.
- Treating a successful parse as a passed schema check.
- Ignoring BOM and encoding until production data breaks.
Check the fixture with curl
Download the representative file and print the response status, MIME type, and transferred byte count.
curl --fail --location --silent --show-error \
--output sample-document.pdf \
--write-out 'status=%{http_code}\ncontent_type=%{content_type}\nbytes=%{size_download}\n' \
'https://assets.testfiles.dev/documents/sample-document.pdf'Verify document integrity with Python Requests
Download the document and assert its MIME type, exact byte size, and SHA-256 digest before passing it to a parser or preview service.
import hashlib
import requests
url = "https://assets.testfiles.dev/documents/sample-document.pdf"
response = requests.get(url, timeout=30)
response.raise_for_status()
assert "application/pdf" in response.headers.get("content-type", "")
assert len(response.content) == 9051
assert hashlib.sha256(response.content).hexdigest() == "c0ca139748753dd192bda50ea731868e8f832b5ed97499d12ffb2c995791ffbc"
print("Verified sample-document.pdf", len(response.content), "bytes")Node.js CSV and JSON fixture check
Read a generated CSV file and a generated JSON file, verify CSV headers with consistent column counts across quoted fields, and confirm the JSON top-level shape and key count.
import { readFile } from 'node:fs/promises';
function parseCsv(text) {
const rows = [];
let row = [];
let field = '';
let quoted = false;
for (let index = 0; index < text.length; index++) {
const char = text[index];
if (quoted) {
if (char === '"') {
if (text[index + 1] === '"') { field += '"'; index++; }
else quoted = false;
} else field += char;
} else if (char === '"') quoted = true;
else if (char === ',') { row.push(field); field = ''; }
else if (char === '\n') { row.push(field); rows.push(row); row = []; field = ''; }
else if (char !== '\r') field += char;
}
if (field.length > 0 || row.length > 0) { row.push(field); rows.push(row); }
return rows;
}
const csvPath = process.argv[2];
const jsonPath = process.argv[3];
if (!csvPath || !jsonPath) throw new Error('Usage: node verify-structured-data.mjs <fixture.csv> <fixture.json>');
const rawCsv = await readFile(csvPath, 'utf8');
const csvText = rawCsv.charCodeAt(0) === 0xfeff ? rawCsv.slice(1) : rawCsv;
const csvRows = parseCsv(csvText);
const csvHeaders = csvRows[0];
for (const csvRow of csvRows.slice(1)) {
if (csvRow.length !== csvHeaders.length) throw new Error('ragged CSV row');
}
const jsonValue = JSON.parse(await readFile(jsonPath, 'utf8'));
const jsonTopLevel = Array.isArray(jsonValue) ? 'array' : typeof jsonValue;
const jsonKeyCount = jsonTopLevel === 'object' && jsonValue !== null ? Object.keys(jsonValue).length : 0;
console.log({ csvHeaders, csvRows: csvRows.length - 1, jsonTopLevel, jsonKeyCount });Use stable sample files
These fixtures have stable URLs, recorded MIME types, byte sizes, SHA-256 values, and dedicated detail pages.