Read before running tests. Detailed instructions for single, standard unit tests (fast), full suites (slow), handling authentication, and obtaining the API Token. Tests must be run when a job is complete.
66
78%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./.gemini/skills/testing-workflow/SKILL.mdAfter code is developed, tests must be run to ensure the integrity of the final result.
Crucial: Tests MUST be run inside the container to access the correct runtime environment (DB, Config, Dependencies).
Before running any tests, verify you are inside the development container:
ls -d /workspaces/NetAlertXIF this directory does not exist, you are likely on the host machine. You MUST immediately activate the devcontainer-management skill to enter the container or run commands inside it.
activate_skill("devcontainer-management")Unless the user explicitly requests "fast" or "quick" tests, you MUST run the full test suite. Do not optimize for time. Comprehensive coverage is the priority over speed.
cd /workspaces/NetAlertX; pytest test/ONLY use this if the user explicitly asks for "fast tests", "quick tests", or "unit tests only". This excludes slow tests marked with docker or feature_complete.
cd /workspaces/NetAlertX; pytest test/ -m 'not docker and not feature_complete'To run a specific file or folder:
cd /workspaces/NetAlertX; pytest test/<path_to_test>Example:
cd /workspaces/NetAlertX; pytest test/api_endpoints/test_mcp_extended_endpoints.pyAuthentication tokens are required to perform certain operations such as manual testing or crafting expressions to work with the web APIs. After making code changes, you MUST reset the environment to ensure the new code is running and verify you have the latest API_TOKEN.
bash /workspaces/NetAlertX/.devcontainer/scripts/setup.shsleep 5python3 -c "from helper import get_setting_value; print(get_setting_value('API_TOKEN'))"The retrieved token MUST be used in all subsequent API or test calls requiring authentication.
If tests fail with 403 Forbidden or empty tokens:
/workspaces/NetAlertX/.devcontainer/scripts/setup.sh) if required.app.conf inside the container: cat /data/config/app.confBefore attributing failures to your changes, check what was already broken:
cd /workspaces/NetAlertX; pytest test/ --tb=no -q 2>&1 | tail -20Do not fix pre-existing failures unless that is the explicit goal.
The test environment is pre-configured with:
/app — primary location where Python runs in production/app/server — symlink to /workspaces/NetAlertX/server/app/server/plugins — symlink to /workspaces/NetAlertX/server/plugins/opt/venv/lib/pythonX.Y/site-packages/workspaces/NetAlertX/test/workspaces/NetAlertX/server/workspaces/NetAlertX/usr/lib/pythonX.Y/site-packagesIf the Dockerfile or dependencies changed, rebuild the test image before running:
docker buildx build -t netalertx-test .Takes ~30 seconds; ~90 seconds if the venv stage changed.
sys.modules Stubbing Leaks Across Test FilesSome plugin tests (e.g. test/plugins/test_ntfy_custom_headers.py) stub NetAlertX
modules (conf, helper, models.notification_instance, etc.) via
sys.modules[name] = fake_module so the plugin script can be imported standalone,
outside the container. Because sys.modules is a single process-wide cache shared
by the whole pytest session, a fake module inserted by one test file silently
shadows the real module for every other test file collected afterwards — pytest
imports all test files during collection, before any test runs, so this can happen
regardless of alphabetical/directory order.
Symptom: AttributeError: <module 'models.notification_instance'> does not have the attribute 'get_setting_value' (or similar) in an unrelated test file, where
the module repr has no from '<path>' suffix — a giveaway that a stub, not the
real module, was resolved.
Fix pattern: track which module names your stub actually inserted, and pop them
back out of sys.modules immediately after the one-time import that needed them
(the already-imported script keeps its bound names regardless):
_stubbed_module_names = []
def _stub(name, **attrs):
if name not in sys.modules:
mod = types.ModuleType(name)
for k, v in attrs.items():
setattr(mod, k, v)
sys.modules[name] = mod
_stubbed_module_names.append(name)
# ... _stub(...) calls, then the one-time import ...
import ntfy
for _name in _stubbed_module_names:
sys.modules.pop(_name, None)014b960
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.