Skip to content
Scaling & Monitoring

How to Manage NPI Testing with TofuPilot

Structure your test procedures across EVT, DVT, and PVT phases. Refine measurement limits using early data and track procedure versions as your product matures.

JJulien Buteau
intermediate7 min readMarch 14, 2026

New product introduction means your test procedures start loose and get tighter as the design matures. TofuPilot tracks every version of your tests across EVT, DVT, and PVT, so you can see how limits evolved and use real production data to set final specifications.

Testing Needs at Each NPI Phase

Each phase has different goals, and your tests should reflect that.

PhaseGoalTest approach
EVTValidate the design worksWide limits, characterization measurements, data collection
DVTProve reliability and complianceTightened limits, environmental stress tests, margin analysis
PVTConfirm manufacturing readinessProduction-ready limits, yield optimization, process capability

During EVT, you're learning what the product actually does. During PVT, you're proving it can be built at volume. The test procedures need to evolve accordingly.

EVT: Characterize with Wide Limits

In EVT, you don't know the true distribution of your measurements yet. Set limits wide enough to collect data without rejecting units unnecessarily. The goal is characterization, not screening.

test_amplifier_evt.py
import openhtf as htf
from openhtf.util import units
from tofupilot.openhtf import TofuPilot

@htf.measures(
    htf.Measurement("gain")
    .in_range(minimum=18.0, maximum=26.0)
    .doc("EVT: wide limits for characterization"),
    htf.Measurement("noise_floor")
    .in_range(maximum=-60.0)
    .doc("EVT: upper bound only, collecting distribution data"),
    htf.Measurement("input_impedance")
    .in_range(minimum=40.0, maximum=60.0)
    .with_units(units.OHM)
    .doc("EVT: centered on 50 ohm nominal, wide tolerance"),
)
def test_amplifier_performance(test):
    test.measurements.gain = 21.4
    test.measurements.noise_floor = -72.3
    test.measurements.input_impedance = 49.1

def main():
    test = htf.Test(
        test_amplifier_performance,
        station_id="LAB-BENCH-01",
    )
    with TofuPilot(test):
        test.execute(test_start=lambda: "AMP-EVT-0012")

if __name__ == "__main__":
    main()

Upload every EVT run to TofuPilot. Even with only 20-50 units, the measurement histograms show the natural distribution of your design. This data is what you'll use to set DVT limits.

DVT: Tighten Limits Based on EVT Data

After EVT, you have real measurement distributions in TofuPilot. Use them to set informed limits. Look at the histogram for each measurement: the mean tells you where the design centers, the spread tells you how much to allow.

test_amplifier_dvt.py
import openhtf as htf
from openhtf.util import units
from tofupilot.openhtf import TofuPilot

@htf.measures(
    htf.Measurement("gain")
    .in_range(minimum=20.0, maximum=23.0)
    .doc("DVT: tightened from EVT data, Cpk target > 1.33"),
    htf.Measurement("noise_floor")
    .in_range(maximum=-65.0)
    .doc("DVT: tightened based on EVT distribution"),
    htf.Measurement("input_impedance")
    .in_range(minimum=45.0, maximum=55.0)
    .with_units(units.OHM)
    .doc("DVT: narrowed from 40-60 to 45-55 based on EVT Cpk"),
)
def test_amplifier_performance(test):
    test.measurements.gain = 21.2
    test.measurements.noise_floor = -73.1
    test.measurements.input_impedance = 50.3

def main():
    test = htf.Test(
        test_amplifier_performance,
        station_id="LAB-BENCH-02",
    )
    with TofuPilot(test):
        test.execute(test_start=lambda: "AMP-DVT-0087")

if __name__ == "__main__":
    main()

The gain limit narrowed from 18-26 (EVT) to 20-23 (DVT) because EVT data showed the design naturally centers around 21 with low spread. TofuPilot's Cpk and measurement statistics make this analysis straightforward.

PVT: Lock Production-Ready Limits

PVT is the final gate before mass production. Limits should be tight enough to catch defective units but not so tight that they kill yield on good units. Use DVT data to set limits that achieve your Cpk target.

test_amplifier_pvt.py
import openhtf as htf
from openhtf.util import units
from tofupilot.openhtf import TofuPilot

@htf.measures(
    htf.Measurement("gain")
    .in_range(minimum=20.2, maximum=22.8)
    .doc("PVT: production limits, Cpk > 1.67"),
    htf.Measurement("noise_floor")
    .in_range(maximum=-67.0)
    .doc("PVT: production limit with margin"),
    htf.Measurement("input_impedance")
    .in_range(minimum=46.0, maximum=54.0)
    .with_units(units.OHM)
    .doc("PVT: final production limits"),
    htf.Measurement("thd_pct")
    .in_range(maximum=0.5)
    .doc("PVT: added THD test for production screening"),
)
def test_amplifier_performance(test):
    test.measurements.gain = 21.3
    test.measurements.noise_floor = -71.8
    test.measurements.input_impedance = 50.1
    test.measurements.thd_pct = 0.12

def main():
    test = htf.Test(
        test_amplifier_performance,
        station_id="SZ-L1-FCT-01",
    )
    with TofuPilot(test):
        test.execute(test_start=lambda: "AMP-PVT-0341")

if __name__ == "__main__":
    main()

Notice the PVT version also adds a new measurement (thd_pct) that wasn't in EVT or DVT. As you learn more about the product through testing, you add tests that catch failure modes discovered during validation.

Version-Control Your Procedure Evolution

Keep every NPI phase in version control. Tag releases so you can trace which limits were active when any unit was tested.

v0.1.0 EVT - initial characterization limits v0.2.0 EVT - added noise floor measurement v1.0.0 DVT - tightened all limits from EVT data v1.1.0 DVT - added environmental stress sequence v2.0.0 PVT - production-ready limits, added THD v2.0.1 PVT - adjusted impedance limit after line trial

TofuPilot tracks which procedure version produced each run. You can filter by version to compare yield between EVT and DVT limits, or to see the impact of a specific limit change.

Use TofuPilot Data to Drive Limit Decisions

The key advantage of uploading every run from every phase is that TofuPilot builds a complete picture of your product's behavior over time.

  • EVT histograms show the design's natural distribution before any limit optimization
  • DVT Cpk values tell you whether your tightened limits have enough margin for volume production
  • PVT yield trends confirm the limits work on real production lines, not just lab benches
  • Cross-phase comparison shows how the measurement distribution changed as the design and process matured

Don't set limits in a spreadsheet and hope for the best. Use the actual measurement data from each NPI phase to make informed decisions. TofuPilot keeps all of it in one place, from your first EVT prototype through PVT line trials and into mass production.

Transition to Mass Production

When PVT is complete and limits are locked, the same test procedure and TofuPilot integration carry straight into production. There's no handoff gap. The production team inherits:

  • Validated test procedures with data-driven limits
  • Historical measurement distributions for comparison
  • Established station configurations and naming conventions
  • Alert thresholds tuned during PVT line trials

The NPI data stays in TofuPilot alongside production data, giving you a continuous record from first prototype to millionth unit.

More Guides

Put this guide into practice