skills/check-test-code-quality/rules/R001/SKILL.md
# R001: 禁止使用getSync系统接口 ## 规则元数据 | 字段 | 值 | |------|-----| | 规则ID | R001 | | 规则名称 | 禁止使用getSync系统接口 | | 严重级别 | Critical | | 规则类别 | simple(简单规则,可用grep直接检测) | | 问题类型 | 源代码规范 | | 修复建议 | 使用`canIUse`接口替代或`差异化API`接口替代 | ## 问题描述 多设备XTS适配禁止使用任何形式的`getSync()`系统接口。`getSync()`是同步阻塞调用,在多设备测试场景中会导致死锁或超时问题。 **注意**: 本规则只针对**系统参数模块**的`getSync()`调用(如`@ohos.systemparameter`),不针对应用API的`getSync()`(如`mPreference.getSync()`)。 ## 扫描范围 ### 文件类型(关键) R001必须扫描**所有源代码文件**,不仅仅是测试文件: | 文件类型 | 扩展名 | 是否扫描 | |---------
npx skillsauth add openharmonyinsight/openharmony-skills skills/check-test-code-quality/rules/R001Install this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
| 字段 | 值 |
|------|-----|
| 规则ID | R001 |
| 规则名称 | 禁止使用getSync系统接口 |
| 严重级别 | Critical |
| 规则类别 | simple(简单规则,可用grep直接检测) |
| 问题类型 | 源代码规范 |
| 修复建议 | 使用canIUse接口替代或差异化API接口替代 |
多设备XTS适配禁止使用任何形式的getSync()系统接口。getSync()是同步阻塞调用,在多设备测试场景中会导致死锁或超时问题。
注意: 本规则只针对系统参数模块的getSync()调用(如@ohos.systemparameter),不针对应用API的getSync()(如mPreference.getSync())。
R001必须扫描所有源代码文件,不仅仅是测试文件:
| 文件类型 | 扩展名 | 是否扫描 |
|---------|--------|---------|
| ArkTS源代码 | .ets | 是 |
| TypeScript源代码 | .ts | 是 |
| JavaScript源代码 | .js | 是 |
| 配置文件 | BUILD.gn, Test.json等 | 否 |
def get_all_source_files(directory: str) -> List[str]:
"""
获取所有源代码文件(包括测试文件和非测试文件)
扫描文件类型: .ets, .ts, .js
Args:
directory: 扫描目录
Returns:
源代码文件路径列表
"""
source_files = []
source_extensions = ['.ets', '.ts', '.js']
for root, dirs, files in os.walk(directory):
for file in files:
if any(file.endswith(ext) for ext in source_extensions):
source_files.append(os.path.join(root, file))
return source_files
必须确认文件中存在以下任一import模式,才继续检测getSync调用:
import_patterns = [
r'import\s+.*\s+from\s+[\'"]@ohos\.systemparameter[\'"]',
r'import\s+.*\s+from\s+[\'"]@ohos\.systemParameterEnhance[\'"]',
r'import\s+.*\{.*systemParameter.*\}\s+from\s+[\'"]@kit\.BasicServicesKit[\'"]',
r'import\s+.*\{.*systemParameterEnhance.*\}\s+from\s+[\'"]@kit\.BasicServicesKit[\'"]'
]
关键: 必须先确认import存在,再检测getSync调用。这样可以避免误报应用API的getSync。
注意: @ohos.systemparameter(小写p)和 @ohos.systemParameterEnhance(大写P)是两个不同的模块名,必须分别匹配,不能仅用大小写不敏感的正则。同时必须覆盖 default import(import xxx from)和 named import(import { xxx } from)两种形式。
getsync_pattern = r'(\w+)\.getSync\s*\('
从import语句中提取变量名,然后确认getSync调用使用的变量名与之匹配。
例如:
import parameter from '@ohos.systemparameter' → 变量名parameter → 检测parameter.getSync(import systemParameterEnhance from '@ohos.systemParameterEnhance' → 变量名systemParameterEnhance → 检测systemParameterEnhance.getSync(import { systemParameter } from '@kit.BasicServicesKit' → 变量名systemParameter → 检测systemParameter.getSync(import re
import os
def check_r001(file_path: str, base_dir: str = '') -> list:
"""
检测R001问题:禁止使用getSync系统接口
Args:
file_path: 文件绝对路径
base_dir: 基准目录(用于计算相对路径)
Returns:
问题列表,每条问题包含: rule, type, severity, file, line, testcase, snippet, suggestion
"""
issues = []
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
lines = content.split('\n')
full_content = content
# 第一步:检测系统参数模块的import
# 必须同时覆盖 named import 和 default import
# 必须同时覆盖 @ohos.systemparameter 和 @ohos.systemParameterEnhance(大小写不同)
import_patterns = [
# Named import: import { systemParameterEnhance } from '@ohos.systemParameterEnhance'
r'import\s+\{([^}]+)\}\s+from\s+[\'"]@ohos\.systemparameter[\'"]',
r'import\s+\{([^}]+)\}\s+from\s+[\'"]@ohos\.systemParameterEnhance[\'"]',
# Default import: import parameter from '@ohos.systemparameter'
r'import\s+(\w+)\s+from\s+[\'"]@ohos\.systemparameter[\'"]',
r'import\s+(\w+)\s+from\s+[\'"]@ohos\.systemParameterEnhance[\'"]',
# @kit.BasicServicesKit (仅 named import)
r'import\s+\{([^}]*\b(?:systemParameter|systemParameterEnhance)\b[^}]*)\}\s+from\s+[\'"]@kit\.BasicServicesKit[\'"]',
]
has_system_param_import = False
system_param_vars = set()
for pattern in import_patterns:
for match in re.finditer(pattern, full_content):
has_system_param_import = True
if match.lastindex and match.group(1):
system_param_vars.add(match.group(1))
else:
named_match = re.search(
r'\b(systemParameter|systemParameterEnhance)\b',
match.group(0)
)
if named_match:
system_param_vars.add(named_match.group(1))
if not has_system_param_import:
return issues
# 第二步:检测getSync调用
getsync_pattern = r'(\w+)\.getSync\s*\('
for i, line in enumerate(lines, 1):
for match in re.finditer(getsync_pattern, line):
var_name = match.group(1)
# 第三步:确认是系统参数模块的变量
if var_name in system_param_vars:
rel_path = os.path.relpath(file_path, base_dir) if base_dir else file_path
testcase = find_testcase(lines, i)
issues.append({
'rule': 'R001',
'type': '禁止使用getSync系统接口',
'severity': 'Critical',
'file': rel_path,
'line': i,
'testcase': testcase,
'snippet': line.strip(),
'suggestion': (
f"多设备XTS适配禁止使用getSync()系统接口。"
f"请使用canIUse接口替代或差异化API接口替代。"
)
})
return issues
def find_testcase(lines: list, target_line: int) -> str:
"""
查找目标行所在的it()块,提取testcase名称
Args:
lines: 文件所有行(0-indexed list)
target_line: 目标行号(1-indexed)
Returns:
testcase名称,或 '-'
"""
it_pattern = re.compile(r"\bit\s*\(\s*['\"]([^'\"]+)['\"]")
best_it_name = '-'
best_it_start = -1
for i, line in enumerate(lines):
match = it_pattern.search(line)
if match and (i + 1) <= target_line:
if (i + 1) > best_it_start:
best_it_name = match.group(1)
best_it_start = i + 1
if best_it_start > 0 and best_it_start <= target_line:
return best_it_name
return '-'
def scan_directory(directory: str) -> list:
"""
扫描目录中所有源代码文件的R001问题
Args:
directory: 扫描目录
Returns:
所有问题列表
"""
all_issues = []
source_extensions = ['.ets', '.ts', '.js']
for root, dirs, files in os.walk(directory):
for file in files:
if any(file.endswith(ext) for ext in source_extensions):
file_path = os.path.join(root, file)
issues = check_r001(file_path, directory)
all_issues.extend(issues)
return all_issues
| 检测项 | 要求 |
|--------|------|
| 检测所有形式的getSync()调用 | 必须 |
| 支持多个import语句 | 必须 |
| 支持变量引用(如parameter.getSync()) | 必须 |
| 不检测应用API的getSync(如mPreference.getSync()) | 必须 |
| 确认系统参数import存在后才报告 | 必须 |
| 同时覆盖 @ohos.systemparameter 和 @ohos.systemParameterEnhance 两种大小写 | 必须 |
| 同时处理 named import({ })和 default import(无 { }) | 必须 |
| 处理多行 import 语句 | 建议 |
每条issue必须包含以下字段:
{
'rule': 'R001', # 问题规则编号
'type': '禁止使用getSync系统接口', # 问题类型描述
'severity': 'Critical', # 严重级别
'file': 'rel/path.test.ets', # 相对文件路径
'line': 25, # 问题行号
'testcase': 'testGetSync', # 所属用例名称(it()的第一个参数),无对应用例时为 '-'
'snippet': 'parameter.getSync(...)', # 问题代码片段
'suggestion': '...' # 修复建议
}
-it()块内的问题(如import语句、describe级别的代码):testcase字段为 -it()块内的问题:取it('后面的第一个字符串参数import parameter from '@ohos.systemparameter';
export default function test() {
describe('test', () => {
it('test001', () => {
let value = parameter.getSync('key'); // ✗ 错误:使用了getSync系统接口
expect(value).assertEqual('expected');
});
});
}
import systemParameterEnhance from '@ohos.systemParameterEnhance';
export default function test() {
describe('test', () => {
it('test001', () => {
let value = systemParameterEnhance.getSync('key'); // ✗ 错误:使用了getSync系统接口
expect(value).assertEqual('expected');
});
});
}
import { systemParameter } from '@kit.BasicServicesKit';
export default function test() {
describe('test', () => {
it('test001', () => {
let value = systemParameter.getSync('key'); // ✗ 错误:使用了getSync系统接口
expect(value).assertEqual('expected');
});
});
}
import { BusinessError } from '@kit.BasicServicesKit';
export default function test() {
describe('test', () => {
it('test001', () => {
if (canIUse("SystemCapability.xxx")) {
// 基于能力的判断
}
});
});
}
import { BusinessError } from '@kit.BasicServicesKit';
export default function test() {
describe('test', () => {
it('test001', async (done: Function) => {
try {
// 使用异步API替代getSync
let value = await parameter.get('key');
expect(value).assertEqual('expected');
done();
} catch (error) {
expect(error.code).assertEqual(17100001);
done();
}
});
});
}
import preferences from '@ohos.data.preferences';
export default function test() {
describe('test', () => {
it('test001', () => {
let value = mPreference.getSync('key'); // ✓ 正确:这是应用API,不是系统接口
expect(value).assertEqual('expected');
});
});
}
严重性: 极高
问题描述: R001不仅存在于测试文件(.test.ets)中,也存在于非测试源代码文件(如.ets页面文件、.ts模块文件、Ability文件等)。
错误做法:
# 错误: 只扫描测试文件
test_files = get_test_files(directory) # 只返回 .test.ets/.test.ts/.test.js
for fp in test_files:
check_r001(fp, ...) # 漏掉 Ability/Page 等文件中的 getSync
正确做法:
# 正确: R001 应扫描所有源代码文件
source_files = get_all_source_files(directory) # 返回所有 .ets/.ts/.js
for fp in source_files:
check_r001(fp, ...)
影响: 使用get_test_files()而非get_all_source_files()会导致约81个R001问题漏报。
规则分类参考:
| 规则类别 | 扫描范围 | 相关规则 | 文件扫描函数 |
|---------|---------|---------|------------|
| 源代码规范 | 所有源代码文件 | R001, R005, R006 | get_all_source_files() |
| 测试代码规范 | 仅测试文件 | R002, R003, R004, R015, R016, R018 | get_test_files() |
| 配置文件 | 配置文件 | R007, R010, R012, R014, R017 | 特殊处理 |
问题描述: 不是所有getSync()调用都违反R001。只有系统参数模块(@ohos.systemparameter等)的getSync()才是禁止的。应用API(如@ohos.data.preferences的mPreference.getSync())是允许的。
检测策略: 必须先确认文件中存在系统参数模块的import语句,然后再检测getSync调用,且调用变量必须与import的变量名匹配。
严重性: 严重
问题描述: 系统参数模块存在两种大小写形式的模块名,正则表达式必须同时覆盖,否则会漏检大量问题。
| 模块名形式 | 示例 | 出现频率 |
|-----------|------|---------|
| 小写 | @ohos.systemparameter | 较少 |
| 大写P | @ohos.systemParameterEnhance | 主要形式(约70条) |
正确做法(同时覆盖两种大小写):
import_patterns = [
r'import\s+\{([^}]+)\}\s+from\s+["\']@ohos\.systemparameter["\']',
r'import\s+\{([^}]+)\}\s+from\s+["\']@ohos\.systemParameterEnhance["\']',
r'import\s+\{([^}]+)\}\s+from\s+["\']@kit\.BasicServicesKit["\']',
]
详见 references/TRAPS.md 陷阱3。
严重性: 严重
问题描述: 系统参数模块的导入有两种语法形式。如果只处理 named import(大括号形式),会漏检 default import 形式。
| 导入形式 | 语法 | 出现频率 |
|---------|------|---------|
| Named import | import { systemParameterEnhance } from '@ohos.systemParameterEnhance' | 较多 |
| Default import | import parameter from '@ohos.systemparameter' | 约41条 |
正确做法(同时处理两种导入形式):
# Named import: import { xxx } from '...'
named_import_re = re.compile(
r'import\s+\{([^}]+)\}\s+from\s+["\'](@ohos\.systemparameter(?:Enhance)?|@kit\.BasicServicesKit)["\']'
)
# Default import: import xxx from '...'
default_import_re = re.compile(
r'import\s+(\w+)\s+from\s+["\'](@ohos\.systemparameter(?:Enhance)?|@kit\.BasicServicesKit)["\']'
)
# 使用 re.finditer(而非 re.search)以支持同一文件中的多个导入
详见 references/TRAPS.md 陷阱4。
严重性: 低
部分文件的 import 语句跨多行书写,单行正则无法匹配。扫描前将多行 import 合并为单行即可。
详见 references/TRAPS.md 陷阱2(R001/R005/R006须扫描所有源文件)。
testing
--- name: ohos-req-value-decision description: Use after review meeting to record decision and route to next step. Triggers: 评审决策纪要, 评审结论回流, value decision, 评审接纳, 评审不接纳, 评审退回, 下次重新上会. Do NOT use for feature baseline (ohos-req-feature-baseline), review gate checks (ohos-req-review-gate), or IR generation (ohos-req-feature-to-ir). metadata: author: openharmony scope: common stage: requirements capability: value-decision version: 0.3.0 status: draft tags: - sdd - requirements
development
Use when converting an OpenHarmony requirement document, spec, or design proposal into an OpenHarmony review slide deck (需求评审 / 需求变更评审 / 设计评审 PPTX) — produces the fixed OpenHarmony-branded review-deck structure (OH logo on every page) with architecture/flow diagrams and field tables. Triggers on "需求评审PPT", "需求变更评审", "把需求文档转成评审PPT", "spec转评审PPT", "requirement/spec to review deck". NOT for arbitrary or generic slide decks unrelated to OpenHarmony requirement/design review.
testing
Use when performing the Phase 0 Step 0.5 Review Ready Gate on a 04-feature.md, especially when the user says "evaluate gate", "review readiness", "feature ready?", "should we generate IR", or when the ohos-req-intake-orchestration main session needs a structured Ready / Conditional Ready / Not Ready judgment instead of doing the check inline. Reads 01-04, runs seven fixed checks plus a conditional-items check, and returns a machine-readable JSON summary plus a human-readable table that the main session can route on. Do NOT use for feature baseline generation (ohos-req-feature-baseline), value decision recording (ohos-req-value-decision), or IR generation (ohos-req-feature-to-ir).
testing
--- name: ohos-req-requirement-intake description: Use when importing an OHOS requirement into Phase 0.1, especially for 01-requirement.md, requirement intake, background, user value, scenarios, scope, FR/NFR, affected modules, or priority. Triggers: 需求导入, 01-requirement, 需求基线, RR单号. Do NOT use for feasibility analysis (ohos-req-feasibility-analysis), architecture decision (ohos-req-arch-decision), or feature baseline (ohos-req-feature-baseline). metadata: author: openharmony scope: common