# skill-template 测试说明(企业数字员工技能) 本目录提供面向 **ERP / TMS / WMS / 船司 / 报关 / 邮件 / 浏览器 / LLM / RPA** 等外联场景的**分层测试骨架**:默认仅内存与本地 SQLite;**真实 API / 真实 RPA** 必须通过环境变量显式授权,且仅以 ``*.sample`` 或复制后的文件提供范式。 复制为新技能后,请保留隔离数据根与 profile 策略,再按域扩展用例。 --- ## 1. 默认必跑(unittest) 在**技能仓库根目录**执行: ```powershell $env:PYTHONDONTWRITEBYTECODE = "1" python tests/run_tests.py python tests/run_tests.py -v python tests/run_tests.py cli_smoke python tests/run_tests.py test_cli_smoke ``` ### 1.1 收集范围 - ``run_tests.py`` **只**发现 ``tests/`` **根目录**下 ``test_*.py``。 - **不递归**:``tests/samples/``、``tests/integration/``、``tests/desktop/``(其中文件为 ``*.sample`` 或需 pytest 单独跑)。 - 启动时把 ``scripts/`` 与 ``tests/`` 加入 ``sys.path``。 - Windows 下将 **stdout/stderr** 包装为 **UTF-8**。 ### 1.2 默认套件覆盖 | 能力 | 文件 | |------|------| | CLI 冒烟(import ``cli.app.main``) | ``test_cli_smoke.py`` | | **subprocess 真实入口** ``python scripts/main.py`` | ``test_entrypoint_subprocess.py`` | | 运行路径与 **CLAW_*/JIANGCHANG_*** 隔离 | ``test_runtime_paths.py`` | | ``SKILL.md`` slug 与 ``constants.SKILL_SLUG`` | ``test_skill_metadata.py`` | | DB / ``publish_logs`` 骨架冒烟 | ``test_db_smoke.py`` | | **adapter profile / 外呼授权策略** | ``test_adapter_profile_policy.py`` + ``adapter_test_utils.py``(非 ``test_`` 前缀,不自动当用例收集) | ### 1.3 数据隔离(``_support.IsolatedDataRoot``) 同时设置(进入同一临时目录 / 用户): | ``CLAW_DATA_ROOT`` | ``JIANGCHANG_DATA_ROOT`` | |--------------------|---------------------------| | 同一 ``tempfile.mkdtemp(prefix="skill-test-")`` | 同上 | | ``CLAW_USER_ID`` | ``JIANGCHANG_USER_ID`` | |------------------|-------------------------| | ``_test`` | ``_test`` | 退出时四个键均恢复(原不存在则 ``pop``),并删除临时目录。 ### 1.4 产物与密钥 - ``tests/.gitignore`` 忽略 ``__pycache__``、``.pytest_cache``、``*.pyc``、``desktop/artifacts/``、``integration/artifacts/``、``.env`` 等。 - 推荐运行前设置 ``PYTHONDONTWRITEBYTECODE=1`` 减少 ``.pyc``。 --- ## 2. 可选:Service / Golden(``tests/samples/*.sample``) - 展示 **service 契约** 与 **fixture 回归** 写法;**默认不执行**。 - 启用:复制 ``tests/samples/test_service_contract.py.sample`` 等为 ``tests/test_*.py``(去掉 ``.sample``),按业务修改后再 ``python tests/run_tests.py``。 - 脱敏样例数据见 ``tests/fixtures/README.md`` 与 ``sample_request.json`` / ``expected_response.json``;profile 结构见 ``adapter_profiles.sample.yaml``。 --- ## 3. 可选:Integration(``tests/integration/*.sample``) - **默认不跑**;文件均为 ``*.py.sample``。 - 说明与开关见 **`tests/integration/README.md`**。 - **禁止**在样例中硬编码真实 token、密码、生产 URL;凭证须来自密钥库或受控环境变量。 --- ## 4. 可选:Desktop E2E(pytest) 见 **`tests/desktop/README.md`**。示例为 `test_desktop_smoke.py.sample`,需复制为 `test_desktop_smoke.py` 后用 pytest 运行。 --- ## 5. 环境变量:测试档位与授权 ### 5.1 测试档位(二选一变量名,后者为历史拼写兼容) - ``OPENCLAW_TEST_TARGET`` 或 ``OPENCLOW_TEST_TARGET`` **合法取值**(非法值将使 ``get_test_target()`` 抛 ``ValueError``): | 取值 | 含义 | |------|------| | ``unit`` | **默认**:单元 / 内存 / mock,不跑仿真与真实外联 | | ``mock`` | 与 ``unit`` 类似的安全档位(显式语义) | | ``simulator_api`` | 仅允许 **仿真 HTTP** 类集成(如 localhost) | | ``simulator_rpa`` | 仅允许 **仿真页面 / 录播 RPA** | | ``real_api`` | 真实 API(另需 ``ALLOW_REAL_API=1``) | | ``real_rpa`` | 真实 RPA(另需 ``ALLOW_REAL_RPA=1``) | 未设置时等价 ``unit``。 ### 5.2 授权开关(显式 ``1``) | 变量 | 作用 | |------|------| | ``ALLOW_REAL_API=1`` | 允许 ``real_api`` profile 访问真实 HTTP 通道 | | ``ALLOW_REAL_RPA=1`` | 允许 ``real_rpa`` profile 驱动真实浏览器/RPA | | ``ALLOW_WRITE_ACTIONS=1`` | 在 ``real_*`` 下允许**写**操作(提交表单、下单等) | ### 5.3 默认安全策略(``adapter_test_utils``) - 默认 ``unit``:不访问真实 API、不跑真实 RPA、不做写操作、不读取真实密钥、不写真实数据根。 - ``assert_no_real_network_env()`` 断言默认未误开 ``ALLOW_REAL_*``(用于必跑用例自检)。 --- ## 6. 与 content-manager 的关系 - **未**复制 article / media / prompt / NotebookLM 等业务测试。 - 本骨架面向**通用外联技能**;业务契约请放在各自技能的 ``tests/samples`` / ``tests/integration`` 复制件中实现。