Move project test environments into the workspace
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
- 设备持久 ID、协议能力和业务命令是连接契约,不依赖蓝牙 MAC、网页布局或私有驱动调用。
|
||||
- 只产出 debug APK,正式签名必须有用户明确指令;调试密钥也不进入 Git。
|
||||
- 源码、测试、发布说明都在安卓app下;构建缓存、SDK、密钥、真实设备登记不进 Git。
|
||||
- 项目专用 SSH venv、测试 SDK、AVD 与主机密钥统一存放在根目录的 `测试相关资料/如何测试/本机测试环境/.local/`;通用工具保持复用。搭建入口、锁文件和测试经验跟踪提交,具体命令见该目录 README,禁止新增全局项目专用测试材料。
|
||||
- Android Studio 属于正常安装软件:下载官方安装包、校验、交给用户安装后停下等待,不安装进 Codex 工具目录。
|
||||
- 不擅自关闭 VPN、不自动修改系统设置以修复下载。版本、依赖和 Wrapper 必须锁定并可复建。
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ WiFi 加速与回退专项见 [WiFi 传输测试](WiFi传输测试.md),必须
|
||||
|
||||
远端联调脚本在电脑端使用 `requirements-host.txt` 的 Paramiko;它不属于核桃派离线安装依赖,不能加入设备端 `requirements-dev.txt` 或 OTA wheelhouse。
|
||||
|
||||
项目 SSH 环境、独立测试 SDK、AVD 和私有主机密钥统一放在仓库内被忽略的本机 `.local/`,不再写入全局工具目录。复建、版本锁定与中文路径模拟器入口见 [本机环境说明](../../../测试相关资料/如何测试/本机测试环境/README.md)。SSH 用其中 `.local/ssh/venv/Scripts/python.exe` 运行本目录脚本;凭据/登记门禁不变。普通 UI 使用 `local_env.py build-ui android` 和 `ui-smoke android` 做定向验证,不涉及真机或核桃派。
|
||||
|
||||
## 1. 门禁
|
||||
|
||||
- 用户授权主测试机可安装覆盖本 App、清理 App 测试数据、操作权限及蓝牙;自动测试点击使用 root,也不操作其他应用数据。
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
"""Workspace-owned private host-test state; importing this performs no I/O."""
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[3]
|
||||
LOCAL = ROOT / '测试相关资料/如何测试/本机测试环境/.local'
|
||||
PRIVATE = LOCAL / 'private'
|
||||
SSH_KNOWN_HOSTS = PRIVATE / 'qms-mobile-known_hosts'
|
||||
|
||||
|
||||
def private_directory():
|
||||
PRIVATE.mkdir(parents=True, exist_ok=True)
|
||||
return PRIVATE
|
||||
@@ -7,6 +7,7 @@ from pathlib import Path
|
||||
import re
|
||||
|
||||
import paramiko
|
||||
from local_test_paths import SSH_KNOWN_HOSTS
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[3]
|
||||
@@ -23,7 +24,7 @@ def connect():
|
||||
host = fields["IP"].strip()
|
||||
port_match = re.search(r"(?:^|\s)-p\s+(\d+)", fields["SSH"])
|
||||
port = int(port_match.group(1)) if port_match else 22
|
||||
trust = Path.home() / ".codex-tools/tmp/qms-mobile-known_hosts"
|
||||
trust = SSH_KNOWN_HOSTS
|
||||
trust.parent.mkdir(parents=True, exist_ok=True)
|
||||
client = paramiko.SSHClient()
|
||||
if trust.exists():
|
||||
|
||||
@@ -321,7 +321,8 @@ def main() -> int:
|
||||
raise RuntimeError("当前设备地址不是电脑热点网段")
|
||||
import paramiko
|
||||
keys = paramiko.HostKeys()
|
||||
keys.load(str(Path.home() / ".codex-tools/tmp/qms-mobile-known_hosts"))
|
||||
from local_test_paths import SSH_KNOWN_HOSTS
|
||||
keys.load(str(SSH_KNOWN_HOSTS))
|
||||
expected_key = next(iter(keys.lookup(fields["IP"].strip()).values()))
|
||||
board = connect_at(current_ip, expected_key, fields)
|
||||
original, backup_root, backup_unit = resume_configuration(board, fields)
|
||||
@@ -355,8 +356,8 @@ def main() -> int:
|
||||
"static_address": static_address, "hotspot_gateway": hotspot["gateway"],
|
||||
"wrong_password": "qms-invalid-password-2026",
|
||||
}
|
||||
private_tmp = Path.home() / ".codex-tools/tmp"
|
||||
private_tmp.mkdir(parents=True, exist_ok=True)
|
||||
from local_test_paths import private_directory
|
||||
private_tmp = private_directory()
|
||||
path = private_tmp / ("qms-wifi-test-" + secrets.token_hex(8) + ".json")
|
||||
path.write_text(json.dumps(values, ensure_ascii=False), encoding="utf-8")
|
||||
host_secret = path
|
||||
|
||||
@@ -82,7 +82,7 @@ Compose 的禁用语义可能位于父节点,文字节点自身仍 enabled。
|
||||
## 13. 按影响选测与独立模拟器(2026-09-29)
|
||||
|
||||
- 先读 [按影响选测](按影响选测.md),选中场景后才执行环境门禁。不能因为手机登记/网络不可用而阻塞不依赖它们的 JVM、模拟器或文档检查。需要真机但环境不可用时仍是“未验证”。
|
||||
- `--list-scenarios` / `--dry-run` 不导入远端联调依赖、不访问凭据或 ADB。电脑系统 Python 未装 Paramiko 时,优先复用本机测试环境的 `.venv` 并检查 import;不要给核桃派添加主机依赖。
|
||||
- `--list-scenarios` / `--dry-run` 不导入远端联调依赖、不访问凭据或 ADB。电脑系统 Python 未装 Paramiko 时,使用本机 `local_env.py setup ssh` 重建 `.local/ssh/venv` 并检查 import;不要给核桃派添加主机依赖。
|
||||
- com.android.test 插件已由同版本 AGP 放入 classpath 时,uiTest 使用无版本 `id("com.android.test")`;显式重复版本可能导致 unknown version 冲突。uiTest 的 Compose 测试库与现有 Compose Multiplatform 锁定版本一致。
|
||||
- 独立 uiTest 使用 self-instrumenting APK 和实际 Controller,不从反射篡改内部状态。fake RPC 必须遵循真实字段契约:内容条目需要 revision,缺失会在 thumbnailKey 中失败。此类夹具错误应修夹具,不弱化产品断言。
|
||||
- 真机 navigation 临时撤销扫描/连接权限,防止已有记忆触发自动重连;finally 恢复原权限并回读,不访问板端身份。不将此场景用于权限允许/拒绝的产品验收。
|
||||
@@ -94,3 +94,14 @@ Compose 的禁用语义可能位于父节点,文字节点自身仍 enabled。
|
||||
真实用户动画的首帧可能是 `path` 指向持久图片,演示动画则可能是内嵌 `image`。新增 BLE 图片接口时要先检查 `animations.playback_snapshot` 的实际首帧结构,并沿设备既有路径验证与解码规则读取两种形式;不能把 `path` 当作无图或错误参数。空动画仍应按不可播放条目处理。复测须覆盖用户动画和演示动画,并做全库图片只读读取;本轮修正和实测见 [内容缓存验收](../测试结果归档/2026-09-29_内容缓存/README.md)。
|
||||
|
||||
模拟器 AVD 名称若存在但启动提示系统目录不存在,先核对该名称的配置指向和镜像登记。保留旧配置,使用已安装镜像新建专用 AVD 再测试;不要因名称存在就反复启动,也不要擅自清空原 AVD。真机 instrumentation 前同时确认产品 APK 与 androidTest APK 已构建,只有测试 APK 时先补产品构建,再运行选中场景。
|
||||
|
||||
## 15. 项目本机环境迁移与中文路径(2026-10-01)
|
||||
|
||||
- 本项目专用 venv、AVD/系统镜像和私有主机状态使用 [本机环境入口](../../../测试相关资料/如何测试/本机测试环境/README.md),不再依赖全局项目目录。旧全局 AVD 索引存在不代表 AVD 数据存在,先检查实际目录;缺失的数据和主机密钥不能写成迁移成功。
|
||||
- venv 不能直接搬动后作为可移植环境:`pyvenv.cfg` 和入口脚本可能仍引用原位置。保留旧目录,用完整版本/哈希锁定 wheel 在新位置重建,再检查依赖与解释器。
|
||||
- 本机 Emulator 在中文路径下报告 `Could not write file`、损坏的中文路径和无法读取 kernel;同一系统镜像通过 ASCII 目录联接启动后 settings/baseline 通过,确认本次启动失败属于路径访问问题。用 `local_env.py ui-smoke android` 自动创建短期入口,镜像/AVD 留在项目内,不移动到全局目录或再次下载镜像。临时入口结束后移除,AVD 的持久 image 路径恢复为项目内位置。
|
||||
- AGP 构建入口传入 ASCII 目录联接时,不应先 `resolve()` 展开为中文目标;`build_android.py` 保留用户传入的 ASCII 拼写,构建实际写入项目 `.local/work/`。只读路径解析使用常规 resolve,不把此规则扩展到其他环境。
|
||||
- Emulator 可能把 `config.ini` 重写成 `key = value`,读取时应修剪键值空白,不能把格式变化误报为失效路径。复制项目后 setup 只刷新本工具管理的路径,保留用户数据。
|
||||
- Windows Python 控制台在诊断输出包含替换字符时可能触发 GBK 编码错误;仅对本次 Python 进程使用 `-X utf8`,不全局调整系统设置。
|
||||
|
||||
单次启动失败与复测结果记录在 `各种归档/2026-10-01_本机环境迁移/README.md`;模拟器结果不代表任何真机或板端验收。
|
||||
|
||||
@@ -29,6 +29,8 @@ python "移动端相关内容/安卓app/构建与发布/build_android.py" --work
|
||||
|
||||
路径实测:AGP 默认拒绝非 ASCII 路径;启用 `android.overridePathCheck=true` 后编译继续,但当前 JBR/Gradle 下 JVM 测试出现类加载失败。在 ASCII 隔离目录同一测试通过,故当前使用该回退。2026-09-25 已在全新且包含空格的 ASCII 构建根目录重新执行全部 92 个任务,JVM 测试及两个 debug APK 均成功;保留中文源码位置。
|
||||
|
||||
项目专用 UI 构建现使用 [本机环境入口](../../../测试相关资料/如何测试/本机测试环境/README.md) 的 `local_env.py build-ui android`:缓存与构建实际保存在项目 `.local/work/`,短期 ASCII 目录联接只作调用入口并在结束后移除。`build_android.py --work-root` 保留显式 ASCII 联接的拼写,避免先 resolve 展开为中文路径。产品 APK 原有版本、签名和交付流程不变。
|
||||
|
||||
## APK 与签名
|
||||
|
||||
- 应用名“奇妙小屏幕”,applicationId 为 `org.qimiaoscreen.controller`,minSdk 26,首版版本 0.1.0。
|
||||
|
||||
@@ -17,7 +17,9 @@ def main():
|
||||
parser.add_argument('--gradle', type=Path, help='Optional verified Gradle executable; otherwise use Wrapper')
|
||||
parser.add_argument('tasks', nargs='*', default=[':sharedCore:jvmTest', ':androidApp:assembleDebug'])
|
||||
args = parser.parse_args()
|
||||
root = args.work_root.resolve()
|
||||
# Keep an explicitly supplied ASCII junction spelling. Resolving it first
|
||||
# would expose the Chinese workspace path to AGP despite the alias.
|
||||
root = Path(os.path.abspath(args.work_root))
|
||||
if not str(root).isascii():
|
||||
parser.error('work-root must use ASCII characters')
|
||||
if not (args.jdk / 'bin/java.exe').is_file() or not (args.sdk / 'platforms').is_dir():
|
||||
|
||||
@@ -72,3 +72,7 @@ MOBILE-STATUS/DISCOVERY/PREVIEW:顶栏自动循环、扫描条目断开与
|
||||
DEVICE-MOBILE-LIBRARY-CACHE/MOBILE-LIBRARY-CACHE:设备协议 1.1 在主版本 1 下新增 `library_progressive`、`library.summary` 和 16×16 `library.preview`,保留既有 64×64 `library.thumbnail` 与旧目录契约。Android 0.2.2 使用分档缓存和渐进加载,旧设备回退现有方式;旧 App 可继续连接新设备。设备与 App 本轮均获用户明确迭代和部署授权。验证证据待本轮测试归档,不涉及驱动或当前帧输出。
|
||||
|
||||
兼容说明:原 mobile.transport 为 BLE 统计对象,保持原义;实际链路新增 active_transport,不改变旧字段类型。
|
||||
|
||||
## 2026-10-01 本机测试环境归属
|
||||
|
||||
项目专用 SSH/编辑器环境、Android 测试系统镜像与 AVD 迁入本机测试目录 `.local/`,搭建入口及锁定依赖进入源码管理,私有主机状态/临时材料不提交。Android 构建入口支持指向项目存储的短期 ASCII 联接;SSH 和 WiFi 测试私有路径改为工作区内。只改变测试基础设施;App、设备公共接口、协议、驱动和部署契约均不变,不发布产品 APK、不部署设备、不推进版本和 FEATURE_UPDATED_AT。
|
||||
|
||||
Reference in New Issue
Block a user