Automated Test Reporting with TofuPilot
Test reports are necessary. Building them manually is not. TofuPilot stores all your test data in a structured format, so reports can be generated automatically instead of assembled by hand in Excel every Friday.
The Manual Reporting Problem
A typical weekly quality report requires:
- Export data from each test station (15 min per station)
- Merge exports into one spreadsheet (30 min)
- Calculate FPY, failure pareto, and measurement stats (45 min)
- Build charts (30 min)
- Write summary and observations (30 min)
- Format and distribute (15 min)
That's 3+ hours every week. For a quality engineer who should be analyzing data, not formatting cells.
What TofuPilot Automates
TofuPilot replaces steps 1-4 entirely. The data is already centralized. The metrics are already computed. The charts are already drawn.
| Manual step | TofuPilot equivalent |
|---|---|
| Export from each station | Data uploads automatically |
| Merge into one spreadsheet | Already in one database |
| Calculate FPY | Computed in real time |
| Build charts | Built-in dashboards |
| Failure pareto | Auto-generated from test results |
| Measurement distributions | Histograms per measurement |
Types of Test Reports
Per-Unit Test Report
A complete record of one unit's test results. Useful for:
- Customer acceptance documentation
- Warranty records
- Regulatory submissions
Contents: serial number, all test procedures run, all measurements with limits, pass/fail status, timestamps.
Batch Summary Report
Aggregate quality data for a production batch. Useful for:
- Production release decisions
- Supplier quality reviews
- Management dashboards
Contents: batch size, FPY, failure pareto, measurement distributions, Cpk values.
Station Performance Report
How each test station is performing. Useful for:
- Maintenance planning
- Capacity planning
- Station qualification
Contents: FPY per station, cycle time, failure modes, measurement distributions.
Generating Reports via the API
Use TofuPilot's API to pull data for custom report formats.
from tofupilot import TofuPilotClient
from datetime import datetime, timedelta
client = TofuPilotClient()
# Pull all runs for a procedure in the last 7 days
runs = client.get_runs(
procedure_id="FINAL-FUNCTIONAL-V3",
limit=500,
)
# Calculate batch statistics
total = len(runs)
passed = sum(1 for r in runs if r["run_passed"])
fpy = passed / total if total > 0 else 0
# Failure mode breakdown
failure_modes = {}
for run in runs:
if not run["run_passed"]:
for step in run.get("steps", []):
if not step["status"]:
mode = step["name"]
failure_modes[mode] = failure_modes.get(mode, 0) + 1
print(f"Batch Report - FINAL-FUNCTIONAL-V3")
print(f"Period: Last 7 days")
print(f"Total units: {total}")
print(f"Passed: {passed}")
print(f"FPY: {fpy:.1%}")
print()
print("Top failure modes:")
for mode, count in sorted(failure_modes.items(), key=lambda x: -x[1]):
print(f" {mode}: {count} ({count/total:.1%})")Generating a CSV Export
import csv
from tofupilot import TofuPilotClient
client = TofuPilotClient()
runs = client.get_runs(
procedure_id="FINAL-FUNCTIONAL-V3",
limit=1000,
)
with open("test_report.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerow(["Serial", "Date", "Status", "Step", "Measurement", "Value", "Unit", "Low Limit", "High Limit", "Pass"])
for run in runs:
serial = run["unit_under_test"]["serial_number"]
date = run["created_at"]
status = "PASS" if run["run_passed"] else "FAIL"
for step in run.get("steps", []):
for m in step.get("measurements", []):
writer.writerow([
serial,
date,
status,
step["name"],
m["name"],
m["value"],
m.get("unit", ""),
m.get("limit_low", ""),
m.get("limit_high", ""),
"PASS" if step["status"] else "FAIL",
])
print(f"Exported {len(runs)} runs to test_report.csv")Report Scheduling
Option A: Cron-Based Reports
# Run every Monday at 7 AM via cron
# 0 7 * * 1 python3 /opt/reports/weekly_report.py
from tofupilot import TofuPilotClient
import smtplib
from email.mime.text import MIMEText
client = TofuPilotClient()
# Generate report content
runs = client.get_runs(procedure_id="FINAL-FUNCTIONAL-V3", limit=500)
total = len(runs)
passed = sum(1 for r in runs if r["run_passed"])
fpy = passed / total if total > 0 else 0
report = f"""Weekly Test Report - FINAL-FUNCTIONAL-V3
Units tested: {total}
First-pass yield: {fpy:.1%}
"""
# Send via email
msg = MIMEText(report)
msg["Subject"] = f"Weekly Test Report - FPY {fpy:.1%}"
msg["From"] = "reports@yourcompany.com"
msg["To"] = "quality-team@yourcompany.com"
with smtplib.SMTP("smtp.yourcompany.com") as server:
server.send_message(msg)Option B: Dashboard Links
Instead of generating PDF reports, share TofuPilot dashboard links. The recipient sees live data, not a snapshot from when the report was generated.
Advantages over static reports:
- Always up to date
- Interactive (filter, drill down, compare)
- No generation step needed
- No distribution step needed
Replacing the Weekly Quality Meeting
Instead of spending the first 30 minutes of your quality meeting presenting data, open TofuPilot's dashboard and start the conversation from the data. The meeting shifts from "here's what happened" to "here's what we should do about it."