Skip to content

Instantly share code, notes, and snippets.

@ginpei

ginpei/text.md Secret

Last active February 26, 2019 06:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ginpei/89f2658a80f244e2b37d6e79c50498a4 to your computer and use it in GitHub Desktop.
Save ginpei/89f2658a80f244e2b37d6e79c50498a4 to your computer and use it in GitHub Desktop.
WIP: 自動で徳を積むための試験とCIハンズオン

参考:前回 Ginpei先生によるJavaScript初心者講習会 | Frog

自動で徳を積むための試験とCIハンズオン

(TODO 筋肉に響くメッセージをここに)

イベント詳細

CI をぐるぐる回して、コードを書くたびに自動で徳が高まるようにするハンズオンです。試験の実施やデプロイ作業などを自動化し、実装に集中できるような環境整備を目指します。

日時

2019年3月16日(土) 午後2時~5時頃まで

場所

Frog/COS バンクーバーオフィス
Suite225 – 314 W.Cordova St, Vancouver BC V6B1E8

対象者

  • ウェブアプリを開発しているひと
  • JavaScriptを普通に書けるひと
  • 人力より機械化を信じるひと

既に試験を書いた経験があるとなお良いですが、なくても大丈夫です。

やること

  • ESLintで綺麗にする
  • Jestで試験する
  • TravisCIで自動試験する
  • CodeClimateで自動レビューする
  • 試験の実施範囲 (coverage) を自動集計する
  • GitHub Pagesへ自動デプロイする

やらないこと

  • JavaScriptの書き方、JS以外の試験
  • 試験の詳しい話、enzyme, jsdom
  • ウェブアプリ自体の作り方
  • React, Vue.js, Webpack
  • GitHub以外のホスティングサービス

必要なもの

  • 基礎的なJavaScriptの技量(サーバー側、クライアント側問わず)
  • ウェブアプリ開発の経験、実行環境
  • GitHubアカウント

今回のJavaScriptはクライアント側のものになります。ただしサーバー側に関して実施する場合も(GitHub Pagesへのデプロイ以外は)大差ありませんので、あまり気にしないでください。

JavaScriptの試験も今回の範囲ですが、書き方というよりは実行環境の整備が主眼です。試験の経験あると良いですが、ない方はこれからやっていきましょう。

お申込み

云々


以下、本編。

目次

  • ESLintで綺麗にする
  • Jestで試験する
  • TravisCIで自動試験する
  • CodeClimateで自動レビューする
  • 試験 Coverage を自動集計する
  • GitHub Pagesへ自動デプロイする

ESLint

導入

eslint がアプリ。eslint-config-airbnb-base が下敷きにするルール集、eslint-plugin-import はその依存。

$ npm install --save-dev eslint eslint-config-airbnb-base eslint-plugin-import

プロジェクトルートに .eslintrc.js を作成。

module.exports = {
  "env": {
    "browser": true,
    "es6": true
  },
  "extends": "eslint-config-airbnb-base",
  "rules": {
    "arrow-parens": [
      "error",
      "always"
    ],
  },
};

実行。

$ npx eslint .

自動修正

セミコロンの抜けのような軽微なエラーは自動修正できる。--fix を付ける。

$ npx eslint . --fix

ファイルは上書きされるが git があるので恐るるに足らぬ。

npm scripts

に書いておくと吉。

{
  "scripts": {
    "lint": "eslint ."
  }
}
$ npm run lint
$ npm run lint -- --fix

Prettier

今回やりません。

Jest

導入

$ npm install --save-dev jest

まずコードを書く。

// src/sum.js
function sum(a, b) {
  return a + b;
}
module.exports = sum;

続いて試験コードを書く。先の対象コードを import する。

// src/sum.test.js
const sum = require('./sum');

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3);
});

実行。

$ npx jest

開発中はwatchしたい場合、--watch オプション。^C で終了。

$ npx jest --watch

npm scripts

に書いておくと吉。

{
  "scripts": {
    "test": "jest"
  }
}
$ npm run test
$ npm run test -- --watch

Jestの試験の書き方

it(), expect()

試験項目。it() が実行され、expect() で結果を確認する。

it(() => {
  const result = 3 + 2;
  const expected = 5;
  expect(result).toBe(expected);
});

非同期の場合も、普通に async, await を書けば動く。

test('the data is peanut butter', async () => {
  expect.assertions(1);
  const data = await fetchData();
  expect(data).toBe('peanut butter');
});

toBe()

"matcher" と呼ばれるもの。expect() の確認の方法。

  • toBe() … 同じ値か。Object.is() を利用
  • toEqual() … オブジェクトの中身が同じか

その他たくさんあるので公式文書を確認。

not

matcher の判定を逆にする。

expect(10).toBe(10);
expect(10).not.toBe(99);

toThrow()

例外を確認。この場合、expect() には関数を与える。

expect(() => {
  throw new Error('It is not OK');
}).toThrow();

.toThrow(/foo/) のように引数を与えエラーメッセージを確認することもできる。しなくて良いのでは。

非同期の場合は async 内で catch する。

try {
  throw new Error('It is not OK');
} catch (error) {
  expect(error).not.toBeUndefined();
}

Jestの試験の組み立て方

describe()

複数の試験をまとめる。入れ子にできる。

describe('FooApp()' => {
  it('works nicely', () => ...);
  it('works finely', () => ...);

  describe('BarModule', () => {
    it('works straightforwardly', () => ...);
  });
});

結果も入れ子になって表示される。

beforeEach(), afterEach()

Jestの試験の制御

only

TODO

skip

TODO

Jestで関数の試験

たいへん。

TODO

試験の考え方

public な interface の「入力」と「出力」の確認をする。内側へ秘匿されている機能は気にしない。(ブラックボックス試験。) これで実装の変更があっても試験が通っていれば、結果は変わらないと判断できる。

試験自体が誤っていないことを確認するため、一度わざと失敗すると良い。失敗するはずなの成功する場合、前提が誤っていることがある。

TODO もっと良いこと言う

TravisCI

導入

GitHubと連携して、ダッシュボードの "+" ボタンを押してリポジトリ―一覧を開いて、目的のものを選択。

右上 "More options" から "Trigger build" でビルド実行。

まだ何もしてないので

TODOどうなる?

プロジェクトルートに .travis.yml を作成。

language: node_js
node_js:
  - "10"
script:
  - npm run test

これを含めてリポジトリ―へ上げる。Travisが変更を監視しているので、自動で試験が実行される。失敗するとメールが飛んでくる。

スクリプトはYAMLの配列なので、複数書ける。lintとか。

vs local git-hooks

git commit のたびに試験実行されるとかもできるけど、時間かかって面倒なのでCIだけで良いのでは。

バッジを付ける

よく見かけるアレをREADMEに追加しよう。

CodeClimate

  • Quality | Code Climate
    https://codeclimate.com/quality/
  • コードを静的解析して、改善提案してくれたり点数を付けて変化を記録してくれたりする
  • 同社製品の Velocity ($799+/mo) ではなく Quality ($0+/mo) の方ね
  • Vue.js未対応。ReactやTypeScriptには対応

導入

なんかぽちぽちすれば終わる。

連携してしばらく待つと出てくる。

Coverage

試験がコードをどれだけカバーしているか。試験項目の有無ではなく試験時に行を通ったかどうかの判定っぽい。

CodeClimateが対応しているので、記録してもらおう。

試す

$ npx jest --coverage

coverage ディレクトリー以下に諸々出力される。coverage/lcov-report/index.html をブラウザーで開いて見てみよう。

リポジトリ―には上げない

自動生成される系のファイルを上げてはいけない。

.gitignore に追加しておく。

CodeClimateと連携

TravisCIで試験時に coverage 出力し、その結果を CodeClimate へ送信する、という流れ。

キーが必要なので、まず CodeClimate で対象プロジェクトの "Repo Settings" → "Analysis" 以下 "Test coverage" → "Use this ID with Code Climate's test reporters" のIDを控えておく。

続いてTravisCIで対象プロジェクトの設定で Environment Variables を追加する。

  • Name: CC_TEST_REPORTER_ID
  • Value: 前述のID

さらに .travis.yml の設定を更新。

language: node_js
node_js:
  - "10"
before_script:
  - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
  - chmod +x ./cc-test-reporter
  - ./cc-test-reporter before-build
script:
  - npm test -- --coverage
after_script:
  - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT

これをリポジトリ―に上げると、TravisCI が反応して試験を実行、同時に coverage 出力して CodeClimate へ送信、そこで記録される。

GitHub Pagesへ自動デプロイ

release ブランチ更新時、GitHub Pagesも自動で更新するようにする。

GitHub Pages

一度手動でやってみる。

TODO

TravisCI の設定

TODO


by 高梨ギンペイ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment