测试覆盖率与持续集成

测试覆盖率

1.配置jest.config.js文件

reporters: ["default", "jest-junit"],
collectCoverage: true,
// 要从哪些代码里面测试,测试lib里所有目录下面的.ts和.tsx, 不测试任意目录下的node_modules里的所有文件
    collectCoverageFrom: ["lib/**/*.{ts,tsx}", "!**/node_modules/**"],
  // 生成的报告放在'coverage'里
    coverageDirectory: 'coverage',
    // 要用哪些测试报告;text:控制台的输出
    coverageReporters: ['text', 'lcov'],
  1. 配置package.json
"script": {
  "xxx": "cross-env NODE_ENV=test JEST_JUNIT_OUTPUT=./test-results/jest/results.xml jest --config=jest.config.js"
}
  1. 运行 yarn xxx,然后在浏览器里打开coverage/icov-report/index.html

配置circle CI 持续集成

  1. 创建.circleci/config.yml文件
  2. 内容先拷贝给出的demo
  3. 根据demo去修改
  4. push

config.yml完整代码链接:https://github.com/wanglifa/IReact-UI/blob/ebd827bd127b6e9ffe94bb248cfd8647361caa82/.circleci/config.yml

点击running会看到下面的3个工作流程

  1. prepare
  2. test
  3. build
config.yml代码详解
#https://github.com/revolunet/create-react-app-circleci/blob/master/.circleci/config.yml
defaults: &defaults # 使用默认的配置
  docker:
    - image: circleci/node:8 # 使用node8来测试

version: 2 # circleci的版本
jobs:
  # 准备阶段
  prepare:
    <<: *defaults
    steps:
      - checkout # 1. 迁出代码
    
    # 2. 以v2-dependencies-{{ checksum "package.json" }}这个文件的md5作为key创建一个缓存
      - restore_cache:
          keys:
            - v2-dependencies-{{ checksum "package.json" }}

      #缓存的内容
      - run: yarn install  #2.1 安装所有依赖
      #2.2 缓存保存的内容
      - save_cache:
        #把所有node_modules目录文件保存到缓存里,只要我们依据的md5的这个package.json文件没有变,它就不会再重新去安装node_modules
          paths:
            - node_modules
          key: v2-dependencies-{{ checksum "package.json" }}
      - persist_to_workspace:
          root: .
          paths:
            - node_modules
  build:
    <<: *defaults
    steps:
      - checkout
      - attach_workspace:
          at: .
      - run: yarn build
      # 持久化工作流(不删除的)
      - persist_to_workspace:
          root: .
          paths:
            - dist
 # 测试
  test:
    <<: *defaults
    steps:
      - checkout # 迁出代码
      
      # 把刚才准备工作保存的代码挪过来
      - attach_workspace:
          at: .

      # 运行 yarn ci
      - run: yarn ci

      # 把测试的结果保存到test-results目录上
      - store_test_results:
          path: test-results


# workflows让circleci知道我们三个流程的顺序
workflows:
  version: 2
  build_accept_deploy:
    jobs:
      - prepare // 没有依赖
      - build: // build必须先运行test
          requires:
            - test
      - test: // test 必须先运行prepare
          requires:
            - prepare

在index.tsx里导出我们的icon组件

  • index.tsx
export { default as Icon } from './icon/icon'

运行yarn build
运行npm publish报错

解决办法:

  1. 在package.json里添加files
"files": ["/dist"]
  1. 运行yarn publish(如果运行npm publish报错就换成yarn)

自动发布

在circleci自动测试,自动打包的基础上再加一个自动发布

  • config.yml
publish:
    <<: *defaults
      steps:
        - checkout
        - attach_workspace:
            at: .
        - run: npm publish

workflows:
  - publish:
          requires:
            - build

push后报错,因为我们没有登录也没有用户信息和密码
解决方法:
在npm上生成一个token,然后将这个token添加到circleci中

点击create new token

选择可以读和写的

成功后我们会得到一串token,复制它然后到circleci中点击你的项目名右边的设置

在config.yml里的publish中添加

- run: npm config set //registry.npmjs.org/:_authToken $NPM_TOKEN
- run: npm publish

自己写deploy.sh脚本

现在我们已经可以自动测试,自动打包,自动发布,但是我们每次还是得手动修改版本号

  • 版本号拓展知识
    版本号有三位数字构成比如:
    1.0.100 分别对应着major(大版本).minor(小版本).patch(补丁版本)

16.8.2 -> 16.8.3 API不变,修复了bug
16.8.2 -> 16.9.0 API有变化,变化不大,完全不影响现有代码
16.8.2 -> 17.0.0 API变化很大,影响现有代码

运行npm version patch 最后一位会加一,major和minor也是和上面对应加一

  • 自动升级版本
    新建一个deploy.sh
npm version patch
git push

运行 sh ./deploy.sh就会自动升级版本,自动push

简化运行命令我们可以在文件里配置一个/bin/env bash,然后再通过chmod +x deploy.sh添加一个可执行权限,就可以直接通过./deploy.sh来运行

#!/bin/env bash

问题:我们运行deploy.sh只能升级补丁版本,如果想要升级minor哪?
方法:通过一个参数来获取我们命令后传入的字段

npm version $1

上面的1就可以拿到我们deploy.sh后面的参数,比如我们运行`deploy.sh minor`那么1就是minor,为了确保我们版本升级成功后再push,所以我们要添加一个&&(只有当前面成功后才会运行后面的)

npm version $1 && \
    git push

CI添加tag filters

问题:我们如果又不需要build的改动,但现在一旦我们的代码push后它就会自动build
解决办法:在publish的时候添加一个filters

workflows:
  version: 2
    - publish:
          requires:
            - build
          # 过滤:忽略任意全部分支,只有以v后面是0-9的数字开头的tags才会去部署
          filters:
            tags:
              only: /^v[0-9]+(\.[0-9]+)*/
            branches:
              ignore: /.*/

添加项目小徽标

  1. 添加circleci徽标
    在jobs里点项目右边的设置,然后点击Status Badges

复制它放到我们的README.md文件里

JS和JSX 以及 TS和TSX的区别

x:有两种意思

  1. 罗马数字的10
  2. extension 扩展

JSX相比JS扩展了支持XML的写法,我们可以在js里写return <div></div>也就是React.createElement('div')

TS:Type+JS;在js的基础上支持类型
TSX: Type+JS+XML

区分本地测试和CI测试

我们本地运行yarn test会发现它也返回了测试覆盖率相关的数据,这样就会让我们的运行结果变慢,而实际上我们本地是不需要测试覆盖率的,所以我们就需要对CI和test进行区分

  1. 把之前的jest.config.js作为基础配置,把CI和test都需要用到的(除测试覆盖率之外的)放在里面
  • jest.config.js
// https://jestjs.io/docs/en/configuration.html
module.exports = {
    verbose: true,
    clearMocks: false,
    collectCoverage: false,
    reporters: ["default"],
    moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx'],
    moduleDirectories: ['node_modules'],
    globals: {
      'ts-jest': {
        tsConfig: 'tsconfig.test.json',
      },
    },
    moduleNameMapper: {
      "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/test/__mocks__/file-mock.js",
      "\\.(css|less|sass|scss)$": "<rootDir>/test/__mocks__/object-mock.js",
    },
    testMatch: ['<rootDir>/**/__tests__/**/*.unit.(js|jsx|ts|tsx)'],
    transform: {
      "^.+unit\\.(js|jsx)$": "babel-jest",
      '^.+\\.(ts|tsx)$': 'ts-jest',
    },
    setupFilesAfterEnv: ["<rootDir>test/setupTests.js"]
  }

-jest.config.ci.js

// https://jestjs.io/docs/en/configuration.html
const base = require('./jest.config')
module.exports = Object.assign({}, base, {
  collectCoverage: true,
  collectCoverageFrom: ["{lib,include}/**/*.{ts,tsx}", "!**/node_modules/**"],
  coverageDirectory: 'coverage',
  coverageReporters: ['text', 'lcov'],
  reporters: ["jest-junit"]
})
  • package.json
"test": "cross-env NODE_ENV=test jest --config=jest.config.js --runInBand",
"ci": "cross-env NODE_ENV=test JEST_JUNIT_OUTPUT=./test-results/jest/results.xml jest --config=jest.config.ci.js"
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355

推荐阅读更多精彩内容