Add test infrastructure: unit tests + nbmake notebook smoke tests + CI#9
Merged
Conversation
Add pytest unit tests for makelab + gesturerec helpers Adds tests/ covering the deterministic helper functions: signal generation / shift / zero-crossings / remap (makelab.signal), FFT + peak extraction (gesturerec.signalproc), the file-handling helpers incl. the fulldatastream exclusion guard (gesturerec.utility), SensorData/Trial/GestureSet parsing incl. the Windows double-underscore filename quirk (gesturerec.data), and TrialClassificationResult n-best sorting (gesturerec.experiments). 26 tests. A tiny synthetic fixture corpus under tests/fixtures/TestGestures/ keeps the data.py tests off the large real GestureLogs/. Adds a [test] optional-dependency group (pytest + nbmake + pytest-xdist) and pytest config to pyproject.toml. Nothing was added inside the notebooks. Part of #8. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> @
Add GitHub Actions CI (unit + nbmake notebook smoke tests) and document testing Two workflows, both executing entirely outside the notebooks: - ci.yml (push to master + PRs): a unit-test job (pytest tests/) and a fast notebook-execution job running nbmake over Tutorials/ + StepTracker/. - notebooks-nightly.yml (schedule + workflow_dispatch): the slow GestureRecognizer notebooks. Both install the pinned requirements.txt + .[test] on Python 3.12 plus libsndfile1 for librosa. nbmake executes each notebook in its own directory (CWD-relative data loads work) and honors the existing raises-exception cell tags, so no notebook edits are needed. This automates the manual Pass 2-4 "Restart & Run All" sweeps. Docs: correct the "no test suite, no CI" line in CLAUDE.md + add a Testing section; add a Testing section to README; add a Pass 5 entry to MODERNIZATION-NOTES.md. Part of #8. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> @
Run heavy gesture notebooks on relevant changes + monthly canary, not nightly The top-level deps are pinned, so a nightly rerun of the slow gesture notebooks against an unchanged stack adds nothing. Instead trigger notebooks-heavy.yml on paths-filtered push/PR (Projects/GestureRecognizer/** or the pinned deps) -- i.e. only when a change could actually affect them -- plus a monthly drift canary for unpinned transitive deps / system libs, and the existing manual workflow_dispatch. Renames notebooks-nightly.yml -> notebooks-heavy.yml and updates the doc references in CLAUDE.md, README.md, and MODERNIZATION-NOTES.md. Part of #8. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> @
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #8.
Adds a real test layer for the repo — without adding a single line inside the notebooks. All test code lives in
tests/+.github/workflows/.What's here
Unit tests (
tests/, pytest) — 26 tests, green locallymakelab.signal— wave generation,shift_array,calc_zero_crossings,map/remap, top-N indicesgesturerec.signalproc—compute_fft(half-spectrum, peak bin, amplitude scaling),get_top_n_frequency_peaksgesturerec.utility— the deliberatefulldatastreamexclusion guard,extract_gesture_name,path_leaf, subdirsgesturerec.data—SensorDatamag/rate + int64 cast,TrialCSV parse,GestureSet.loadordering and the Windows__double-underscore filename quirkgesturerec.experiments—TrialClassificationResultn-best sorting +is_correctA tiny synthetic fixture corpus under
tests/fixtures/TestGestures/keeps thedata.pytests off the large realGestureLogs/.Notebook smoke tests (nbmake) — execute-only (no output diffing; random amplitudes /
randomxzoom / timing make strict comparison flaky). Honors the existingraises-exceptiontags (NB2, NB5) and runs each notebook in its own dir so CWD-relative data loads work.CI (
.github/workflows/)ci.yml(push tomaster+ PRs): unit job + fast notebook job (Tutorials + StepTracker)notebooks-nightly.yml(schedule08:00 UTC +workflow_dispatch): the slow GestureRecognizer notebooksPackaging/docs:
[test]optional-dependency group +[tool.pytest.ini_options]inpyproject.toml; Testing sections inCLAUDE.md+README.md; Pass 5 entry inMODERNIZATION-NOTES.md.Verified locally
pytest tests/→ 26 passedraises-exception(IntroToNumPy) and CWD data loads (StepTracker-Exercises)Note
CI runs can only be confirmed green once this PR triggers Actions. This automates the manual Pass 2–4 "Restart & Run All" sweeps.