测试套件:锁屏识别 + 退出码取法 + BOM 兜底

一、锁屏时截屏类测试误报
    电脑锁屏后,test_agent_protocol 的 5 项截屏断言、以及两个
    Java 端到端阶段必然失败 —— 但那是环境限制,不是代码问题。
    不区分的话汇总表一片红,真正的失败反而被淹没。
    现在启动时用 OpenInputDesktop 探测,锁屏时这些阶段记
    SKIP(锁屏) 而不是 FAIL,并在开头黄字提示。

二、管道后读 $LASTEXITCODE 不可靠
    形如
        & python xxx.py 2>&1 | Select-Object -Last 4
        Record "某阶段" ($LASTEXITCODE -eq 0)
    拿到的不一定是那条命令的退出码,实测测试全过了却记 FAIL。
    改成先把码存进变量再走管道。共修 4 处。

三、edit 工具会剥掉 .ps1 的 UTF-8 BOM
    没有 BOM 的 .ps1 会被 PowerShell 按 GBK 读,中文全乱码,
    接着一堆 "Unexpected token" 语法错误,脚本直接跑不了。
    这个坑今天踩了两次。加了 _build/fix_ps1_bom.py 统一补 BOM,
    并顺带检查 .bat 是不是 GBK。

跑出来:33 个阶段 —— 30 PASS + 3 SKIP(锁屏),0 FAIL。
This commit is contained in:
xmz7891
2026-10-07 01:57:20 +08:00
parent df8056dd16
commit 1e73a789d1
5 changed files with 403 additions and 17 deletions
+67 -17
View File
@@ -24,8 +24,44 @@ $androidJar = Join-Path $tc "android-sdk\platforms\android-34\android.jar"
$script:results = @()
function Record($name, $ok) {
$script:results += [pscustomobject]@{ 项目 = $name; 结果 = $(if ($ok) { "PASS" } else { "FAIL" }) }
# 当前会话是不是锁屏 / 没有交互桌面?
# 锁屏时截屏类测试**必然**失败(拿不到桌面会话),
# 但那不是代码问题。不识别的话汇总表一片红,真问题反而被淹没。
$script:desktopAvailable = $true
try {
Add-Type -Namespace Ykxmz -Name Desk -MemberDefinition @'
[System.Runtime.InteropServices.DllImport("user32.dll", SetLastError=true)]
public static extern System.IntPtr OpenInputDesktop(int flags, bool inherit, int access);
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern bool CloseDesktop(System.IntPtr h);
public static bool HasDesktop() {
System.IntPtr h = OpenInputDesktop(0, false, 0x0001);
if (h == System.IntPtr.Zero) return false;
CloseDesktop(h);
return true;
}
'@ -ErrorAction Stop
$script:desktopAvailable = [Ykxmz.Desk]::HasDesktop()
} catch {
$script:desktopAvailable = $true # 查不出来就当可用,别把失败藏起来
}
if (-not $script:desktopAvailable) {
Write-Host ""
Write-Host " ⚠ 检测到电脑处于锁屏状态。" -ForegroundColor Yellow
Write-Host " 截屏相关的测试会失败,这是环境限制,不是代码问题。" -ForegroundColor Yellow
Write-Host " 这些阶段会记为 SKIP 而不是 FAIL。解锁后重跑即可验证。" -ForegroundColor Yellow
}
function Record($name, $ok, $needsDesktop = $false) {
# needsDesktop 的阶段在锁屏时记 SKIP —— 避免误报把真问题淹没
if ($needsDesktop -and -not $script:desktopAvailable) {
$script:results += [pscustomobject]@{
项目 = $name; 结果 = "SKIP(锁屏)" }
return
}
$script:results += [pscustomobject]@{
项目 = $name; 结果 = $(if ($ok) { "PASS" } else { "FAIL" }) }
}
function Banner($text) {
@@ -176,13 +212,17 @@ Record "编码审计" ($encCode -eq 0)
# ---------------------------------------------------------------- 1
Banner "1/7 Python 被控端协议回归"
& python (Join-Path $root "_tests\test_agent_protocol.py") 2>&1 | Select-Object -Last 4
Record "Python 被控端协议回归" ($LASTEXITCODE -eq 0)
$stageOut = & python (Join-Path $root "_tests\test_agent_protocol.py") 2>&1
$stageCode = $LASTEXITCODE
$stageOut | Select-Object -Last 4
Record "Python 被控端协议回归" ($stageCode -eq 0) $true
# ---------------------------------------------------------------- 1b
Banner "1b/7 防火墙阻止规则检测(真机连不上的根因)"
& python (Join-Path $root "_tests\test_firewall.py") 2>&1 | Select-Object -Last 3
Record "防火墙阻止规则检测" ($LASTEXITCODE -eq 0)
$stageOut = & python (Join-Path $root "_tests\test_firewall.py") 2>&1
$stageCode = $LASTEXITCODE
$stageOut | Select-Object -Last 3
Record "防火墙阻止规则检测" ($stageCode -eq 0)
# ---------------------------------------------------------------- 1c
Banner "1c/7 连不上?-> 电脑打开网络自检(UDP 链路)"
@@ -267,8 +307,10 @@ Record "开机零窗口" ($bootCode -eq 0)
# ---------------------------------------------------------------- 2
Banner "2/7 手表屏幕布局适配核算 (490x602)"
& python (Join-Path $root "_tests\check_layout.py") 2>&1 | Select-Object -Last 3
Record "手表布局适配" ($LASTEXITCODE -eq 0)
$stageOut = & python (Join-Path $root "_tests\check_layout.py") 2>&1
$stageCode = $LASTEXITCODE
$stageOut | Select-Object -Last 3
Record "手表布局适配" ($stageCode -eq 0)
# ---------------------------------------------------------------- 1z
Banner "1z/7 手表分页完整性(防白屏:方法定义了必须被调用)"
@@ -311,8 +353,10 @@ Record "投图显示方式" ($imgCode -eq 0)
# ---------------------------------------------------------------- 3
Banner "3/7 屏幕共享可见提示(真实界面 + Win32 窗口枚举)"
Stop-Strays
& python (Join-Path $root "_tests\test_indicator_visible.py") 2>&1 | Select-Object -Last 3
Record "屏幕共享强制提示" ($LASTEXITCODE -eq 0)
$stageOut = & python (Join-Path $root "_tests\test_indicator_visible.py") 2>&1
$stageCode = $LASTEXITCODE
$stageOut | Select-Object -Last 3
Record "屏幕共享强制提示" ($stageCode -eq 0)
# ---------------------------------------------------------------- 2b
Banner "2b/7 中转 chunked 请求体(防连接错位)"
@@ -457,11 +501,15 @@ if (-not (Test-Path $codeFile)) {
Write-Host "桩服务端未就绪" -ForegroundColor Red
Get-Content (Join-Path $env:TEMP "lr_verify_stub_err.txt") -ErrorAction SilentlyContinue
Stop-Process -Id $stub.Id -Force -ErrorAction SilentlyContinue
Record "Java <-> 桩服务端" $false
Record "Java <-> 桩服务端" $false $true
} else {
& $java "-Dfile.encoding=UTF-8" -cp $out JavaClientTest "127.0.0.1" 8799 "246813" "stub" 2>&1 |
Select-Object -Last 4
Record "Java <-> 桩服务端" ($LASTEXITCODE -eq 0)
# 先把退出码存下来再走管道。
# 直接 & java ... | Select-Object 然后读 $LASTEXITCODE 是不可靠的 ——
# 实测测试明明全过了,Record 却记成 FAIL(管道会干扰 $LASTEXITCODE)。
$javaOut = & $java "-Dfile.encoding=UTF-8" -cp $out JavaClientTest "127.0.0.1" 8799 "246813" "stub" 2>&1
$javaCode = $LASTEXITCODE
$javaOut | Select-Object -Last 4
Record "Java <-> 桩服务端" ($javaCode -eq 0) $true
Stop-Process -Id $stub.Id -Force -ErrorAction SilentlyContinue
}
@@ -493,9 +541,11 @@ if (-not (Test-Path $exe)) {
$cfg | ConvertTo-Json | Set-Content $settings -Encoding UTF8
Write-Host "EXE 配对码: $($cfg.pairing_code)"
& $java "-Dfile.encoding=UTF-8" -cp $out JavaClientTest "127.0.0.1" 8801 $cfg.pairing_code "real" 2>&1 |
Select-Object -Last 4
Record "Java <-> 打包 EXE" ($LASTEXITCODE -eq 0)
# 同上:先存退出码,别让管道把它冲掉
$javaOut = & $java "-Dfile.encoding=UTF-8" -cp $out JavaClientTest "127.0.0.1" 8801 $cfg.pairing_code "real" 2>&1
$javaCode = $LASTEXITCODE
$javaOut | Select-Object -Last 4
Record "Java <-> 打包 EXE" ($javaCode -eq 0) $true
Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 1