🧭

2024年だけどJSのユニットテストをブラウザで動かす方法の紹介

2024/09/30に公開

できるだけnode.jsを使わずテストしたい

せっかくHotwireでnode.jsなどから解放された世界が手に入ったのに、
テスト用にnodeを動かすのはちょっともったいないなと思ったのがブラウザでユニットテストが動くかどうかを調べ始めたモチベーションでした。
特に業務で必要に駆られてというよりは単純な興味からでした。

Mocha, Chai

Jestは無理で、ブラウザでの動作をサポートしながら一番モダンっぽいのはこれかなーという感じでした。今も使われていると思いますけど流行っていた時期もありましたよね。

https://mochajs.org/#running-mocha-in-the-browser

今回はMochaとChaiでブラウザでユニットテストを動かす手順を紹介します。
簡単な関数とWebComponentsに関するテストを数ケース書きました。
下記GitHubにすべてのコードを掲載しておくのでこちらも合わせてご覧ください。

1. テスト動作用のHTMLを準備する

下記のようにテストランナー用の設定を書きます。
MyComponent.jsはテスト対象WebComponentsのコードで、test.js がテストコードです。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Mocha Tests</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="https://unpkg.com/mocha/mocha.css" />
  </head>
  <body>
    <div id="mocha"></div>

    <script src="https://cdn.jsdelivr.net/npm/mocha/mocha.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chai@4.3.4/chai.js"></script>

    <script class="mocha-init">
      mocha.setup('bdd');
      mocha.checkLeaks();
    </script>
    <script src="../src/MyComponent.js"></script>
    <script src="../src/test.js"></script>
    <script class="mocha-exec">
      mocha.run();
    </script>
  </body>
</html>

2. テストコードを書く

describe とかのおなじみの記法も書けそうです。

// Chaiのexpectを使う
const expect = chai.expect;

// 例1: 簡単な足し算の関数をテスト
describe('Math Functions', function() {
  it('should return 4 when 2 + 2 is called', function() {
    expect(2 + 2).to.equal(4);
  });

  it('should return 9 when 3 * 3 is called', function() {
    expect(3 * 3).to.equal(9);
  });
});


// 例2: オブジェクトのプロパティをテスト
describe('Object Tests', function() {
  it('should have property name', function() {
    const person = { name: 'John', age: 30 };
    expect(person).to.have.property('name');
  });

  it('should have the correct age', function() {
    const person = { name: 'John', age: 30 };
    expect(person.age).to.equal(30);
  });
});

// 例3: 非同期処理のテスト
describe('Async Test', function() {
  it('should resolve with correct value', function(done) {
    setTimeout(function() {
      expect(true).to.be.true;
      done();
    }, 400);
  });
});


describe('MyComponent', function() {
  // WebComponentが正しく作成されるかをテスト
  it('should create a shadow DOM and render content', function() {
    const el = document.createElement('my-component');
    document.body.appendChild(el);

    const shadowRoot = el.shadowRoot;
    expect(shadowRoot).to.exist;

    const p = shadowRoot.querySelector('p');
    expect(p).to.exist;
    expect(p.textContent).to.equal('Hello, WebComponent!');

    // HTMLにレンダリングされたままになるので後始末
    document.body.removeChild(el); 
  });
});

未検証

別途モックライブラリも使えるそうですがこちらは未検証です。モックが使えればテストを書いてて困ることはあまりなさそうです。安定性についても未知数なところがありますが、実際にブラウザで動く

CLIでやっぱ動かしたい

CI上であったりはやっぱりCLIで動したいと思います。
import部分だったりをうまいことやればテストコード自体は修正しなくてもCLIでも動くと思います。

QUnit

古くからあるQUnitというテスティングライブラリでもブラウザで動かせるようです。
https://qunitjs.com/browser/

まとめ

2024年にもなって、ブラウザで動くJSのユニットテストを書く方法について紹介しました。
Hotwireの誕生により、このようにちょっと古いやり方みたいなのが再注目していっても面白いのではないかなと思いました。

OSIRO テックブログ

Discussion