Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

はじめに

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

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

スクリーンショット 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、または会社のブログ、年一回のアドベントカレンダーなどの機会を上手に使いながら学習していきましょう!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした