QUnit官方文檔譯文(不完整版)-2.62

QUnit官方文檔譯文

官方文檔:https://api.qunitjs.com/QUnit/module

主要方法

- module

QUnit.module(name [,hooks] [,nested])
使用單個(gè)標(biāo)簽對(duì)測(cè)試進(jìn)行分組
<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>name(string)</td>
<td>用來(lái)標(biāo)志一組測(cè)試</td>
</tr>
<tr>
<td>hooks(object)</td>
<td>在執(zhí)行測(cè)試時(shí)的回調(diào)</td>
</tr>
<tr>
<td>nested(function)</td>
<td>嵌套模塊的回調(diào)</td>
</tr>
</table>

hooks的屬性:{before, beforeEach, afterEach, after}

<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>before (function)</td>
<td>執(zhí)行第一個(gè)測(cè)試之前運(yùn)行</td>
</tr>
<tr>
<td>beforeEach (function)</td>
<td>每個(gè)測(cè)試之前運(yùn)行</td>
</tr>
<tr>
<td>afterEach (function)</td>
<td>每個(gè)測(cè)試之后運(yùn)行</td>
</tr>
<tr>
<td>after (function)</td>
<td>最后一個(gè)測(cè)試之后運(yùn)行</td>
</tr>
</table>

提示:如果module的隊(duì)列為空了之后定義了額外的測(cè)試方法,after這個(gè)鉤子不會(huì)再次運(yùn)行惕它。

嵌套模塊: nested( hooks )

當(dāng)前模塊下的一組測(cè)試和嵌套模塊的回調(diào)
<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>hooks (object)</td>
<td>定義了before/beforeEach/afterEach/after鉤子的對(duì)象</td>
</tr>
</table>

描述

你可以用模塊名稱(chēng)來(lái)組織宫屠、選擇秉颗、篩選你要運(yùn)行的測(cè)試院峡。

所有的測(cè)試都是放在module的回調(diào)函數(shù)里來(lái)進(jìn)行分組的攻柠。在測(cè)試結(jié)果里都是模塊名稱(chēng)打頭的护赊,后面才是跟著具體的測(cè)試名稱(chēng)给赞。其他模塊可以嵌套在這個(gè)回調(diào)函數(shù)中初婆,其中它們的測(cè)試名稱(chēng)將由它們的名稱(chēng)標(biāo)記蓬坡,并以其父模塊為前綴。

如果QUnit.module定義的時(shí)候沒(méi)有nested回調(diào)參數(shù)磅叛,所有后來(lái)定義的測(cè)試方法都被分組到這個(gè)模塊里屑咳,直到另一個(gè)模塊被定義。

有一組測(cè)試方法的module可以定義嵌套的module弊琴,在深入嵌套之前兆龙,QUnit會(huì)先在父module上跑測(cè)試,即使那些嵌套的module在父module最頂部定義了敲董。此外紫皇,父模塊上的任何鉤子回調(diào)都會(huì)將掛鉤包裝在嵌套模塊上。換句話說(shuō)腋寨,before 和 beforeEach回調(diào)會(huì)形成一個(gè)隊(duì)列聪铺,afterEach 和 after會(huì)形成一個(gè)棧。

你可以用鉤子指定你在測(cè)試之前或測(cè)試之后需要做的事情萄窜,還可以創(chuàng)建用來(lái)在module內(nèi)部的測(cè)試方法之間共享屬性铃剔。鉤子對(duì)象上的任何其他屬性都將添加到該module中。如果你嵌套了子module查刻,hooks參數(shù)是可選的番宁。

The module’s callback is invoked with the test environment as its this context, with the environment’s properties copied to the module’s tests, hooks, and nested modules. Note that changes on tests’ this are not preserved between sibling tests, where this will be reset to the initial value for each test.

如果你的回調(diào)函數(shù)返回了了一個(gè)then,可用的Promise赖阻,QUnit.module的鉤子能自動(dòng)幫你進(jìn)行一部結(jié)果的解析蝶押。

指定運(yùn)行測(cè)試代碼

當(dāng)你在調(diào)試你的代碼時(shí),通常只需要運(yùn)行一部分的測(cè)試代碼火欧。那你可以在QUnit.module后加上only告訴QUnit你想要運(yùn)行的module棋电。

如果有多個(gè) QUnit.module.only(),則只運(yùn)行最先定義的苇侵。

QUnit.only()也可以運(yùn)行赶盔。

指定跳過(guò)測(cè)試代碼

隨著代碼越來(lái)越龐大,你會(huì)發(fā)現(xiàn)有些與功能相關(guān)的測(cè)試由于某些原因暫時(shí)中斷榆浓。在你找到bug之前于未,你可以使用skip跳過(guò)這些損壞的模塊。

如果子組件和測(cè)試包含一些todo或僅僅是tests,QUnit也會(huì)跳過(guò)這些測(cè)試代碼烘浦。

正在編寫(xiě)的測(cè)試

當(dāng)這個(gè)module還在編寫(xiě)階段抖坪,你可以用 QUnit.module.todo來(lái)標(biāo)記。

Using this method will mark all underlying tests as todo as if they were defined using QUnit.todo except for tests defined using QUnit.skip() which will be left intact. Those tests will pass as long as one failing assertion is present.

If all assertions pass, then the tests will fail signaling that QUnit.module.todo should be replaced by QUnit.module.

例子

使用QUnit.module方法標(biāo)記一組測(cè)試方法

QUnit.module( "group a" );
QUnit.test( "a basic test example", function( assert ) {
  assert.ok( true, "this test is fine" );
});
QUnit.test( "a basic test example 2", function( assert ) {
  assert.ok( true, "this test is fine" );
});

 QUnit.module( "group b" );
    QUnit.test( "a basic test example 3", function( assert ) {
      assert.ok( true, "this test is fine" );
    });
    QUnit.test( "a basic test example 4", function( assert ) {
      assert.ok( true, "this test is fine" );
    });

使用現(xiàn)代語(yǔ)法

QUnit.module( "group a" );

test( "a basic test example", t => {
  t.ok( true, "this test is fine" );
});
test( "a basic test example 2", t => {
  t.ok( true, "this test is fine" );
});

QUnit.module( "group b" );
test( "a basic test example 3", t => {
  t.ok( true, "this test is fine" );
});
test( "a basic test example 4", t => {
  t.ok( true, "this test is fine" );
});

嵌套用法

QUnit.module( "module a", function() {
  QUnit.test( "a basic test example", function( assert ) {
    assert.ok( true, "this test is fine" );
  });
});

QUnit.module( "module b", function() {
  QUnit.test( "a basic test example 2", function( assert ) {
    assert.ok( true, "this test is fine" );
  });

  QUnit.module( "nested module b.1", function() {

    // This test will be prefixed with the following module label:
    // "module b > nested module b.1"
    QUnit.test( "a basic test example 3", function( assert ) {
      assert.ok( true, "this test is fine" );
    });
  });
});

使用現(xiàn)代語(yǔ)法

const { test } = QUnit;
QUnit.module( "module a", () => {
  test( "a basic test example", t => {
    t.ok( true, "this test is fine" );
  });
});

QUnit.module( "module b", () => {
  test( "a basic test example 2", t => {
    t.ok( true, "this test is fine" );
  });

  QUnit.module( "nested module b.1", () => {

    // This test will be prefixed with the following module label:
    // "module b > nested module b.1"
    test( "a basic test example 3", t => {
      t.ok( true, "this test is fine" );
    });
  });
});

before, beforeEach, afterEach, and after 鉤子的用法

QUnit.module( "module A", {
  before: function() {
    // prepare something once for all tests
  },
  beforeEach: function() {
    // prepare something before each test
  },
  afterEach: function() {
    // clean up after each test
  },
  after: function() {
    // clean up once after all tests are done
  }
});

共同上下文環(huán)境的鉤子和測(cè)試共享變量

QUnit.module( "Machine Maker", {
  beforeEach: function() {
    this.maker = new Maker();
    this.parts = [ "wheels", "motor", "chassis" ];
  }
});

QUnit.test( "makes a robot", function( assert ) {
  this.parts.push( "arduino" );
  assert.equal( this.maker.build( this.parts ), "robot" );
  assert.deepEqual( this.maker.made, [ "robot" ] );
});

QUnit.test( "makes a car", function( assert ) {
  assert.equal( this.maker.build( this.parts ), "car" );
  this.maker.duplicate();
  assert.deepEqual( this.maker.made, [ "car", "car" ] );
});

before/beforeEach鉤子在嵌套模塊中以隊(duì)列方式調(diào)用闷叉,after/afterEach鉤子在嵌套模塊中以棧方式調(diào)用

QUnit.module( "grouped tests argument hooks", function( hooks ) {

  // You can invoke the hooks methods more than once.
  hooks.beforeEach( function( assert ) {
    assert.ok( true, "beforeEach called" );
  } );

  hooks.afterEach( function( assert ) {
    assert.ok( true, "afterEach called" );
  } );

  QUnit.test( "call hooks", function( assert ) {
    assert.expect( 2 );
  } );

  QUnit.module( "stacked hooks", function( hooks ) {

    // This will run after the parent module's beforeEach hook
    hooks.beforeEach( function( assert ) {
      assert.ok( true, "nested beforeEach called" );
    } );

    // This will run before the parent module's afterEach
    hooks.afterEach( function( assert ) {
      assert.ok( true, "nested afterEach called" );
    } );

    QUnit.test( "call hooks", function( assert ) {
      assert.expect( 4 );
    } );
  } );
} );

在鉤子里處理異步返回的例子擦俐,例子使用es6的Promise接口,操作是連接握侧、斷開(kāi)數(shù)據(jù)庫(kù)

QUnit.module( "Database connection", {
  before: function() {
    return new Promise( function( resolve, reject ) {
      DB.connect( function( err ) {
        if ( err ) {
          reject( err );
        } else {
          resolve();
        }
      } );
    } );
  },
  after: function() {
    return new Promise( function( resolve, reject ) {
      DB.disconnect( function( err ) {
        if ( err ) {
          reject( err );
        } else {
          resolve();
        }
      } );
    } );
  }
} );

只跑一部分測(cè)試代碼

QUnit.module( "Robot", function() {
  // ...
} );

// Currenly working on implementing features related to androids
QUnit.module.only( "Android", function( hooks ) {
  hooks.beforeEach( function() {
    this.android = new Android();
  } );

  QUnit.test( "Say hello", function( assert ) {
    assert.strictEqual( this.android.hello(), "Hello, my name is AN-2178!" );
  } );

  QUnit.test( "Basic conversation", function( assert ) {
    this.android.loadConversationData( {
      "Hi": "Hello",
      "What's your name?": "My name is AN-2178.",
      "Nice to meet you!": "Nice to meet you too!",
      "...": "..."
    } );

    assert.strictEqual(
      this.android.answer( "What's your name?" ), "My name is AN-2178."
    );
  } );

  // ...
} );

跳過(guò)損壞模塊

QUnit.module( "Robot", function() {
  // ...
} );

// Tests related to androids are failling due to unkown cause.
// Skipping them for now.
QUnit.module.skip( "Android", function( hooks ) {
  hooks.beforeEach( function() {
    this.android = new Android();
  } );

  QUnit.test( "Say hello", function( assert ) {
    assert.strictEqual( this.android.hello(), "Hello, my name is AN-2178!" );
  } );

  QUnit.test( "Basic conversation", function( assert ) {
    // ...
    assert.strictEqual(
      this.android.answer( "Nice to meet you!" ), "Nice to meet you too!"
    );
  } );

  QUnit.test( "Move left arm", function ( assert ) {
    // Move the left arm of the android to point (10, 50)
    this.android.moveLeftArmTo( 10, 50 );

    assert.deepEqual( this.android.getLeftArmPosition(), { x: 10, y: 50 } );
  } );

  QUnit.test( "Move right arm", function ( assert ) {
    // Move the right arm of the android to point (15, 45)
    this.android.moveRightArmTo( 15, 45 );

    assert.deepEqual( this.android.getRightArmPosition(), { x: 15, y: 45 } );
  } );

  QUnit.test( "Grab things", function ( assert ) {
    // Move the arm of the android to point (10, 50)
    this.android.grabThingAt( 25, 5 );

    assert.deepEqual( this.android.getPosition(), { x: 25, y: 5 } );
    assert.ok( this.android.isGrabbing() );
  } );

  QUnit.test( "Can walk", function ( assert ) {
    assert.ok( this.android.canWalk() );
  } );

  QUnit.test( "Can speak", function ( assert ) {
    assert.ok( this.android.canSpeak() );
  } );

  // ...
} );

使用 QUnit.module.todo()來(lái)標(biāo)記代碼還在編寫(xiě)中

QUnit.module.todo( "Robot", function( hooks ) {
  hooks.beforeEach( function() {
    this.robot = new Robot();
  } );

  QUnit.test( "Say", function( assert ) {
    // Currently, it returns undefined
    assert.strictEqual( this.robot.say(), "I'm Robot FN-2187" );
  } );

  QUnit.test( "Move arm", function ( assert ) {
    // Move the arm to point (75, 80). Currently, it throws a NotImplementedError
    assert.throws( function() {
      this.robot.moveArmTo(75, 80);
    }, /Not yet implemented/ );

    assert.throws( function() {
      assert.deepEqual( this.robot.getPosition(), { x: 75, y: 80 } );
    }, /Not yet implemented/ );
  } );

  // ...
} );

- only

QUnit.only( name, callback )
添加單獨(dú)運(yùn)行的測(cè)試蚯瞧,阻止其他測(cè)試代碼運(yùn)行
<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>name (string)</td>
<td>名稱(chēng)</td>
</tr>
<tr>
<td>callback (function)</td>
<td>Function to close over assertions</td>
</tr>
</table>
回調(diào)的參數(shù): callback( assert ):
<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>assert (object) </td>
<td>斷言方法的新的實(shí)例對(duì)象</td>
</tr>
</table>

描述

這個(gè)方法能幫助你專(zhuān)注于你的特殊測(cè)試單元,QUnit.only會(huì)導(dǎo)致運(yùn)行時(shí)其他的測(cè)試被忽略品擎。

如果QUnit.only有多個(gè)埋合,則只運(yùn)行最早定義的那個(gè)。

當(dāng)有測(cè)試代碼中大量的測(cè)試或者想要在控制臺(tái)看測(cè)試輸出時(shí)萄传,這個(gè)方法非常有用饥悴。可以在頁(yè)面的結(jié)果輸出頁(yè)面過(guò)濾其他測(cè)試的輸出盲再。

例子

如何使用 QUnit.only

QUnit.module( "robot", {
  beforeEach: function() {
    this.robot = new Robot();
  }
});

QUnit.test( "say", function( assert ) {
  assert.ok( false, "I'm not quite ready yet" );
});

QUnit.test( "stomp", function( assert ) {
  assert.ok( false, "I'm not quite ready yet" );
});

// You're currently working on the laser feature, so we run only this test
QUnit.only( "laser", function( assert ) {
  assert.ok( this.robot.laser() );
});

使用現(xiàn)代語(yǔ)法

const { test, only } = QUnit;

QUnit.module( "robot", {
  beforeEach: function() {
    this.robot = new Robot();
  }
});

test( "say", t => {
  t.ok( false, "I'm not quite ready yet" );
});

test( "stomp", t => {
  t.ok( false, "I'm not quite ready yet" );
});

// You're currently working on the laser feature, so we run only this test
only( "laser", function( t ) {
  t.ok( this.robot.laser() );
});

- skip

QUnit.skip( name )
跳過(guò)指定測(cè)試方法
<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>name (string)</td>
<td>名稱(chēng)</td>
</tr>
</table>

描述

使用這個(gè)方法替換掉QUnit.test()來(lái)跳過(guò)整個(gè)測(cè)試方法

This test’s prototype will be listed on the suite as a skipped test, ignoring the callback argument and the respective global and module’s hooks.

Example

如何使用skip方法

QUnit.module( "robot", {
  beforeEach: function() {
    this.robot = new Robot();
  }
});

QUnit.test( "say", function( assert ) {
  assert.strictEqual( this.robot.say(), "Exterminate!" );
});

// Robot doesn't have a laser method, yet, skip this test
// Will show up as skipped in the results
QUnit.skip( "laser", function( assert ) {
  assert.ok( this.robot.laser() );
});

使用現(xiàn)代語(yǔ)法

const { test, skip } = QUnit;

QUnit.module( "robot", {
  beforeEach() {
    this.robot = new Robot();
  }
});

test( "say", function( t ) {
  t.strictEqual( this.robot.say(), "Exterminate!" );
});

// Robot doesn't have a laser method, yet, skip this test
// Will show up as skipped in the results
skip( "laser", function( t ) {
  t.ok( this.robot.laser() );
});

- start

QUnit.start()

略(#TODO)

- test

QUnit.test( name, callback )
添加測(cè)試方法
<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>name (string)</td>
<td>名稱(chēng)</td>
</tr>
<tr>
<td>callback (function)</td>
<td>Function to close over assertions</td>
</tr>
</table>
回調(diào)參數(shù)
<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>assert (object)</td>
<td>斷言方法的新的實(shí)例對(duì)象</td>
</tr>
</table>

描述

使用QUnit.test()添加測(cè)試方法

這個(gè)assert參數(shù)包含了QUnit所有的斷言方法宅粥,使用這個(gè)參數(shù)進(jìn)行斷言

如果你的回調(diào)函數(shù)返回了了一個(gè)then撒璧,可用的Promise术辐,QUnit.test能自動(dòng)幫你進(jìn)行一部結(jié)果的解析渡处。

例子

一個(gè)實(shí)際的例子,使用局部的assert參數(shù)

function square( x ) {
  return x * x;
}

QUnit.test( "square()", function( assert ) {
  var result = square( 2 );

  assert.equal( result, 4, "square(2) equals 4" );
});

使用現(xiàn)代語(yǔ)法

function square( x ) {
  return x * x;
}

const { test } = QUnit;

test( "square()", t => {
  t.equal( square( 2 ), 4, "square(2) equals 4" );
  t.equal( square( 3 ), 9, "square(3) equals 9" );
});

關(guān)于處理Promise異步返回的一個(gè)例子梦碗,例子使用的是es6的Promise并且延時(shí)了500ms

QUnit.test( "a Promise-returning test", function( assert ) {
  assert.expect( 1 );

  var thenable = new Promise(function( resolve, reject ) {
    setTimeout(function() {
      assert.ok( true );
      resolve( "result" );
    }, 500 );
  });
  return thenable;
});

接著上面的例子禽绪,QUnit.test也支持js的async方法。

function squareAfter1Second(x) {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(x * x);
    }, 1000);
  });
}

const { test } = QUnit;

test( "an async test", async t => {
  var a = await squareAfter1Second(2);
  var b = await squareAfter1Second(3);

  t.equal( a, 4 );
  t.equal( b, 9 );
  t.equal( await squareAfter1Second(5), 25 );
});

- todo

QUnit.todo( name, callback )
添加一個(gè)在運(yùn)行期間至少有個(gè)失敗斷言的測(cè)試
<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>name (string)</td>
<td>名稱(chēng)</td>
</tr>
<tr>
<td>callback (function)</td>
<td>Function to close over assertions</td>
</tr>
</table>
回調(diào)參數(shù): callback( assert ):
<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>assert (object)</td>
<td>斷言方法的新的實(shí)例對(duì)象</td>
</tr>
</table>

描述

可以使用這個(gè)方法去測(cè)試還在開(kāi)發(fā)階段的代碼洪规。只要存在一個(gè)失敗的斷言印屁,測(cè)試就會(huì)通過(guò)。

如果全部斷言都通過(guò)斩例,測(cè)試后會(huì)有個(gè)失敗結(jié)果雄人,然后應(yīng)該替換成QUnit.test

例子

如何使用QUnit.todo

QUnit.module( "robot", {
  beforeEach: function() {
    this.robot = new Robot();
  }
});

// fireLazer hasn't been properly implemented yet, so this is a todo test
QUnit.todo( "fireLazer returns the correct value", function( assert ) {
  var result = this.robot.fireLazer(); // Currently returns undefined
  assert.equal( result, "I'm firing my lazer!" );
});

斷言

- async

async( [ acceptCallCount = 1 ] )

等待異步操作
<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>acceptCallCount (Number)</td>
<td>在測(cè)試完成之前期望回調(diào)次數(shù),默認(rèn)是1</td>
</tr>
</table>

介紹

assert.async()返回一個(gè)回調(diào)函數(shù)念赶,并且暫停測(cè)試進(jìn)程直到回調(diào)方法被調(diào)用指定的次數(shù)础钠。The callback will throw an Error if it is invoked more often than the accepted call count.

這取代了先前由QUnit.stop()和QUnit.start()提供的功能

例子

讓QUnit等待定時(shí)器里的done方法調(diào)用(#TODO,以后不確定的就用#TODO)

QUnit.test( "assert.async() test", function( assert ) {
  var done = assert.async();
  var input = $( "#test-input" ).focus();
  setTimeout(function() {
    assert.equal( document.activeElement, input[0], "Input was focused" );
    done();
  });
});

為了每一個(gè)操作assert.async()叉谜,每一個(gè)done回調(diào)被調(diào)用至多一次

QUnit.test( "two async calls", function( assert ) {
  assert.expect( 2 );

  var done1 = assert.async();
  var done2 = assert.async();
  setTimeout(function() {
    assert.ok( true, "test resumed from async operation 1" );
    done1();
  }, 500 );
  setTimeout(function() {
    assert.ok( true, "test resumed from async operation 2" );
    done2();
  }, 150);
});

設(shè)置異步測(cè)試三個(gè)退出點(diǎn)旗吁。 每個(gè)done()調(diào)用都會(huì)累加到acceptCallCount。 三次調(diào)用后停局,測(cè)試完成

QUnit.test( "multiple call done()", function( assert ) {
  assert.expect( 3 );
  var done = assert.async( 3 );

  setTimeout(function() {
    assert.ok( true, "first call done." );
    done();
  }, 500 );

  setTimeout(function() {
    assert.ok( true, "second call done." );
    done();
  }, 500 );

  setTimeout(function() {
    assert.ok( true, "third call done." );
    done();
  }, 500 );
});

- deepEqual

深度遞歸比較很钓,處理原始類(lèi)型香府,數(shù)組,對(duì)象码倦,正則表達(dá)式企孩,日期和函數(shù)

<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>actual</td>
<td>測(cè)試的值</td>
</tr>
<tr>
<td>expected</td>
<td>已知被比較的值</td>
</tr>
<tr>
<td>message(string)</td>
<td>描述</td>
</tr>
</table>

介紹

如果是判斷兩個(gè)對(duì)象相不相等,比如說(shuō)像這樣子的叹洲,{ key: value } 等于 { key: value }柠硕。deepEqual斷言可以像equal()那樣子去使用工禾。對(duì)于non-scalar values运提、identity會(huì)被deepEqual無(wú)視

notDeepEqual()可用于顯式測(cè)試深度,嚴(yán)格的不等式

例子

比較兩個(gè)對(duì)象

QUnit.test( "deepEqual test", function( assert ) {
  var obj = { foo: "bar" };

  assert.deepEqual( obj, { foo: "bar" }, "Two objects can be the same in value" );
});

- equal

equal( actual, expected [, message ] )

不嚴(yán)格比較闻葵,大致相當(dāng)于JUnit的assertEquals民泵。

<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>actual</td>
<td>測(cè)試的值</td>
</tr>
<tr>
<td>expected</td>
<td>已知被比較的值</td>
</tr>
<tr>
<td>message(string)</td>
<td>描述</td>
</tr>
</table>

描述

equal斷言用來(lái)簡(jiǎn)單比較actual和expected這兩個(gè)參數(shù),跟操作符(==)相似槽畔。如果相等栈妆,則斷言通過(guò);否則就失敗厢钧。如果失敗了鳞尔,actual和expected這兩個(gè)值會(huì)展示在測(cè)試結(jié)果上。除了給定的消息早直。

notEqual用來(lái)判斷不相等寥假。

strictEqual用來(lái)判斷嚴(yán)格相等。

例子

簡(jiǎn)單的斷言例子

QUnit.test( "a test", function( assert ) {
  assert.equal( 1, "1", "String '1' and number 1 have the same value" );
});

一組稍微徹底點(diǎn)的斷言

QUnit.test( "equal test", function( assert ) {
  assert.equal( 0, 0, "Zero, Zero; equal succeeds" );
  assert.equal( "", 0, "Empty, Zero; equal succeeds" );
  assert.equal( "", "", "Empty, Empty; equal succeeds" );

  assert.equal( "three", 3, "Three, 3; equal fails" );
  assert.equal( null, false, "null, false; equal fails" );
});

- expect

expect( amount )

指定在測(cè)試中會(huì)有多少個(gè)斷言

<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>actual</td>
<td>斷言的數(shù)量</td>
</tr>
</table>

描述

確保在任何運(yùn)行中的測(cè)試的準(zhǔn)確斷言的數(shù)量霞扬,用assert.expert(number)注冊(cè)斷言的數(shù)量糕韧。如果運(yùn)行測(cè)試后斷言數(shù)量與注冊(cè)的斷言數(shù)量不匹配,則不通過(guò)測(cè)試

例子

聲明斷言數(shù)量

QUnit.test( "a test", function( assert ) {
  assert.expect( 2 );

  function calc( x, operation ) {
    return operation( x );
  }

  var result = calc( 2, function( x ) {
    assert.ok( true, "calc() calls operation function" );
    return x * x;
  });

  assert.equal( result, 4, "2 squared equals 4" );
});

- notDeepEqual

notDeepEqual( actual, expected [, message ] )

深度遞歸比較差異(與deepEqual相反喻圃,一個(gè)判相同萤彩,一個(gè)判不同),處理原始類(lèi)型斧拍,數(shù)組雀扶,對(duì)象,正則表達(dá)式肆汹,日期和函數(shù)

<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>actual</td>
<td>測(cè)試的值</td>
</tr>
<tr>
<td>expected</td>
<td>已知被比較的值</td>
</tr>
<tr>
<td>message(string)</td>
<td>描述</td>
</tr>
</table>

描述

如果是判斷兩個(gè)對(duì)象相不相等怕吴,比如說(shuō)像這樣子的,{ key: value } 等于 { key: value }县踢。notDeepEqual斷言可以像equal()那樣子去使用转绷。對(duì)于non-scalar values、identity會(huì)被notDeepEqual無(wú)視

deepEqual()可用于顯式測(cè)試深度硼啤,嚴(yán)格的相等式

例子

比較兩個(gè)對(duì)象

QUnit.test( "notDeepEqual test", function( assert ) {
  var obj = { foo: "bar" };

  assert.notDeepEqual( obj, { foo: "bla" }, "Different object, same key, different value, not equal" );
});

- notEqual

notEqual( actual, expected [, message ] )

不嚴(yán)格比較议经,用來(lái)判斷不等

<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>actual</td>
<td>測(cè)試的值</td>
</tr>
<tr>
<td>expected</td>
<td>已知被比較的值</td>
</tr>
<tr>
<td>message(string)</td>
<td>描述</td>
</tr>
</table>

描述

notEqual斷言用來(lái)簡(jiǎn)單比較actual和expected這兩個(gè)參數(shù),跟操作符(!=)相似。如果不相等煞肾,則斷言通過(guò)咧织;否則就失敗。如果失敗了籍救,actual和expected這兩個(gè)值會(huì)展示在測(cè)試結(jié)果上习绢,除了給定的消息。

equal用來(lái)判斷相等

notStrictEqual()用來(lái)判斷嚴(yán)格不相等

例子

簡(jiǎn)單的例子

QUnit.test( "a test", function( assert ) {
  assert.notEqual( 1, "2", "String '2' and number 1 don't have the same value" );
});

- notOk

notOk( state [, message ] )

和ok()和CommonJS的assert.ok()相反蝙昙,與JUnit的assertFalse等價(jià)闪萄。第一個(gè)參數(shù)為false就通過(guò)測(cè)試

<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>state</td>
<td>測(cè)試的值</td>
</tr>
<tr>
<td>message(string)</td>
<td>描述</td>
</tr>
</table>

描述

notOk()只需要一個(gè)參數(shù)。如果參數(shù)為false奇颠,則測(cè)試通過(guò)败去;否則就失敗。如果提供了第二個(gè)參數(shù)烈拒,會(huì)在結(jié)果那里展示出來(lái)圆裕。

例子

QUnit.test( "notOk test", function( assert ) {
  assert.notOk( false, "false succeeds" );
  assert.notOk( "", "empty string succeeds" );
  assert.notOk( NaN, "NaN succeeds" );
  assert.notOk( null, "null succeeds" );
  assert.notOk( undefined, "undefined succeeds" );

  assert.notOk( true, "true fails" );
  assert.notOk( 1, "1 fails" );
  assert.notOk( "not-empty", "not-empty string fails" );
});

- notPropEqual

notPropEqual( actual, expected [, message ] )

嚴(yán)格比較對(duì)象的屬性,判斷不相等則通過(guò)測(cè)試

<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>actual</td>
<td>測(cè)試的值</td>
</tr>
<tr>
<td>expected</td>
<td>已知被比較的值</td>
</tr>
<tr>
<td>message(string)</td>
<td>描述</td>
</tr>
</table>

描述

notPropEqual斷言用來(lái)嚴(yán)格判斷對(duì)象的屬性相不相等荆几,并不是constructors吓妆。不相等測(cè)試就通過(guò)。

例子

比較兩個(gè)對(duì)象的屬性相不相等

QUnit.test( "notPropEqual test", function( assert ) {
  function Foo( x, y, z ) {
    this.x = x;
    this.y = y;
    this.z = z;
  }
  Foo.prototype.doA = function () {};
  Foo.prototype.doB = function () {};
  Foo.prototype.bar = 'prototype';

  var foo = new Foo( 1, "2", [] );
  var bar = new Foo( "1", 2, {} );
  assert.notPropEqual( foo, bar, "Properties values are strictly compared." );
});

- notStrictEqual

notStrictEqual( actual, expected [, message ] )

嚴(yán)格比較相不相等

<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>actual</td>
<td>測(cè)試的值</td>
</tr>
<tr>
<td>expected</td>
<td>已知被比較的值</td>
</tr>
<tr>
<td>message(string)</td>
<td>描述</td>
</tr>
</table>

描述

notStrictEqual斷言用來(lái)簡(jiǎn)單比較actual和expected這兩個(gè)參數(shù)吨铸,跟操作符(!==)相似行拢。如果不相等,則斷言通過(guò)焊傅;否則就失敗剂陡。如果失敗了,actual和expected這兩個(gè)值會(huì)展示在測(cè)試結(jié)果上狐胎。除了給定的消息鸭栖。

strictEqual()用來(lái)嚴(yán)格判斷相等

例子

簡(jiǎn)單的例子

QUnit.test( "a test", function( assert ) {
  assert.notStrictEqual( 1, "1", "String '1' and number 1 have the same value but not the same type" );
});

- ok

ok( state [, message ] )

等價(jià)于CommonJS的assert.ok()和JUnit的assertTrue().state參數(shù)為true,則則是通過(guò)握巢。

<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>state</td>
<td>測(cè)試的值</td>
</tr>
<tr>
<td>message(string)</td>
<td>描述</td>
</tr>
</table>

描述

在QUnit中最基礎(chǔ)的斷言晕鹊,只需要一個(gè)參數(shù)。如果個(gè)為true暴浦,則測(cè)試通過(guò)溅话,如果為false,則測(cè)試失敗歌焦。如果提供了第二個(gè)參數(shù)msg飞几,msg則會(huì)顯示在測(cè)試結(jié)果上。

例子

QUnit.test( "ok test", function( assert ) {
  assert.ok( true, "true succeeds" );
  assert.ok( "non-empty", "non-empty string succeeds" );

  assert.ok( false, "false fails" );
  assert.ok( 0, "0 fails" );
  assert.ok( NaN, "NaN fails" );
  assert.ok( "", "empty string fails" );
  assert.ok( null, "null fails" );
  assert.ok( undefined, "undefined fails" );
});

- propEqual

propEqual( actual, expected [, message ] )

比較對(duì)象的屬性

<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>actual</td>
<td>測(cè)試的值</td>
</tr>
<tr>
<td>expected</td>
<td>已知被比較的值</td>
</tr>
<tr>
<td>message(string)</td>
<td>描述</td>
</tr>
</table>

描述

propEqual斷言判斷對(duì)象的屬性独撇,相等則通過(guò)屑墨,不相等則不通過(guò)躁锁。跟操作符(===)類(lèi)似。不同于deppEqual卵史,propEqual使用來(lái)判斷對(duì)象的屬性和constructors相不相等的战转。

例子

比較兩個(gè)對(duì)象的屬性

QUnit.test( "propEqual test", function( assert ) {
  function Foo( x, y, z ) {
    this.x = x;
    this.y = y;
    this.z = z;
  }
  Foo.prototype.doA = function () {};
  Foo.prototype.doB = function () {};
  Foo.prototype.bar = 'prototype';

  var foo = new Foo( 1, "2", [] );
  var bar = {
    x : 1,
    y : "2",
    z : []
  };
  assert.propEqual( foo, bar, "Strictly the same properties without comparing objects constructors." );
});

- pushResult

pushResult( data: { result, actual, expected, message } )

報(bào)告自定義斷言的結(jié)果

<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>data.result (boolean)</td>
<td>斷言的結(jié)果</td>
</tr>
<tr>
<td>data.actual</td>
<td>測(cè)試的值</td>
</tr>
<tr>
<td> data.expected</td>
<td>期望的值</td>
</tr>
<tr>
<td> data.message(string)</td>
<td>描述</td>
</tr>
</table>

描述

某些測(cè)試套件可能需要表達(dá)QUnit的任何內(nèi)置斷言未定義的期望∫郧可以通過(guò)將期望封裝在JavaScript函數(shù)中來(lái)滿足此需求(#TODO)槐秧,該JavaScript函數(shù)返回布爾值。然后將此值傳遞給ok()斷言

A more readable solution would involve defining a custom assertion. If the expectation function invokes pushResult, QUnit will be notified of the result and report it accordingly.

例子

定義自定義斷言mod2忧设,在modulo2刁标,如果提供的參數(shù)是等價(jià)的則通過(guò)。

QUnit.assert.mod2 = function( value, expected, message ) {
    var actual = value % 2;
    this.pushResult( {
        result: actual === expected,
        actual: actual,
        expected: expected,
        message: message
    } );
};

QUnit.test( "mod2", function( assert ) {
    assert.expect( 2 );

    assert.mod2( 2, 0, "2 % 2 == 0" );
    assert.mod2( 3, 1, "3 % 2 == 1" );
});

- rejects

rejects( promise[, expectedMatcher][, message ] )

Test if the provided promise rejects, and optionally compare the rejection value.

<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>promise (thenable)</td>
<td>返回的rejects</td>
</tr>
<tr>
<td>expectedMatcher</td>
<td>比較Reject值的方法</td>
</tr>
<tr>
<td>message (string)</td>
<td>描述</td>
</tr>
</table>

描述

當(dāng)測(cè)試代碼基于一組特定的環(huán)境想要返回rejects時(shí)见转,使用assert.rejects()測(cè)試并比較

expectedMatcher方法的參數(shù)可以是

  • 斷言通過(guò)時(shí)返回true的方法

  • 錯(cuò)誤對(duì)象

  • A base constructor to use ala rejectionValue instanceof expectedMatcher

  • 匹配 rejectionValue.toString()
    的正則

提示:為了避免把 message 和 expectedMatcher搞混了命雀,expectedMatcher不能是string

例子

糾正錯(cuò)誤信息的斷言收到自定義錯(cuò)誤對(duì)象(#TODO)

QUnit.test( "rejects", function( assert ) {

  assert.rejects(Promise.reject("some error description"));

  assert.rejects(
    Promise.reject(new Error("some error description")),
    "rejects with just a message, not using the 'expectedMatcher' argument"
  );

  assert.rejects(
    Promise.reject(new Error("some error description")),
    /description/,
    "`rejectionValue.toString()` contains `description`"
  );

  // Using a custom error like object
  function CustomError( message ) {
    this.message = message;
  }

  CustomError.prototype.toString = function() {
    return this.message;
  };

  assert.rejects(
    Promise.reject(new CustomError()),
    CustomError,
    "raised error is an instance of CustomError"
  );

  assert.rejects(
    Promise.reject(new CustomError("some error description")),
    new CustomError("some error description"),
    "raised error instance matches the CustomError instance"
  );

  assert.rejects(
    Promise.reject(new CustomError("some error description")),
    function( err ) {
      return err.toString() === "some error description";
    },
    "raised error instance satisfies the callback function"
  );
});

- step

step( [ message ] )

給定測(cè)試的進(jìn)度標(biāo)記

<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>message (string)</td>
<td>描述</td>
</tr>
</table>

描述

step通常都會(huì)通過(guò)不報(bào)錯(cuò)的蒜哀,除非你傳的參數(shù)不是string類(lèi)型或者沒(méi)傳參數(shù)斩箫。step使用提供的消息注冊(cè)測(cè)試中的斷言。這使得開(kāi)發(fā)者容易檢查執(zhí)行中代碼的關(guān)鍵點(diǎn)撵儿,特別是在異步測(cè)試的時(shí)候和使用verifySteps的時(shí)候乘客。

與verifySteps一起使用的時(shí)候,step斷言幫你驗(yàn)證代碼執(zhí)行的順序和執(zhí)行次數(shù)

例子

QUnit.test( "step test", function( assert ) {
  assert.expect( 1 );
  obj.hook = function() {
    assert.step('Hook is called!');
  };
  obj.invokeHookIndirectly();
});
提示:查看verifySteps淀歇,知道更多內(nèi)容和例子

- strictEqual

strictEqual( actual, expected [, message ] )

嚴(yán)格類(lèi)型易核、值的比較

<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>actual</td>
<td>測(cè)試的值</td>
</tr>
<tr>
<td>expected</td>
<td>已知被比較的值</td>
</tr>
<tr>
<td>message(string)</td>
<td>描述</td>
</tr>
</table>

描述

提供嚴(yán)格的類(lèi)型、值的比較浪默。與操作符(===)等價(jià)

例子

QUnit.test( "strictEqual test", function( assert ) {
  assert.strictEqual( 1, 1, "1 and 1 have the same value and type" );
}); 

- throws

throws( blockFn[, expectedMatcher][, message ] )

Test if a callback throws an exception, and optionally compare the thrown error.

<table>
<thead>
<tr>
<td>參數(shù)</td>
<td>描述</td>
</tr>
</thead>
<tbody>
<tr>
<td>blockFn (function)</td>
<td>執(zhí)行的方法</td>
</tr>
<tr>
<td>expectedMatcher</td>
<td>錯(cuò)誤處理方法</td>
</tr>
<tr>
<td>message(string)</td>
<td>描述</td>
</tr>
</table>

描述

當(dāng)測(cè)試代碼基于一組特定的環(huán)境期望拋出錯(cuò)誤時(shí)牡直,使用assert.throws()捕捉錯(cuò)誤對(duì)像并比較是否相同。

expectedMatcher的參數(shù)

  • 錯(cuò)誤對(duì)象

  • An Error constructor to use ala errorValue instanceof expectedMatcher

  • 匹配錯(cuò)誤提示的正則

  • 必須返回true的回調(diào)以通過(guò)測(cè)試

  • 在極少數(shù)的環(huán)境下纳决,像Closure Compiler碰逸,異常信息是不返回的并且會(huì)因?yàn)榘l(fā)生錯(cuò)誤而中斷。對(duì)于這種情況阔加,別名被捆綁稱(chēng)為引發(fā)饵史。 它具有相同的簽名和行為,只是一個(gè)不同的名稱(chēng)胜榔。(#TODO)

例子

糾正錯(cuò)誤信息的斷言收到自定義錯(cuò)誤對(duì)象(#TODO)

QUnit.test( "throws", function( assert ) {

  function CustomError( message ) {
    this.message = message;
  }

  CustomError.prototype.toString = function() {
    return this.message;
  };

  assert.throws(
    function() {
      throw "error"
    },
    "throws with just a message, not using the 'expected' argument"
  );

  assert.throws(
    function() {
      throw new CustomError("some error description");
    },
    /description/,
    "raised error message contains 'description'"
  );

  assert.throws(
    function() {
      throw new CustomError();
    },
    CustomError,
    "raised error is an instance of CustomError"
  );

  assert.throws(
    function() {
      throw new CustomError("some error description");
    },
    new CustomError("some error description"),
    "raised error instance matches the CustomError instance"
  );

  assert.throws(
    function() {
      throw new CustomError("some error description");
    },
    function( err ) {
      return err.toString() === "some error description";
    },
    "raised error instance satisfies the callback function"
  );
});

- timeout

timeout( duration )

(#TODO)

描述

(#TODO)

例子

QUnit.test( "Waiting for focus event", function( assert ) {
  assert.timeout( 1000 ); // Timeout of 1 second
  var done = assert.async();
  var input = $( "#test-input" ).focus();
  setTimeout(function() {
    assert.equal( document.activeElement, input[0], "Input was focused" );
    done();
  });
});

--

QUnit.test( "Waiting for async function", function( assert ) {
  assert.timeout( 500 ); // Timeout of .5 seconds
  var promise = asyncFunction();
  return promise.then( function( result ) {
    assert.ok( result );
  } );
});

--

QUnit.test( "Waiting in an async test", async assert => {
  assert.timeout( 500 ); // Timeout of .5 seconds

  let result = await asyncFunction();
  assert.ok( result );
});

- verifySteps

verifySteps( steps [, message ] )

(#TODO)

描述

(#TODO)

例子

(#TODO)

QUnit.test( "user-defined hooks execute in correct order", function( assert ) {
  let lastStep = 'none';
  let startCount = 0;
  let middleCount = 0;
  let endCount = 0;

  obj.start = function() {
    assert.equal(lastStep, 'none');
    lastStep = 'start';
    startCount++;
  };
  obj.middle = function() {
    assert.equal(lastStep, 'start');
    lastStep = 'middle';
    middleCount++;
  };
  obj.end = function() {
    assert.equal(lastStep, 'middle');
    endCount++;
  };

  return obj.process().then(function() {
    assert.equal(startCount, 1);
    assert.equal(middleCount, 1);
    assert.equal(endCount, 1);
  });
});

(#TODO)

QUnit.test( "user-defined hooks execute in correct order", function( assert ) {
  obj.start = function() {
    assert.step('start');
  };
  obj.middle = function() {
    assert.step('middle');
  };
  obj.end = function() {
    assert.step('end');
  };

  return obj.process().then(function() {
    assert.verifySteps(['start', 'middle', 'end']);
  });
});

(#TODO)

QUnit.test( "subscribe/unsubscribe", function( assert ) {

  const publisher = new Publisher();
  const messages = [];

  const subscriber1 = message => messages.push(`Subscriber #1: ${message}`);
  const subscriber2 = message => messages.push(`Subscriber #2: ${message}`);

  publisher.subscribe(subscriber1);
  publisher.subscribe(subscriber2);

  publisher.publish('Hello!');

  publisher.unsubscribe(subscriber1);

  publisher.publish('World!');

  assert.deepEqual(messages, [
    'Subscriber #1: Hello!',
    'Subscriber #2: Hello!',
    'Subscriber #2: World!'
  ]);
});

(#TODO)

QUnit.test( "subscribe/unsubscribe", function( assert ) {

  const publisher = new Publisher();

  const subscriber1 = message => assert.step(`Subscriber #1: ${message}`);
  const subscriber2 = message => assert.step(`Subscriber #2: ${message}`);

  publisher.subscribe(subscriber1);
  publisher.subscribe(subscriber2);

  publisher.publish('Hello!');

  publisher.unsubscribe(subscriber1);

  publisher.publish('World!');

  assert.verifySteps([
    'Subscriber #1: Hello!',
    'Subscriber #2: Hello!',
    'Subscriber #2: World!'
  ]);
});

(#TODO)

QUnit.test( "verify steps", function test(assert){
    assert.expect( 5 );

    assert.step( "do stuff 1" );
    assert.step( "do stuff 2" );
    assert.verifySteps( [ "do stuff 1", "do stuff 2" ] );

    assert.step( "do stuff 3" );
    assert.verifySteps( [ "do stuff 3" ] );
} );
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末胳喷,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子夭织,更是在濱河造成了極大的恐慌吭露,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尊惰,死亡現(xiàn)場(chǎng)離奇詭異讲竿,居然都是意外死亡纬向,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)戴卜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)逾条,“玉大人,你說(shuō)我怎么就攤上這事投剥∈χ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵江锨,是天一觀的道長(zhǎng)吃警。 經(jīng)常有香客問(wèn)我,道長(zhǎng)啄育,這世上最難降的妖魔是什么酌心? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮挑豌,結(jié)果婚禮上安券,老公的妹妹穿的比我還像新娘。我一直安慰自己氓英,他們只是感情好侯勉,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著铝阐,像睡著了一般址貌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上徘键,一...
    開(kāi)封第一講書(shū)人閱讀 52,475評(píng)論 1 312
  • 那天练对,我揣著相機(jī)與錄音,去河邊找鬼吹害。 笑死螟凭,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的赠制。 我是一名探鬼主播赂摆,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼钟些!你這毒婦竟也來(lái)了烟号?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤政恍,失蹤者是張志新(化名)和其女友劉穎汪拥,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體篙耗,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡迫筑,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年宪赶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脯燃。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡搂妻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辕棚,到底是詐尸還是另有隱情欲主,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布逝嚎,位于F島的核電站扁瓢,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏补君。R本人自食惡果不足惜引几,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望挽铁。 院中可真熱鬧伟桅,春花似錦、人聲如沸屿储。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)够掠。三九已至,卻和暖如春茄菊,著一層夾襖步出監(jiān)牢的瞬間疯潭,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工面殖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留竖哩,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓脊僚,卻偏偏與公主長(zhǎng)得像相叁,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子辽幌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理增淹,服務(wù)發(fā)現(xiàn),斷路器乌企,智...
    卡卡羅2017閱讀 134,713評(píng)論 18 139
  • https://nodejs.org/api/documentation.html 工具模塊 Assert 測(cè)試 ...
    KeKeMars閱讀 6,340評(píng)論 0 6
  • 本次翻譯時(shí)間為2016年9月底哭当,目前Mocha的版本為3.1.0。官方文檔地址: http://mochajs.o...
    Awey閱讀 17,559評(píng)論 4 34
  • 步驟 全局安裝 mocha Fork 代碼倉(cāng)庫(kù)并拉到本地 啟動(dòng)測(cè)試 打開(kāi) ./test/test.js 修改代碼跑...
    Junting閱讀 5,167評(píng)論 0 1
  • 早上九點(diǎn)起床 看了資料分析的增長(zhǎng)量冗澈,知道:現(xiàn)期除以n+1 英語(yǔ)的括號(hào)钦勘,句讀之不知惑之不解,斷句亚亲。主謂个盆,主謂賓,主謂...
    飛宏_f667閱讀 324評(píng)論 0 0