HarmonyOS5 折叠屏适配测试:验证应用在展开/折叠状态下的UI自适应

127 阅读2分钟

以下为 ​​HarmonyOS 5多语言自动化测试的完整ArkTS实现方案​​,包含文本验证、布局检测和异常处理的代码示例:


1. 多语言测试架构

image.png


2. 核心测试逻辑

2.1 语言环境切换器

// locale-switcher.ets
import { I18n } from '@ohos.i18n';

export async function setTestLocale(locale: string) {
  await I18n.setSystemLanguage(locale);
  await I18n.setSystemRegion(locale.split('-')[1] || '');
}

export const SUPPORTED_LOCALES = [
  'en-US', 'zh-CN', 'ar-SA', 'ja-JP', 'ru-RU', 
  'fr-FR', 'es-ES', 'de-DE', 'hi-IN', 'pt-BR',
  'it-IT', 'ko-KR', 'th-TH', 'vi-VN', 'tr-TR',
  'nl-NL', 'pl-PL', 'uk-UA', 'ms-MY', 'fa-IR'
];

2.2 自动化测试循环

// locale-test.ets
import { describe, it } from '@ohos/test';
import { setTestLocale, SUPPORTED_LOCALES } from './locale-switcher';

describe('多语言测试套件', () => {
  SUPPORTED_LOCALES.forEach(locale => {
    describe(`语言环境: ${locale}`, () => {
      beforeAll(() => setTestLocale(locale));

      it('文本应正确渲染', () => verifyTextRender());
      it('布局不应溢出', () => checkLayoutOverflow());
      it('特殊字符应处理', () => testSpecialCharacters());
    });
  });
});

3. 文本验证方案

3.1 文本内容断言

// text-validator.ets
import { byI18nKey } from '@ohos.test';

export function verifyTextRender() {
  const testCases = [
    { key: 'welcome.title', maxLength: 30 },
    { key: 'button.submit', forbidden: ['<', '>'] }
  ];

  testCases.forEach(({ key, ...rules }) => {
    const element = byI18nKey(key).findOne();
    expect(element).toMatchRules(rules);
  });
}

// 扩展匹配规则
declare module '@ohos.test' {
  interface Matchers {
    toMatchRules(rules: {
      maxLength?: number,
      forbidden?: string[]
    }): void;
  }
}

3.2 特殊字符检测

// special-chars.ets
export function testSpecialCharacters() {
  const specialTexts = [
    '阿拉伯文本: كلمة',
    '泰语文本: คำ',
    '混合文本: こんにちはHello'
  ];

  specialTexts.forEach(text => {
    const element = byText(new RegExp(text)).findOne();
    expect(element).toHaveValidRender();
  });
}

4. 布局适配检查

4.1 文本溢出检测

// layout-checker.ets
import { Measure } from '@ohos.arkui';

export function checkLayoutOverflow() {
  const containers = ['header', 'item-card', 'button'];

  containers.forEach(id => {
    const container = byId(id).findOne();
    const text = container.findChild(byType(Text));
    
    const containerWidth = Measure.getWidth(container);
    const textWidth = Measure.getTextWidth(text);
    
    expect(textWidth).toBeLessThan(containerWidth);
  });
}

4.2 动态字体调整

// font-check.ets
export function verifyFontScaling() {
  const testElements = [    { id: 'main-title', minSize: 16, maxSize: 24 },    { id: 'body-text', minSize: 12, maxSize: 16 }  ];

  testElements.forEach(({ id, minSize, maxSize }) => {
    const text = byId(id).findOne();
    const fontSize = text.getComputedStyle().fontSize;
    
    expect(fontSize).toBeWithin(minSize, maxSize);
  });
}

5. 双向文本测试 (RTL/LTR)

5.1 布局方向验证

// rtl-test.ets
export function testRtlLayout() {
  const rtlLangs = ['ar', 'fa', 'he'];
  const currentLang = I18n.getCurrentLanguage();
  
  const expectDirection = rtlLangs.includes(currentLang) ? 
    'rtl' : 'ltr';

  const containers = byType(Flex).filter(c => 
    c.props.direction === 'row'
  );

  containers.forEach(container => {
    expect(container.getComputedStyle().flexDirection)
      .toBe(expectDirection);
  });
}

5.2 文本对齐检查

// alignment-test.ets
export function checkTextAlignment() {
  const rtlLangs = ['ar', 'fa', 'he'];
  const isRtl = rtlLangs.includes(I18n.getCurrentLanguage());

  const texts = byType(Text).filter(t => 
    t.props.textAlign === undefined
  );

  texts.forEach(text => {
    const expected = isRtl ? 'right' : 'left';
    expect(text.getComputedStyle().textAlign).toBe(expected);
  });
}

6. 异常处理方案

6.1 缺失翻译检测

// missing-locale.ets
export function checkMissingTranslations() {
  const defaultTexts = I18n.getResources('en-US');
  const currentTexts = I18n.getCurrentResources();

  Object.keys(defaultTexts).forEach(key => {
    if (!currentTexts[key]) {
      recordMissingKey(key);
    }
  });
}

function recordMissingKey(key: string) {
  console.error(`缺失翻译键: ${key}`);
  TestTracker.markFailure('MISSING_TRANSLATION');
}

6.2 文本截断处理

// truncation-handler.ets
export function handleTextOverflow() {
  const overflowing = byType(Text).filter(t => 
    t.getComputedStyle().textOverflow === 'ellipsis'
  );

  overflowing.forEach(text => {
    const content = text.props.text;
    if (content.length > 50) { // 超过50字符需检查
      TestTracker.markWarning('LONG_TEXT_TRUNCATED', {
        key: text.dataset.i18nKey,
        length: content.length
      });
    }
  });
}

7. 测试报告生成

7.1 多语言结果聚合

// report-generator.ets
export function generateLocaleReport() {
  const results = TestTracker.getResults();
  const locales = SUPPORTED_LOCALES.map(locale => ({
    locale,
    passed: results.filter(r => 
      r.suite.includes(locale) && r.passed
    ).length,
    warnings: results.filter(r => 
      r.suite.includes(locale) && r.type === 'WARNING'
    ).length
  }));

  return {
    summary: {
      total: SUPPORTED_LOCALES.length,
      passed: locales.filter(l => l.passed === 3).length,
      warnings: locales.reduce((sum, l) => sum + l.warnings, 0)
    },
    details: locales
  };
}

7.2 可视化报告

// visual-report.ets
import { Chart } from '@ohos.report';

export function renderLocaleChart(data: any) {
  new Chart({
    type: 'bar',
    data: data.details.map(d => ({
      x: d.locale,
      y: d.passed,
      color: d.passed === 3 ? '#4CAF50' : '#FFC107'
    })),
    title: '多语言测试通过率'
  }).render('locale-report.html');
}

8. 完整测试工作流

8.1 测试入口文件

// main-test.ets
import { runLocaleTests } from './locale-test';
import { generateLocaleReport } from './report-generator';

async function main() {
  await runLocaleTests();
  const report = generateLocaleReport();
  
  if (report.summary.passed < report.summary.total) {
    process.exit(1); // 存在失败用例
  }
}

main();

8.2 CI/CD集成

# .github/workflows/i18n.yml
name: I18n Test
on: [push]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: huawei/multilang-test-action@v1
        with:
          locales: 'en-US,zh-CN,ar-SA,ja-JP'
          check-missing: true

9. 关键质量指标

指标合格标准测量工具
翻译覆盖率100%键值覆盖checkMissingTranslations
文本溢出率<1%文本容器checkLayoutOverflow
RTL正确率100%方向正确testRtlLayout
字体缩放合规100%在安全范围内verifyFontScaling

10. 常见问题解决方案

问题现象解决方案代码修改示例
阿拉伯语文本反向强制设置textDirectionText().textDirection(rtl ? 'rtl' : 'ltr')
长德语单词断行添加hyphens样式.style({ hyphens: 'auto' })
泰语字符截断调整lineHeight.lineHeight(1.5)
混合语言对齐问题明确指定textAlign.textAlign('start')