跳到主要内容

lint-test✅

eslint 是如何工作的?

答案
  1. 加载配置 通过 loadConfigFile 加载配置, 配置规则详见 config file
  2. 解析 AST 默认采用 espree. AST 规则遵循 ESTree, ESLint 也支持 markdown/css 等解析,参考 markdown 解析, 可以通过 eslint explorer 查看不同 AST
  3. Rule 遍历节点按规则检查,每条规则接收上下文(RuleContext),在特定 AST 节点上报告问题并可返回 fixer(基于 SourceCode)生成补丁
  4. 生成报告
  5. 格式化 按规则提供 fixer 自动修复

eslint 如何实现增量 lint?

答案
  1. 结合 git diff 与 eslint,只对 MR/PR/commit 变更文件 lint

    # 方案1:命令行增量 lint(仅校验 master 分支与当前分支变更的 js 文件)
    git diff --name-only --diff-filter=d master | grep '\.js$' | xargs eslint
  2. lint-staged + husky(pre-commit 钩子自动 lint 暂存文件) npm install lint-staged husky --save-dev

    {
    "husky": {
    "hooks": {
    "pre-commit": "lint-staged"
    }
    },
    "lint-staged": {
    "*.js": ["eslint --fix", "git add"]
    }
    }

延伸阅读

TDD、BDD、DDD 分别指?

答案

核心概念:

  • TDD(测试驱动开发):先写测试再写实现,强调“红-绿-重构”循环。
  • BDD(行为驱动开发):关注行为描述,测试用例更贴近业务与非技术沟通。
  • DDD(领域驱动设计):以业务领域为核心的软件设计方法论,强调领域建模与分层架构。

示例说明:

// TDD 示例
test('加法函数', () => {
expect(add(1, 2)).toBe(3)
})
// 先写测试,再实现 add
function add (a, b) { return a + b }
提示

BDD 测试用例通常采用 Given-When-Then 语法,便于业务沟通。

面试官视角:

  • 要点:能区分三者本质、适用场景、优缺点
  • 加分项:能举出实际项目应用、理解 TDD/BDD/DDD 组合价值
  • 常见失误:混淆 DDD 与测试方法、只会背定义

延伸阅读

测试金字塔与主流测试类型有哪些?

答案

核心概念:

  • 测试金字塔分为:单元测试(底层)、集成测试(中层)、端到端测试(顶层),越往上越重但数量应减少。
  • 组件测试、静态分析也是前端常见测试手段。
  • 工具:Jest、Mocha、Cypress、React Testing Library、ESLint 等。

示例说明:

// 单元测试示例
function add(a, b) { return a + b }
test('add', () => {
expect(add(2, 3)).toBe(5)
expect(add(-1, 1)).toBe(0)
})

// 端到端测试示例(Cypress)

it('添加商品并结算', () => {
cy.visit('https://your-ecommerce-site.com')
cy.get('.product-item').first().click()
cy.get('.add-to-cart-button').click()
cy.get('.cart-icon').click()
cy.get('.checkout-button').click()
})
})

面试官视角:

  • 要点:能描述金字塔结构、各层测试目标、主流工具
  • 加分项:能结合实际项目说明测试策略
  • 常见失误:只会单一测试类型、不理解金字塔分层意义

延伸阅读

单元测试和端到端测试的区别?

答案
类型测试范围依赖速度维护成本典型工具
单元测试单个函数/类/模块低,常用 mockJest, Mocha
端到端测试整个系统/用户流程高,需完整环境Cypress, Puppeteer

示例说明:

// 单元测试
function add (a, b) { return a + b }
test('add', () => {
expect(add(1, 2)).toBe(3)
})

// 端到端测试
describe('登录流程', () => {
it('用户登录', () => {
cy.visit('/login')
cy.get('input[name=username]').type('user')
cy.get('input[name=password]').type('pass')
cy.get('button[type=submit]').click()
cy.contains('欢迎').should('exist')
})
})

面试官视角:

  • 要点:能清晰区分测试范围、依赖、速度
  • 加分项:能结合实际项目说明两者配合
  • 常见失误:混淆测试目标、只会单一类型

延伸阅读

如何针对 React Hooks 写单测?

答案

核心概念:

  • 针对自定义 Hook 推荐用 @testing-library/react-hooks,可隔离测试 Hook 逻辑。
  • 若依赖 Context,可用 wrapper 包裹。
  • 需用 act 保证状态同步。

示例说明:

// useCounter.js
import { useState, useCallback } from 'react'
export default function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue)
const increment = useCallback(() => setCount(c => c + 1), [])
const decrement = useCallback(() => setCount(c => c - 1), [])
return { count, increment, decrement }
}

// useCounter.test.js
import { renderHook, act } from '@testing-library/react-hooks'
import useCounter from './useCounter'
describe('useCounter', () => {
it('默认值', () => {
const { result } = renderHook(() => useCounter())
expect(result.current.count).toBe(0)
})
it('递增', () => {
const { result } = renderHook(() => useCounter())
act(() => { result.current.increment() })
expect(result.current.count).toBe(1)
})
it('递减', () => {
const { result } = renderHook(() => useCounter(10))
act(() => { result.current.decrement() })
expect(result.current.count).toBe(9)
})
})

面试官视角:

  • 要点:能独立测试 Hook、理解 act 用法
  • 加分项:能处理复杂依赖(如 Context)
  • 常见失误:直接在组件中测 Hook、未用 act

延伸阅读

代码覆盖率一般有什么手段?

答案

核心概念:

  • 覆盖率衡量测试执行代码比例,常见指标:语句、分支、函数、行覆盖率。
  • 工具:Jest(内置)、nyc/Istanbul、Cypress、Chrome DevTools Coverage。
  • CI 可用 Codecov/Coveralls 自动统计。

示例说明:

// Jest 生成覆盖率报告
jest --coverage
提示

Chrome DevTools Coverage Tab 可手动分析页面覆盖率,适合前端调试。

面试官视角:

  • 要点:能说出覆盖率指标、主流工具
  • 加分项:能结合 CI/CD 自动化
  • 常见失误:只会跑测试,不关注覆盖率

延伸阅读