Christian-health / StudyNote2017

2017年学习笔记
0 stars 0 forks source link

jasmine学习笔记 #16

Open Christian-health opened 6 years ago

Christian-health commented 6 years ago

https://jasmine.github.io/2.0/introduction.html

introduction.js 介绍

Jasmine is a behavior-driven development framework for testing JavaScript code. It does not depend on any other JavaScript frameworks. It does not require a DOM. And it has a clean, obvious syntax so that you can easily write tests. This guide is running against Jasmine version 2.6.0.

Jasmine是一个用于测试JavaScript代码的行为驱动开发框架。 它不依赖于任何其他JavaScript框架。 它不需要DOM。 它有一个干净,明显的语法,以便您可以轻松地编写测试。 本指南针对茉莉花版本2.6.0运行。

Christian-health commented 6 years ago

Standalone Distribution 独立分发

The releases page has links to download the standalone distribution, which contains everything you need to start running Jasmine. After downloading a particular version and unzipping, opening SpecRunner.html will run the included specs. You'll note that both the source files and their respective specs are linked in the of the SpecRunner.html. To start using Jasmine, replace the source/spec files with your own.

独立分发

发行版页面具有下载独立发行版的链接,其中包含开始运行Jasmine所需的所有内容。 下载特定版本并解压缩后,打开SpecRunner.html将运行附带的specs文件。 您将注意到源文件及其各自的specs都在SpecRunner.html的中链接。 要开始使用Jasmine,请用自己的源代码替换源/ spec文件。

Christian-health commented 6 years ago

Suites: describe Your Tests 测试集

A test suite begins with a call to the global Jasmine function describe with two parameters: a string and a function. The string is a name or title for a spec suite - usually what is being tested. The function is a block of code that implements the suite.

Christian-health commented 6 years ago

Specs 测试点

Specs are defined by calling the global Jasmine function it, which, like describe takes a string and a function. The string is the title of the spec and the function is the spec, or test. A spec contains one or more expectations that test the state of the code. An expectation in Jasmine is an assertion that is either true or false. A spec with all true expectations is a passing spec. A spec with one or more false expectations is a failing spec.

Christian-health commented 6 years ago

It's Just Functions

Since describe and it blocks are functions, they can contain any executable code necessary to implement the test. JavaScript scoping rules apply, so variables declared in a describe are available to any it block inside the suite.

Christian-health commented 6 years ago

Expectations 期望

Expectations are built with the function expect which takes a value, called the actual. It is chained with a Matcher function, which takes the expected value.

Christian-health commented 6 years ago

Matchers 匹配器

Each matcher implements a boolean comparison between the actual value and the expected value. It is responsible for reporting to Jasmine if the expectation is true or false. Jasmine will then pass or fail the spec.

Any matcher can evaluate to a negative assertion by chaining the call to expect with a not before calling the matcher. |  

Christian-health commented 6 years ago

Included Matchers 包括的匹配器

Jasmine has a rich set of matchers included. Each is used here - all expectations and specs pass. There is also the ability to write custom matchers for when a project's domain calls for specific assertions that are not included below.

Jasmine有丰富的匹配器。每个都在这里使用-----所有的期望和测试点。(意思是说,所有的期望和所有的测试点都在使用)。当Jasmine中的匹配器不能满足你的要求的时候,你可以实现自己的匹配器。

 describe("Included matchers:", function() {

  it("The 'toBe' matcher compares with ===", function() {
    var a = 12;
    var b = a;

    expect(a).toBe(b);    ///////////////匹配器/////////////////
    expect(a).not.toBe(null);    ///////////////匹配器/////////////////
  });

  describe("The 'toEqual' matcher", function() {

    it("works for simple literals and variables", function() {
      var a = 12;
      expect(a).toEqual(12);     ///////////////匹配器/////////////////
    });

    it("should work for objects", function() {
      var foo = {
        a: 12,
        b: 34
      };
      var bar = {
        a: 12,
        b: 34
      };
      expect(foo).toEqual(bar);    ///////////////匹配器/////////////////
    });
  });

  it("The 'toMatch' matcher is for regular expressions", function() {
    var message = "foo bar baz";

    expect(message).toMatch(/bar/);  ///////////////匹配器/////////////////
    expect(message).toMatch("bar");
    expect(message).not.toMatch(/quux/);   ///////////////匹配器/////////////////
  });

  it("The 'toBeDefined' matcher compares against `undefined`", function() {
    var a = {
      foo: "foo"
    };

    expect(a.foo).toBeDefined();   ///////////////匹配器/////////////////
    expect(a.bar).not.toBeDefined();   ///////////////匹配器/////////////////
  });

  it("The `toBeUndefined` matcher compares against `undefined`", function() {
    var a = {
      foo: "foo"
    };

    expect(a.foo).not.toBeUndefined();  ///////////////匹配器/////////////////
    expect(a.bar).toBeUndefined();  ////////////////匹配器/////////////////
  });

  it("The 'toBeNull' matcher compares against null", function() {
    var a = null;
    var foo = "foo";

    expect(null).toBeNull();   ///////////////匹配器/////////////////
    expect(a).toBeNull();
    expect(foo).not.toBeNull();   ///////////////匹配器/////////////////
  });

  it("The 'toBeTruthy' matcher is for boolean casting testing", function() {
    var a, foo = "foo";

    expect(foo).toBeTruthy(); ///////////////匹配器/////////////////
    expect(a).not.toBeTruthy();///////////////匹配器/////////////////
  });

  it("The 'toBeFalsy' matcher is for boolean casting testing", function() {
    var a, foo = "foo";

    expect(a).toBeFalsy(); ///////////////匹配器/////////////////
    expect(foo).not.toBeFalsy(); ///////////////匹配器/////////////////
  });

  describe("The 'toContain' matcher", function() {
    it("works for finding an item in an Array", function() {
      var a = ["foo", "bar", "baz"];

      expect(a).toContain("bar"); ///////////////匹配器/////////////////
      expect(a).not.toContain("quux");///////////////匹配器/////////////////
    });

    it("also works for finding a substring", function() {
      var a = "foo bar baz";

      expect(a).toContain("bar"); ///////////////匹配器/////////////////
      expect(a).not.toContain("quux");///////////////匹配器/////////////////
    });
  });

  it("The 'toBeLessThan' matcher is for mathematical comparisons", function() {
    var pi = 3.1415926,
      e = 2.78;

    expect(e).toBeLessThan(pi); ///////////////匹配器/////////////////
    expect(pi).not.toBeLessThan(e);///////////////匹配器/////////////////
  });

  it("The 'toBeGreaterThan' matcher is for mathematical comparisons", function() {
    var pi = 3.1415926,
      e = 2.78;

    expect(pi).toBeGreaterThan(e);///////////////匹配器/////////////////
    expect(e).not.toBeGreaterThan(pi);///////////////匹配器/////////////////
  });

  it("The 'toBeCloseTo' matcher is for precision math comparison", function() {
    var pi = 3.1415926,
      e = 2.78;

    expect(pi).not.toBeCloseTo(e, 2); ///////////////匹配器/////////////////
    expect(pi).toBeCloseTo(e, 0);///////////////匹配器/////////////////
  });

  it("The 'toThrow' matcher is for testing if a function throws an exception", function() {
    var foo = function() {
      return 1 + 2;
    };
    var bar = function() {
      return a + 1;
    };
    var baz = function() {
      throw 'what';
    };

    expect(foo).not.toThrow(); ///////////////匹配器/////////////////
    expect(bar).toThrow(); ///////////////匹配器/////////////////
    expect(baz).toThrow('what');
  });

  it("The 'toThrowError' matcher is for testing a specific thrown exception", function() {
    var foo = function() {
      throw new TypeError("foo bar baz");
    };

    expect(foo).toThrowError("foo bar baz"); ///////////////匹配器/////////////////
    expect(foo).toThrowError(/bar/); ///////////////匹配器/////////////////
    expect(foo).toThrowError(TypeError);
    expect(foo).toThrowError(TypeError, "foo bar baz");
  });
});
Christian-health commented 6 years ago

Manually failing a spec with fail

手动失败一个测试点通过fail函数。

The fail function causes a spec to fail. faile函数导致了一个测试点失败。 It can take a failure message or an Error object as a parameter. 它可以使用faiure 信息 或者是 一个Error 对象作为参数。

一个测试点使用fail函数
describe("A spec using the fail function", function() {
  var foo = function(x, callBack) {
    if (x) {  
      callBack();
    }
  };

  it("should not call the callBack", function() {
    foo(false, function() { //因为传入的是false值,所以function(){}这个函数就不会调用

    //fail()函数,会导致一个spec测试点失败,它的参数是failure message or an Error object
   //如果这个fail函数执行,那么这个it测试点就会失败
      fail("Callback has been called");

    });
  });
});
Christian-health commented 6 years ago

Grouping Related Specs with describe

通过使用describe来分组相关的specs

The describe function is for grouping related specs. The string parameter is for naming the collection of specs, and will be concatenated with specs to make a spec's full name. This aids in finding specs in a large suite. If you name them well, your specs read as full sentences in traditional BDD style. describe(测试集)功能用于分组相关specs(测试点)。字符串参数用于命名specs的集合, 可以通过测试集的名字和测试集进行关联,这有帮助于找到测试点的集合在一个大的测试集。如果你对他们的命名很好,你的测试点的集合可以类似于传统的BDD风格的句子一样阅读。

describe("A spec", function() {
  it("is just a function, so it can contain any code", function() {
    var foo = 0;
    foo += 1;

    expect(foo).toEqual(1);
  });

  it("can have more than one expectation", function() {
    var foo = 0;
    foo += 1;

    expect(foo).toEqual(1);
    expect(true).toEqual(true);
  });
});
Christian-health commented 6 years ago

Setup and Teardown 安装和拆卸

beforeEach, afterEach, beforeAll, afterAll

To help a test suite dry up any duplicated setup and teardown code, Jasmine provides the global beforeEach, afterEach, beforeAll, and afterAll functions. 为了帮助一个测试集甩干(dry up 干燥)重复的设置和拆卸代码 ,Jasmine提供了全局的 beforeEach, afterEach, beforeAll, afterAll 函数。

As the name implies, the beforeEach function is called once before each spec in the describe in which it is called, and the afterEach function is called once after each spec.

beforeEach在describe中的每个spec调用之前执行,afterEach函数在每个spec测试点调用之后执行。

Here is the same set of specs written a little differently. The variable under test is defined at the top-level scope -- the describe block -- and initialization code is moved into a beforeEach function. The afterEach function resets the variable before continuing. 这里有一个同样的测试集,只不过写法有点不同。变量被放置在describe中的全局部分,顶级部分,并且初始化代码被放置到beforeEach中,而变量的重置放在afterEach中。

describe("A spec using beforeEach and afterEach", function() {
  var foo = 0;

  beforeEach(function() {
    foo += 1;
  });

  afterEach(function() {
    foo = 0;
  });

  it("is just a function, so it can contain any code", function() {
    expect(foo).toEqual(1);
  });

  it("can have more than one expectation", function() {
    expect(foo).toEqual(1);
    expect(true).toEqual(true);
  });
});

The beforeAll function is called only once before all the specs in describe are run, and the afterAll function is called after all specs finish. These functions can be used to speed up test suites with expensive setup and teardown. beforeAll函数在所有的specs调用之前运行一次,afterAll函数在所有的specs运行完之后运行一次。 这些函数可用于加快测试套件的昂贵设置和拆卸。(就是加快设置和拆卸)

However, be careful using beforeAll and afterAll! Since they are not reset between specs, it is easy to accidentally leak state between your specs so that they erroneously pass or fail. 但是,请谨慎使用beforeAll和afterAll! 由于它们不在spects之间重新设置,因此很容易在您的specs之间意外泄露状态,从而错误地通过或失败。

describe("A spec using beforeAll and afterAll", function() {
  var foo;

  beforeAll(function() {
    foo = 1;
  });

  afterAll(function() {
    foo = 0;
  });

  it("sets the initial value of foo before specs run", function() {
    expect(foo).toEqual(1);
    foo += 1;
  });

  it("does not reset foo between specs", function() {
    expect(foo).toEqual(2);
  });
});
Christian-health commented 6 years ago

The this keyword this变量

Another way to share variables between a beforeEach, it, and afterEach is through the this keyword. Each spec's beforeEach/it/afterEach has the this as the same empty object that is set back to empty for the next spec's beforeEach/it/afterEach. 其他的方式在beforeEach,it,afterEach方法之间共享变量,是通过this变量这个关键字。 每一个测试点beforeEach/it/afterEach把this变量设置成为empty的object。 每一个spec周期都会把this设置成为空Object。

describe("A spec", function() {
  beforeEach(function() {
    this.foo = 0;
  });

//这里的this应该是空的,但是在这里beforeEach设置了this.foo=0所以这里的this不为空了。
因为有this.foo但是只有this.foo没有其他的任何东西
  it("can use the `this` to share state", function() {
    expect(this.foo).toEqual(0);
    this.bar = "test pollution?";
  });
//这里的this应该是空的,但是在这里beforeEach设置了this.foo=0所以这里的this不为空了。
因为有this.foo但是只有this.foo没有其他的任何东西,没有this.bar所以这里this.bar===undefined
  it("prevents test pollution by having an empty `this` created for the next spec", function() {
    expect(this.foo).toEqual(0);
    expect(this.bar).toBe(undefined);
  });
});
Christian-health commented 6 years ago

Nesting describe Blocks describe块嵌套

Calls to describe can be nested, with specs defined at any level. This allows a suite to be composed as a tree of functions. Before a spec is executed, Jasmine walks down the tree executing each beforeEach function in order. After the spec is executed, Jasmine walks through the afterEach functions similarly. describe的调用可以嵌套,在任何级别定义specs。

describe("A spec", function() {
  var foo;

  beforeEach(function() {
    foo = 0;
    foo += 1;
  });

  afterEach(function() {
    foo = 0;
  });

  it("is just a function, so it can contain any code", function() {
    expect(foo).toEqual(1);
  });

  it("can have more than one expectation", function() {
    expect(foo).toEqual(1);
    expect(true).toEqual(true);
  });

  describe("nested inside a second describe", function() {
    var bar;

    beforeEach(function() {
      bar = 1;
    });

    it("can reference both scopes as needed", function() {
      expect(foo).toEqual(bar);
    });
  });
});