Jasmine の matcher で遊んでいるので
最近仕事とは別に JavaScript のテストフレームワーク Jasmine で遊んでいます。
理解を深める目的で、日本語化しながらちまちまテスト書いてみている(丸コピーして日本語化して自分用に追記してる)ので、ちょっと公開してみたり。
bitbucketのプライベートリポジトリに他のやつのテストを書くついでに書いたので、そっちで公開できないからベタで張り付けちゃうという暴挙。
JasmineSpec.js
/**
* Jasmine のテストの書き方のテスト
*/
describe('Jasmine の機能テスト', function() {
var obj01 = null;/**
* 全体用初期化
* どのitメソッド呼び出しの前にも呼ばれる
*/
beforeEach(function() {
obj01 = [1, 2, 3, 4, 5];
obj02 = [1, 2, 3, 4, 5, 6];
});/**
* 全体用後片付け
*/
afterEach(function() {
obj01 = null;
// obj02 = null; // あえて初期化しない
});/**
* describe 自体も入れ子にできる
* (全体が describe で囲まれているのを忘れないで)
*/
describe('describe 自体を入れ子にできる', function() {
it('block', function() {
expect(obj01.length).toEqual(5);
expect(obj02.length).toEqual(6);
});
});/**
* describe はテスト結果のブロッキングをしてくれる
*/
describe('describe はテスト結果をブロッキングして表示してくれる', function() {
// it の第一引数のテキストが同じであっても影響はでない
it('block', function() {
// 自身のネスト内にEachがあればソレが使われる// そのため、元の情報は失われる
expect(obj01.length).not.toEqual(5);// 内部のEach(下を参照)で上書きしたから
expect(obj01.length).toEqual(4);// 外のEachも呼ばれているので
expect(obj02.length).toEqual(6);
});// describe 内では順序は関係がない
beforeEach(function() {
obj01 = [1, 2, 3, 4];
});
});/**
* assert に相当するのはexpect メソッドと Matcher メソッド
*/
describe('Matcher紹介', function() {describe('.toBe()は', function() {
it('===と同じ', function() {
// obj01 === obj01 当然同じもの
expect(obj01).toBe(obj01);
});
it('オブジェクトとして同じかどうか', function() {
// obj01 === obj02 コピーしたら同じもの
var obj02 = obj01;
expect(obj01).toBe(obj02);
});
it('中身が同じだけではだめ', function() {
// obj01 !== obj03 中身は同じでもオブジェクトが違う
var obj03 = [1, 2, 3, 4, 5];
expect(obj01).not.toBe(obj03);
// 中の値が同じであることは toEqual()で確認できる(後述)
expect(obj01).toEqual(obj03);
});
});
describe('.toEqual()は', function() {
it('===と同じ動きをする', function() {
expect(123).toEqual(123);
});
it('typeが違うとマッチしない。==とは違うということ', function() {
expect(123).not.toEqual('123');
});
it('中の値が同じなら異なるオブジェクトも同じとして扱う', function() {
obj01 = [1, 2, 3];
obj02 = [1, 2, 3];// 中の値が同じなので
expect(obj01).toEqual(obj02);// ちなみに toBeだと異なる(別のオブジェクトなので)
expect(obj01).not.toBe(obj02);
});
});
describe('.toMatch()は', function() {
var str;
beforeEach(function() {
str = 'This is test case';
});
it('正規表現でマッチ', function() {
expect(str).toMatch(/test/);
});
it('なので大文字小文字を区別する', function() {
// マッチしないから .not
expect(str).not.toMatch(/TEST/);
});
it('ただし演算子は使える', function() {
// i は大文字小文字を無視
expect(str).toMatch(/TEST/i);
});
it('日本語にもマッチする', function() {
str = 'これはテストケースです';
expect(str).toMatch(/テスト/);
});
});
describe('.toBeDefined()は', function() {
it('定義されていることを期待する', function() {
var a = {
foo: 'foo'
};
// 定義されているのでマッチ
expect(a.foo).toBeDefined();
// 定義されていないのでマッチ
expect(a.bar).not.toBeDefined();
});
it('var で宣言しなくても大丈夫', function() {
def = 'OK';
expect(def).toBeDefined();
});
it('そのタイミングで変数としてイキならOK', function() {
expect(obj01).toBeDefined();
// さて、このobj01の中身は?(やってみよう)
});
});describe('.toBeUndefined()は', function() {
it('定義されていないことを期待する', function() {
var a = {
foo: 'foo'
};expect(a.foo).not.toBeUndefined();
expect(a.bar).toBeUndefined();
expect(undefined).toBeUndefined();
});
it('変数のスコープに注意', function() {
// def はvarなしで呼ばれた(上のdescribe)
expect(def).not.toBeUndefined();
});
it('undefinedにした変数もundef', function() {
var def = undefined;
expect(def).toBeUndefined();
});
});describe('.toBeNull()は', function() {
it('nullであることを期待する', function() {
expect(null).toBeNull();
});
it('nullが代入された変数', function() {
var a = null;
var foo = 'foo';expect(a).toBeNull();
expect(foo).not.toBeNull();
});
it('何も代入していない変数はundefined', function() {
var a;
expect(a).not.toBeNull();
});
});describe('.toBeTruthy()は', function() {
it('TRUEと判断される値(状態)であることを期待する', function() {
var a, foo = 'foo';expect(foo).toBeTruthy();
expect(a).not.toBeTruthy();
});
it('例えば true', function() {
var a = true;
expect(a).toBeTruthy();
});
it('例えば 1', function() {
var a = 1;
expect(a).toBeTruthy();
});
});describe('.toBeFalsy()は', function() {
it('FALSEと判断される値(状態)であることを期待する', function() {
var a, foo = 'foo';expect(a).toBeFalsy(); // 値がないので
expect(foo).not.toBeFalsy();
});
it('例えば false', function() {
var a = false;
expect(a).toBeFalsy();
});
it('例えば NaN', function() {
var a = NaN;
expect(a).toBeFalsy();
});
it('例えば 0 (zero)', function() {
var a = 0;
expect(a).toBeFalsy();
});
it('例えば "" (空)', function() {
var a = '';
expect(a).toBeFalsy();
});
});describe('.toContain()は', function() {
it('値が含まれていることを期待する', function() {
var a = ['foo', 'bar', 'baz'];expect(a).toContain('bar');
expect(a).not.toContain('quux');
});
it('変数もうまく動く', function() {
var a1 = 'A1';
var a2 = 'A2';
var a3 = 'A3';
var a = [a1, a2, a3];expect(a).toContain('A1');
expect(a).toContain(a2);
});
it('文字列もうまく動く', function() {
var a = 'abcdefg';expect(a).toContain('a');
expect(a).not.toContain('z');
});
});describe('.toBeLessThan()は', function() {
it('より小さいことを期待する', function() {
var pi = 3.1415926, e = 2.78;expect(e).toBeLessThan(pi);
expect(pi).not.toBeLessThan(e);
});
it('文字は文字コード順', function() {
var a = 'a', b = 'b';expect(a).toBeLessThan(b);
expect(b).not.toBeLessThan(a);
});
});describe('.toBeGreaterThan()は', function() {
it('より大きいことを期待する', function() {
var pi = 3.1415926, e = 2.78;expect(pi).toBeGreaterThan(e);
expect(e).not.toBeGreaterThan(pi);
});
it('文字は文字コード順', function() {
var a = 'a', b = 'b';expect(b).toBeGreaterThan(a);
expect(a).not.toBeGreaterThan(b);
});
it('真偽値を比較してみると', function() {
// true が大きい
expect(true).toBeGreaterThan(false);
expect(false).not.toBeGreaterThan(true);
});
});describe('.toBeCloseTo()は', function() {
it('数学的に近い値であることを期待する', function() {
var pi = 3.1415926, e = 2.78;expect(pi).not.toBeCloseTo(e, 0.1);
expect(pi).toBeCloseTo(e, 0);var r2 = 1.41421356;
expect(r2).not.toBeCloseTo(1.5, 0);
expect(r2).toBeCloseTo(1.5, 0.1);
expect(r2).toBeCloseTo(1.5, 0.2);var x = 1000.1;
expect(x).toBeCloseTo(1000, 0.1);
});
});describe('.toThrow()は', function() {
it('exception が throw されることを期待する', function() {
var foo = function() {
return 1 + 2;
};
var bar = function() {
// a が宣言されていないのでエラーが発生する
return a + 1;
};expect(foo).not.toThrow();
expect(bar).toThrow();
});
});
});/**
* 処理しない
* 一時的に処理しないようにすることができる
*/
describe('処理しないこともできる', function() {
it('xdescribe と xit は処理されない', function() {
expect(123).toEqual(123);
});
xdescribe('このdescribeは処理されない', function() {
it('親が処理されないと入れ子の処理もされない', function() {
expect(123).toEqual(123);
});
});
describe('このdescribeは処理される', function() {
xit('が、ここは処理されない', function() {
expect(123).toEqual(123);
});
it('ここは処理される', function() {
expect(123).toEqual(123);
});
});
});});
skipのxdescribeとxitまでやったら、次はスパイなんだけど、まだよく把握できてないので、とりあえずここまで。
.toBeCloseTo()がイマイチよくわかんない。
もっと使いこなせるようにじゃんじゃん写経せねば。というところ。