9
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Node.jsAdvent Calendar 2018

Day 20

様々なテストツールをいじってみた。

Posted at

はじめに

今回の目的はいろんなテストツールを実際に書いて学習していこう!というものです。
簡単なコードですが、同じコードをそれぞれの記法で書きながら比較していこうとうものです。
基本の「き」しかかいていないので公式のリファレンスをゴリゴリ読むことをおすすめします。

対象テストツールのご紹介

スクリーンショット 2018-12-08 17.14.13.png

引用: https://github.com/kamranahmedse/developer-roadmap

こちらのdeveloper-roadmapや いろんなライブラリーを調べながら進めていきたいと思います。


1 Jest
2 Jasmine
3 Mocha

テスト対象

今回expressを用いて、簡単な認証システムを作成しました。

実際にLoginLogoutについて書いてみました。
今回はRouterオブジェクトのテストをやりやすくるためにsupertestというモジュールをインストールしています。
https://github.com/visionmedia/supertest

Jest

導入

$ npm install --save-dev jest

コード

login-spec.js
const request = require('supertest');
const app = require('../app');

describe('/login', () => {
  test('it returns status code is 200', (done) => {
    request(app).get('/login').then((response) => {
      expect(response.statusCode).toBe(200);
      done();
    });
  });

  test("it returns Content-Type is 'text/html'", (done) => {
    request(app).get('/login').then((response) => {
      expect(response.headers["content-type"]).toBe('text/html; charset=utf-8');
      done();
    });
  });
});

logout-spec.js
const request = require('supertest');
const app = require('../app');

describe('logout', () => {
  test('it returns status code is 302', (done) => {
    request(app).get('/logout').then((response) => {
      expect(response.statusCode).toBe(302)
      done();
    });
  });

  test('it redirects root path', (done) => {
    request(app).get('/logout').then((response) => {
      expect(response.headers['location']).toBe('/')
      done();
    });
  });
});

実行結果

スクリーンショット 2018-12-10 11.55.06.png


スクリーンショット 2018-12-10 12.09.48.png

所感

標準設定でこれらの情報を表示してくれるのは親切だなと思ってしまいました。
またに --watchというような watchオプションをつけると監視モードに入ってくれるので、テストを変更した際に自動で走るようになってくれます。(①)他にも --covarageといったcovarageオプションをつける下記のようなグラフ上で結果を表示してくれます!(②)
Mactherも直感的でわかりやすかったです!

Jasmine

導入

$ npm install --save-dev jasmine

コード

loginSpec.js
const request = require('supertest');
const app = require('../app');

describe('/login', () => {
  it('returns status code is 200', (done) => {
    request(app)
      .get('/login')
      .end((err, res) => {
        try {
          expect(err).toBeNull()
          expect(res.status).toEqual(200)
          done();
        } catch (err) {
          done.fail(err);
        }
      });
  });

  it('responses content-type is 'text/html'', (done) => {
    request(app)
      .get('/login')
      .end((err, res) => {
        try {
          expect(err).toBeNull()
          expect(res.status).toEqual(200)
          expect(res.headers['content-type']).toEqual('text/html; charset=utf-8')
          done();
        } catch (err) {
          done.fail(err);
        }
      });
  });
});

logoutSpec.js
const request = require('supertest');
const app = require('../app');

describe('/logout', () => {
  it('returns status code is 302', (done) => {
    request(app)
      .get('/logout')
      .end((err, res) => {
        try {
          expect(err).toBeNull()
          expect(res.status).toEqual(302)
          done();
        } catch (err) {
          done.fail(err);
        };
      });
  });

  it('redirects root path', (done) => {
    request(app)
      .get('/logout')
      .end((err, res) => {
        try {
          expect(err).toBeNull()
          expect(res.headers['location']).toEqual('/')
          done();
        } catch (err) {
          done.fail(err);
        };
      });
  });
});

実行結果

スクリーンショット 2018-12-11 21.11.42.png

所感

いろんな記事にも書かれていたのですが、Ruby/RailsでRSpecを使ってテストを書く習慣がベースとしてあって、RSpecと似たような記法のJasmineは違和感がないというのは実際に感じました。
Matcherも似たような感じなので、イメージでできてしまいます。(実際にはちゃんと調べましょう!)
Angularで使われることが多々あるようですね!

Mocha

導入

$ npm install --save-dev mocha

コード

login_spec.js
const request = require('supertest');
const app = require('../app');

describe('/login', () => {
  
  it ('return status code is 200', (done) => {
    request(app)
      .get('/login')
      .expect(200, done);
  });

  it ('returns Content-Type is text/html; charset=utf-8', (done) => {
    request(app)
      .get('/login')
      .expect('Content-Type', 'text/html; charset=utf-8', done);
  });
});
logout_spec.js
describe('/logout', (done) => {
  it('returns status code is 302', (done) => {
    request(app)
      .get('/logout')
      .expect(302, done);
  });

  it('redirect root page', (done) => {
    request(app)
      .get('/logout')
      .expect('Location', '/', done);
  });
});

実行結果

スクリーンショット 2018-12-11 21.20.31.png

所感

今回はmochaというよりも、supertest風な書き方になってしまいました....
ですが期待する値と結果を引数で書くやり方はこれまでと一線を画しています。
またGithub上で調べてみると、比較的古めのプロダクトはmochaで書かれている印象を持ちました。
いろんなOSSを参考にしながら、構成を考えたり、リーディングできたりすることはとても魅力的ですね!

まとめ

どんなアプリケーションでも必ずテストは書くかと思います。
実際3つのテストツールを書いてみて感じたことはJestは使いやすいというか、defaultでいろんなことができるなーという印象を持ちました。
また、ReactやVueなどにもしっかり対応しています。Vue jsの Vue Test Utilsでは Jest は最も充実したテストランナですとまで言っていますw
それほど、多くのエンジニアから認められていることを裏付けるかのようです。
今回のこのアドベントカレンダーのおかげさまで、一度に3つのテストツールに触れることができました。簡単なコードではありましたが、沢山リファレンスを読むことができたのでとても勉強になりました!みなさんも個人、会社用のQiita、または会社のブログ、年一回のアドベントカレンダーなどの機会を上手に使いながら学習していきましょう!

9
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?