npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

uvu-jest

v0.0.37

Published

Run the existing jest code with uvu

Downloads

312

Readme

Why

2022年現在、Node.js環境のユニット・統合テストにはJestが多く採用されておりますが、中小規模のユースケースではオーバースペックであったり重すぎることが多く、より軽量かつ高速なテストランナーを利用してDX(開発体験)を向上させたいと考える開発者も少なくないと思われます。

そこで、私は最近 uvu という超軽量で高速なテストランナーを見つけました。スタートアップが超高速で、最低限の機能が実装され、利用しやすいAPIインターフェイスがあり、非常に感銘を受けました。

一方で、uvuはまだ0系のライブラリになっており、Jestを利用する既存のプロダクトへの導入を考えると、Jestの安定性や高機能性とのトレードオフで簡単にuvuに載せ替える選択ができない場合も多いと考えます。

以上のことから、既存のJestで書かれたテストコードをuvuライクなテストランナーで動かせるコードに変換し、高速なテスト実行を実現したいと考えました。

制限

  • テストファイル名は *.spec.ts*.spec.js の形式である必要があります。

使い方

examples のデモも参考にしてください。

  1. パッケージをインストール
npm i -D uvu-jest uvu-jest-ts-plugin ttypescript
  1. tsconfig.ttsc.jsonを作成
{
  "compilerOptions": {
    // 変換用のプラグインを指定します
    "plugins": [{"transform": "uvu-jest-ts-plugin"}],
    "outDir": "./dist-uvu",
    "target": "ESNext"
  }
}
  1. 既存のJestで書かれたテストファイル変換する
npx ttsc -p tsconfig.ttsc.json
# dist-uvu ディレクトリが作成されます
  1. テストを実行する

4.1 CLIを利用する

npx uj dist-uvu spec

コマンドの引数は、第一引数にディレクトリ、第二引数に任意でパターンを指定します。 (ディレクトリの中で、指定したパターンにマッチするテストが実行されます。)

その他のCLIコマンドの機能に関しては、uvuのドキュメント を参照してください。

4.2 直接nodeで実行する

node dist-uvu/{hoge}/{huga}/{piyo}.js

設定ファイル

プロジェクトルートに配置した uvu-jest.config.js に対応しています。

example

module.exports = {
  setupFiles: ['dist-uvu/jestSetUp.js'],
  snapshotResolver: 'test/snapshotResolver.js',
  customMatchers: '@testing-library/jest-dom/matchers',
};
  • setupFiles
    • JestのsetupFilesと同様にテストの実行前に実行するファイルを指定できます。
    • (環境変数の変更などをおこないます。)
  • snapshotResolver
    • jestのsnapshotResolverと同様に、テストファイルに対するsnapshotファイルの保存先を変更できます。
    • resolveSnapshotPathにのみ対応しています。
  • customMatchers
    • expectにMatcherを追加します
    • Record<string, MatcherFn>の形式でexportされている想定です。

動作の仕組み

1. なぜuvuをフォークしたか?

本当はuvuをそのまま利用できればよかったのですが、Jestで書かれたテストをuvuに書き換える際に一点困難な点があったのが最大に理由です。 JestではafterAllというライフサイクルHookが利用できますが、describeでネストさせることが可能です。uvuにもsuite.afterというhookがありますが、下記の様なネストされたケースの実行順序を再現することは出来ません。

describe('desc1', () => {
  afterAll(() => { /* after all 1 */})
  test('test1', () => {});
  describe('desc2', () => {
    afterAll(() => { /* after all 2 */})
    test('test2', () => {});
  });
});

この場合の実行順序は、test1 => test2 => after all 2 => after all 1 です。この様にafterAllはdescribeの各階層ごとにライフサイクルを指定しているので、ネストする機能がないとJestのコードを書き換えることが出来ません。しかしながら、uvuでのネスト機能は依然として 議論中 でした。

そこで、uvuをフォークして、新たに suite.nest という関数を追加することにしました。

2. wrapper

Jestのコードを変換するのに、全てをtransformerに任せると大変なのと、変換後のコードが既存のコードとあまりにかけ離れた物になっているとデバックが難しくなるため、なるべく元コードの形を維持したまま書き換えるための wrapper を用意しました。 (こちらを参考にしています。)

具体的には、以下の簡略化した例の通り、describeを置き換えるラッパーです。

export function describe (name: string, handler: Handler) {
  const test = suite(name);

  handler({
    test,
    expect, // 別で定義しています
    describe,
    afterAll: test.after,
    beforeAll: test.before,
  });

  test.run();
}

Jestのコードを書き換えたイメージは下記の通りです。

describe('desc1', ({ afterAll, test, expect, describe }) => {
  afterAll(() => {});
  test('test1', () => {
    expect(parseInt(0.0000005)).not.toBe(0);
  });
  describe('desc2', ({ afterAll, test, expect, describe }) => {
    afterAll(() => {});
    test('test2', () => {
      expect(parseInt(0.0000005)).toBe(5);
    });
  })
});

3. Jestコードの変換

変換にはTypeScriptのCompilerAPIの中のTransformer機能を利用しました。これは、トランスパイルの途中で入力したTSファイルを修正することができます。2で説明した通り必要な修正はwrapperのdescribeのimport文を追加することと、describeのhandlerに引数を与えることです。

なお、カスタムのTransform pluginはTypeScript(tsconfig.json)では指定できないため、ttypescript を利用します。

Jestの機能への対応

Matcher

  • expect().toBe()
  • expect().toEqual()
  • expect().not.toBe()
  • expect().not.toEqual()
  • expect().rejects.thThrow()
  • expect().toMatchSnapshot()

snapshotテスト

uvuにもsnapshotテストの機能がありますが、既存のjestで作成したスナップショトを生かすため、jest-snapshot を利用することでJestのSnapshotテスト機構をそのまま流用しています。

snapshotテストでは実行ファイルのパスを取得する必要があるので、必ずCLIで実行する必要があります。 また、CLIに-uフラグを指定することで、jestと同様にsnapshotを更新することができます。

jest-snapshotは巨大なパッケージで読み込みに数百msを要するため、必要な時にだけ読込まれます。

Testing Library 対応

Testing Libraryは基本的にJestと併用されることが想定されていますが、#using-without-jest を参考に、 uj => node -r global-jsdom/register node_modules/.bin/uj と置き換えることで利用可能です。

また、Testing LibraryではtoBeInTheDocumentなどの独自の custom matcher が提供されていますが、uvu-jest.config.js に登録することで、利用可能になります。

module.exports = {
  customMatchers: '@testing-library/jest-dom/matchers',
  /* ... other settnigs */
};

TODO

readme に記載

FAQ

TS の path alias を利用する場合

uvu-jest-ts-pluginを利用して生成したjsはTSCでコンパイルした状態なので、TS の path aliasが解決されていません。

そのため、実行時にエイリアスを解決してくれる (module-alias)[https://github.com/ilearnio/module-alias] を利用した設定を、セットアップファイルで読み込みます。

CONTRIBUTE

PRやissueで要望・感想を頂けると助かります。

License

MIT © hedrall