Python 调用 flutter test 时,为什么 --name 没有按预期筛选测试?
结论:现有日志不能证明 --name 失效
你给出的 subprocess.run() 参数列表写法是正确的。默认情况下,--name 和 tp001 会作为两个参数传给 flutter,不需要额外加引号,也不需要设置 shell=True。
目前展示的 loading ...tp010_model_test.dart 说明测试文件正在加载,不能据此判断文件中的所有测试都执行了。仅凭这段输出,无法判断筛选是否失效,更无法确定根因。
为什么会加载其他测试文件?
--name 按测试的完整名称进行正则匹配,完整名称包含所属的 group 名称。它不按文件名筛选,也不专门按 group 标识符筛选。
例如:
group('tp001', () {
test('adds two numbers', () {
expect(1 + 1, 2);
});
});
这个测试的完整名称包含 tp001,因此可以匹配 --name tp001。如果其他测试的完整名称也包含 tp001,它们同样可能匹配。
当命令以 ut 目录为测试目标时,测试运行器可能需要加载多个文件,才能发现其中的测试并应用名称筛选。所以,文件名包含 tp010,不代表该文件中的测试一定匹配或不匹配 tp001。
应查看完整输出中的实际测试名称和最终执行数量。日志中的 +0 是当时的成功计数,不能作为“所有测试已经运行”的证据。
先修正打印变量不一致的问题
示例定义并执行的是 cmd,打印的却是 cmd2:
print('HERE0', cmd2)
如果 cmd2 没有定义,代码会在启动测试前抛出 NameError;如果它已经定义,打印内容也不一定反映实际执行的命令。先统一变量,再输出完整结果:
import subprocess
cmd = [
'flutter', 'test',
'--coverage', '--branch-coverage',
'ut', '--name', 'tp001',
]
print('Command:', cmd, flush=True)
result = subprocess.run(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
)
print(result.stdout)
print('Exit code:', result.returncode)
stdout=subprocess.PIPE 用于捕获输出,stderr=subprocess.STDOUT 用于合并错误输出。这两个选项都不会改变测试名称筛选。
如果确实执行了不匹配的测试,再比较调用环境
先确认 Bash 和 Python 实际运行的是同一个命令。由于没有给出 do_ut tp001 的脚本定义,它可能还会切换目录、设置环境变量或调用特定的 Flutter 路径。
可以在 Bash 中检查:
pwd
type -a flutter
再在 Python 中检查:
import os
import shutil
print('Working directory:', os.getcwd())
print('Flutter executable:', shutil.which('flutter'))
重点核对工作目录、Flutter 可执行文件和相关环境变量。Python 默认继承启动它的进程环境,但从 IDE、终端或其他脚本启动时,环境可能不同。Bash 中的 alias、function 或包装脚本也可能改变实际调用行为。
如果工作目录不同,可以通过 cwd 显式指定项目根目录:
result = subprocess.run(
cmd,
cwd='/absolute/path/to/flutter_project',
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True,
)
请把示例路径替换为实际项目路径。若 Flutter 路径不同,也可以把 cmd 的第一个元素改为已确认的可执行文件绝对路径。
怎样确认筛选真的生效?
找一个完整名称明确不包含 tp001 的测试,检查它是否出现在实际执行记录中。如果只有对应文件的 loading 日志,还不能认定筛选失败。
如果只想扫描某个测试文件,可以将命令中的 ut 改成已确认的文件路径,并保留 --name tp001。文件路径限制测试发现范围,--name 继续筛选该文件中的测试名称。
不要在 Python 参数列表中把值写成 "'tp001'"。列表调用不会像 Shell 那样去掉这些引号,它们会成为匹配表达式的一部分。
备注:内容仅供参考。
