Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Execute Vitest and Playwright test suites with result collection and failure analysis.
.claude/skills/a5c-ai-test-automation/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 249% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 158% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 83% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 56% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 96% | 0% |
Automated test equipment control and data acquisition for hardware validation and characterization.
This skill provides comprehensive capabilities for automating electronic test equipment, enabling consistent and repeatable hardware validation workflows. It supports instrument communication, automated test sequences, data logging, and analysis.
bashpip install pyvisa pyvisa-py numpy pandas matplotlib
bash# For HDF5 data storage pip install h5py tables # For advanced analysis pip install scipy uncertainties # For report generation pip install jinja2 weasyprint
pythonimport pyvisa # Initialize resource manager rm = pyvisa.ResourceManager() # List available instruments print(rm.list_resources()) # Connect to oscilloscope scope = rm.open_resource('TCPIP::192.168.1.100::INSTR') scope.timeout = 5000 # 5 second timeout # Query identification idn = scope.query('*IDN?') print(f"Connected to: {idn}") # Configure and measure scope.write(':CHANnel1:DISPlay ON') scope.write(':CHANnel1:SCALe 1.0') # 1V/div scope.write(':TIMebase:SCALe 0.001') # 1ms/div scope.write(':TRIGger:EDGE:SOURce CHANnel1') scope.write(':TRIGger:EDGE:LEVel 0.5') # Read measurement vpp = float(scope.query(':MEASure:VPP? CHANnel1')) freq = float(scope.query(':MEASure:FREQuency? CHANnel1')) print(f"Vpp: {vpp:.3f} V, Frequency: {freq:.2f} Hz") scope.close()
pythonfrom dataclasses import dataclass from typing import List, Dict, Any import time @dataclass class TestResult: name: str passed: bool value: float unit: str limit_low: float limit_high: float class TestSequence: def __init__(self, instruments: Dict[str, Any]): self.instruments = instruments self.results: List[TestResult] = [] def run_test(self, name: str, measure_func, limit_low: float, limit_high: float, unit: str) -> TestResult: value = measure_func() passed = limit_low <= value <= limit_high result = TestResult(name, passed, value, unit, limit_low, limit_high) self.results.append(result) return result def generate_report(self) -> Dict: return { 'total_tests': len(self.results), 'passed': sum(1 for r in self.results if r.passed), 'failed': sum(1 for r in self.results if not r.passed), 'results': [vars(r) for r in self.results] } # Example usage def measure_output_voltage(): return float(dmm.query(':MEASure:VOLTage:DC?')) sequence = TestSequence({'dmm': dmm, 'psu': psu}) sequence.run_test('Output Voltage', measure_output_voltage, 4.9, 5.1, 'V')
pythonfrom uncertainties import ufloat import numpy as np class UncertaintyAnalysis: def __init__(self): self.measurements = [] self.instrument_uncertainty = 0.0 def add_measurement(self, value: float): self.measurements.append(value) def set_instrument_uncertainty(self, uncertainty: float): """Set Type B uncertainty from instrument specifications""" self.instrument_uncertainty = uncertainty def calculate_combined_uncertainty(self, coverage_factor: float = 2.0): # Type A uncertainty (statistical) n = len(self.measurements) mean = np.mean(self.measurements) std = np.std(self.measurements, ddof=1) type_a = std / np.sqrt(n) # Type B uncertainty type_b = self.instrument_uncertainty / np.sqrt(3) # Rectangular distribution # Combined standard uncertainty combined = np.sqrt(type_a**2 + type_b**2) # Expanded uncertainty expanded = coverage_factor * combined return { 'mean': mean, 'type_a_uncertainty': type_a, 'type_b_uncertainty': type_b, 'combined_uncertainty': combined, 'expanded_uncertainty': expanded, 'coverage_factor': coverage_factor } # Usage analysis = UncertaintyAnalysis() for _ in range(10): analysis.add_measurement(float(dmm.query(':MEASure:VOLTage:DC?'))) analysis.set_instrument_uncertainty(0.001) # 1mV from spec sheet result = analysis.calculate_combined_uncertainty() print(f"Voltage: {result['mean']:.4f} +/- {result['expanded_uncertainty']:.4f} V (k=2)")
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-04 | pass→pass | 40,698 | 5,876 | -86% | 1 | 1 | 0% | 1,888 | 2,948 | +56% | 0 | 0 | — |
case-01 | pass→pass | 40,867 | 35,897 | -12% | 1 | 1 | 0% | 1,489 | 2,921 | +96% | 0 | 0 | — |
case-02 | fail→pass | 4,414 | 4,241 | -4% | 1 | 1 | 0% | 812 | 2,836 | +249% | 0 | 0 | — |
case-13 | pass→pass | 11,870 | 2,990 | -75% | 1 | 1 | 0% | 1,983 | 2,347 | +18% | 0 | 0 | — |
case-14 | pass→pass | 15,412 | 3,006 | -80% | 1 | 1 | 0% | 2,724 | 2,330 | -14% | 0 | 0 | — |
case-03 | fail→pass | 36,575 | 5,721 | -84% | 1 | 1 | 0% | 1,181 | 3,050 | +158% | 0 | 0 | — |
case-05 | pass→pass | 5,823 | 33,858 | +481% | 1 | 1 | 0% | 996 | 2,440 | +145% | 0 | 0 | — |
case-06 | pass→pass | 14,470 | 13,710 | -5% | 1 | 1 | 0% | 2,176 | 4,011 | +84% | 0 | 0 | — |
case-07 | pass→pass | 5,216 | 4,532 | -13% | 1 | 1 | 0% | 907 | 2,815 | +210% | 0 | 0 | — |
case-08 | fail→pass | 28,515 | 8,084 | -72% | 1 | 1 | 0% | 1,772 | 3,238 | +83% | 0 | 0 | — |
case-09 | pass→pass | 4,802 | 5,470 | +14% | 1 | 1 | 0% | 733 | 2,739 | +274% | 0 | 0 | — |
case-10 | fail→fail | 46,125 | 7,289 | -84% | 1 | 1 | 0% | 1,250 | 3,202 | +156% | 0 | 0 | — |
case-11 | pass→pass | 2,173 | 2,270 | +4% | 1 | 1 | 0% | 328 | 2,255 | +588% | 0 | 0 | — |
case-12 | pass→pass | 12,353 | 2,630 | -79% | 1 | 1 | 0% | 2,011 | 2,375 | +18% | 0 | 0 | — |
case-15 | fail→fail | 11,666 | 6,074 | -48% | 1 | 1 | 0% | 2,216 | 3,127 | +41% | 0 | 0 | — |
case-16 | pass→pass | 12,536 | 7,067 | -44% | 1 | 1 | 0% | 1,935 | 3,138 | +62% | 0 | 0 | — |
case-17 | pass→pass | 9,124 | 5,218 | -43% | 1 | 1 | 0% | 1,235 | 2,713 | +120% | 0 | 0 | — |
case-18 | pass→pass | 8,297 | 6,860 | -17% | 1 | 1 | 0% | 1,303 | 2,947 | +126% | 0 | 0 | — |
case-19 | pass→pass | 14,858 | 12,162 | -18% | 1 | 1 | 0% | 2,584 | 4,128 | +60% | 0 | 0 | — |
case-20 | pass→pass | 5,134 | 5,843 | +14% | 1 | 1 | 0% | 773 | 2,547 | +229% | 0 | 0 | — |
case-21 | pass→pass | 17,109 | 8,908 | -48% | 1 | 1 | 0% | 1,643 | 3,508 | +114% | 0 | 0 | — |
case-22 | pass→pass | 19,594 | 16,988 | -13% | 1 | 1 | 0% | 3,391 | 4,830 | +42% | 0 | 0 | — |
case-23 | pass→pass | 25,130 | 9,286 | -63% | 1 | 1 | 0% | 2,090 | 3,620 | +73% | 0 | 0 | — |
case-24 | pass→pass | 7,073 | 4,740 | -33% | 1 | 1 | 0% | 1,193 | 2,785 | +133% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 24 cases were attempted. The headline lift of +13 percentage points is the difference between those two pass rates over the 24 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 7/31/2026 | +57% |
Other measured skills in the registry, with their headline benchmark lift.