Back to Repositories

Validating Multi-Platform Build Processes in dcloudio/uni-app

This test suite validates static asset handling and build processes across multiple platforms in the uni-app framework. It systematically tests both development and production builds for various platforms including web, mobile, and mini-program targets.

Test Coverage Overview

The test suite provides comprehensive coverage of build and development processes across uni-app and uni-app-x platforms.

Key areas tested include:
  • Development builds for multiple platforms (app, harmony, various mp platforms)
  • Production builds for web (H5), native apps, and mini-programs
  • Platform-specific output verification
  • Cross-platform asset handling

Implementation Analysis

The testing approach utilizes Jest’s asynchronous testing capabilities to validate build processes across different platforms. It implements dynamic test generation based on platform configurations, using environment variables to control build behavior.

Technical patterns include:
  • Dynamic test case generation using forEach loops
  • Environment variable injection for build configuration
  • Snapshot testing for build output verification
  • Asynchronous process execution using execa

Technical Details

Testing infrastructure includes:
  • Jest as the primary testing framework
  • fs-extra for file system operations
  • execa for process execution
  • fast-glob for file pattern matching
  • Custom path normalization utilities
Configuration includes:
– Extended timeout (50s) for build processes
– Custom output directory management
– Platform-specific environment variables

Best Practices Demonstrated

The test suite exemplifies several testing best practices for build system validation.

Notable practices include:
  • Systematic platform coverage
  • Clean state management between tests
  • Consistent output verification
  • Automated cleanup of build artifacts
  • Modular test organization
  • Clear separation of build modes and platforms

dcloudio/uni-app

packages/playground/__tests__/static.spec.ts

            
import fs from 'fs-extra'
import path from 'path'
import execa from 'execa'
import { sync } from 'fast-glob'
import { normalizePath } from '@dcloudio/uni-cli-shared'

const projectDir = path.resolve(__dirname, '../static')

describe('static playground', () => {
  jest.setTimeout(50 * 1000)
  const types = {
    'uni-app': [
      // dev 目前面临需要exit的问题
      'dev:app',
      'dev:app-harmony',
      'dev:mp-alipay',
      'dev:mp-baidu',
      'dev:mp-kuaishou',
      'dev:mp-lark',
      'dev:mp-qq',
      'dev:mp-toutiao',
      'dev:mp-weixin',
      'build:app',
      'build:app-harmony',
      'build:h5',
      'build:mp-alipay',
      'build:mp-baidu',
      'build:mp-kuaishou',
      'build:mp-lark',
      'build:mp-qq',
      'build:mp-toutiao',
      'build:mp-weixin',
    ],
    'uni-app-x': [
      'dev:app-android',
      'dev:app-harmony',
      'dev:app-ios',
      'build:app-android',
      'build:app-harmony',
      'build:app-ios',
      'build:h5',
      //   'build:mp-alipay',
      //   'build:mp-baidu',
      //   'build:mp-kuaishou',
      //   'build:mp-lark',
      //   'build:mp-qq',
      //   'build:mp-toutiao',
      //   'build:mp-weixin',
    ],
  }
  const distDir = path.resolve(projectDir, 'dist')
  if (fs.existsSync(distDir)) {
    fs.emptyDirSync(distDir)
  }
  Object.keys(types).forEach((type) => {
    const scripts = types[type]
    scripts.forEach((script) => {
      const mode = script.split(':')[0]
      const platform = script.split(':')[1]
      test(`${type} ${script}`, async () => {
        const outDir = path.resolve(distDir, mode, type, platform)
        console.log(`${type} npm run ${script} start`)
        await execa('npm', ['run', script], {
          cwd: projectDir,
          env: {
            ...process.env,
            UNI_OUTPUT_DIR: outDir,
            UNI_APP_X: type === 'uni-app-x' ? 'true' : 'false',
          },
        })
        console.log(`${type} npm run ${script} end`)
        expect(
          sync('**/test.json', { cwd: outDir, absolute: false })
            .sort()
            .map((filename) => normalizePath(filename))
        ).toMatchSnapshot()
      })
    })
  })
})