JasmineJS - 快速指南


JasmineJS - 概述

Jasmine 是一个开源 JavaScript 框架,能够测试任何类型的 JavaScript 应用程序。Jasmine 遵循Behave驱动开发 (BDD) 程序,以确保每一行 JavaScript 语句都经过正确的单元测试。通过遵循 BDD 过程,Jasmine 提供了一个小语法来测试整个应用程序的最小单元,而不是作为一个整体进行测试。

为什么要用茉莉花?

以下是使用 Jasmine 相对于其他可用 JavaScript 测试框架的优势 -

  • Jasmine 不依赖于任何其他 JavaScript 框架。

  • Jasmine 不需要任何 DOM。

  • Jasmine 框架中使用的所有语法都是干净且明显的。

  • Jasmine 深受 Rspec、JS Spec 和 Jspec 的影响。

  • Jasmine 是一个开源框架,可以轻松获得不同版本,如独立版、ruby gem、Node.js 等。

如何使用茉莉花?

Jasmine 很容易在任何类型的开发方法中实现。您需要从官方网站https://jasmine.github.io/下载独立的库文件,并在您的应用程序中实现相同的库文件。

详细的环境设置将在下一章“环境设置”中介绍。成功下载并解压缩 zip 文件后,您将在该 zip 文件中找到以下子文件夹。

压缩文件

JasmineJS - 环境设置

在本章中,我们将逐步讨论如何设置基于 Jasmine 的 BDD 测试应用程序。

步骤 1 - 访问 jasmine 的官方网站https://jasmine.github.io/

官方网站

步骤 2 - 单击任何版本链接。最好使用最新版本“Edge”。您将被重定向到所选版本的主页。

主页

步骤 3 - 转到主页的下载部分,然后单击独立发布页面。

下载部分

步骤 4 - 一旦您被重定向到 github 发布页面,请从那里下载 Zip 文件。

发布页面

步骤 5 - 解压缩下载的 jasmine-standalone-2.4.1 文件夹。您将看到以下文件夹结构。

独立式

步骤 6 - 现在在您最喜欢的 IDE 中创建一个 Web 应用程序项目,并将下载的库文件添加到应用程序中。在这里,我们使用了netbeans IDE。以下是添加 Jasmine 框架后我们的应用程序的目录结构。

项目

我们的环境设置完成了。现在我们的应用程序已准备好接受 Jasmine 框架的测试。

JasmineJS - 编写文本和执行

在本章中,我们将创建一个hello world 应用程序来测试我们的“helloworld.js”文件。在开发 hello world 应用程序之前,请返回上一章并确保您的环境已准备好使用 Jasmine 进行测试。

第 1 步 - 在 IDE 中创建 Web 应用程序

在这里,我们使用 NetBeans 8.1 在 Jasmine 中开发我们的 hello world 应用程序。在 NetBeans 中,转到文件 → 新建项目 → Html5/JS 应用程序并创建一个项目。创建项目后,项目目录应如下图所示。我们将项目命名为Jasmine_Demo

演示

步骤 2 - 将 Jasmine lib 文件包含到应用程序中

创建演示项目后,您所需要做的就是将 Jasmine 库的解压缩文件夹包含在创建的应用程序的 Unit Tests 文件夹中。将所有库文件添加到我们的应用程序文件夹后,我们的项目的结构将如下图所示。

项目结构

specsrc文件夹下给出的文件是 Jasmine 团队提供的演示文件。删除这些文件,因为我们将创建自己的测试文件和测试用例。在删除这些 JavaScript 文件时,我们需要删除输出 html 文件SpecRunner.html中这些文件的引用。

以下是 SpecRunner.html 文件的屏幕截图,其中specsrc中不同 JavaScript 文件的引用将被删除。

SpecRunner Html 文件

第 3 步 - 创建 JavaScript 文件

在此步骤中,我们将在src文件夹下创建一个名为helloworld.js的 JavaScript 文件。这是我们将通过 Jasmine 测试的文件。创建 JavaScript 文件后,在文件中附加以下代码集。

/*         
* This is the JavaScript file that need to be tested through jasmine   
* Below is the helloworld function that will return 'Hello World' 
*            
*/    

var helloworld = function() {   
   return 'Hello World'; 
}; 

第 4 步 - 创建测试用例

在此步骤中,我们将创建另一个 JavaScript 文件,其中包含上述 JavaScript 文件的测试用例。继续在“Spec”文件夹下创建一个 JavaScript 文件,并将其命名为“HelloWorldsSpec.js”。将以下代码行添加到此js文件中。

/*            
* This is the file which will call our java script file that need to be tested. 
* Each describe block is equivalent to one test case    
*     
*/    

describe("Hello World", function() { 
   
   it("should Return Hello world",function() { 
      expect(helloworld()).toEqual('Hello World'); 
   }); 

});

步骤 5 - 添加对输出文件的引用

我们成功创建了自己的待测试文件以及相应的测试用例。我们将其保存在两个不同的文件夹下。在此步骤中,我们将修改“SpecRunner.html”以包含这两个新创建的文件的引用。

<!DOCTYPE html> 
    
<html>    
   <head>    
      <meta charset = "utf-8"> 
    
      <title>Jasmine Spec Runner v2.4.1</title>  
		
      <link rel = "shortcut icon" type = "image/png" href = 
      "lib/jasmine2.4.1/jasmine_favicon.png">  
      <link rel = "stylesheet" href = "lib/jasmine-2.4.1/jasmine.css"> 
		
      <script src = "lib/jasmine-2.4.1/jasmine.js"></script>
      <script src = "lib/jasmine-2.4.1/jasmine-html.js"></script>
      <script src = "lib/jasmine-2.4.1/boot.js"></script> 

      <!--Lines to be deleted  
      <script src = "src/Player.js"></script> 
      <script src = "src/Song.js"></script> 
      <script src = "spec/SpecHelper.js"></script>    
      <script src = "spec/PlayerSpec.js"></script> --> 

      <!--adding the reference of our newly created file ---> 

      <script src = "src/helloworld.js"></script> 
      <script src = "spec/HelloWorldsSpec.js"></script> 
   </head>   

   <body>   
   </body>   

</html>

步骤 6 - 通过运行 SpecRunner.html 来执行

这是我们应用程序开发的最后一步。在您喜欢的任何浏览器中运行 SpecRunner.html。结果将出现以下屏幕截图。绿屏表示成功,红色表示测试用例失败。

结果

步骤 7 - 了解失败案例

到目前为止,我们已经看到了hello world 应用程序的成功测试用例。现在让我们看看如果出现问题并且测试失败怎么办。为了实现失败案例,我们需要编写失败测试案例。为此,我们将使用以下代码修改helloworld.js文件。

var helloworld = function () { 
   return ''; 
};  

// we are not returning any string whereas in the spec file 
//we are expecting a // string as “Hello World” 

上面的代码肯定会失败,因为我们的规范文件没有获得预期的字符串作为 helloworld ()的输出。以下specRunner.html文件的屏幕截图显示其红色指示器存在错误。

错误

JasmineJS - BDD 架构

Jasmine 遵循Behave驱动开发 (BDD) 框架。在学习Jasmine工作原理之前,我们先来了解一下什么是BDD框架。

以下流程图描述了 BDD 框架的不同阶段。

业务驱动开发框架

步骤 1 - 开始

在此阶段,我们将为 Jasmine 应用程序准备好环境。

第 2 步 - 编写失败的测试

在此步骤中,我们将编写第一个测试用例。很明显,这个测试将会失败,因为没有这样的文件或函数要测试。

步骤 3 - 编写代码使其通过

在此阶段,我们将准备需要测试的 JavaScript 文件或函数。这个阶段至关重要,因为我们需要确保前期准备的所有测试用例都能成功。

步骤 4 - 重构

重构是 BDD 模型的一个非常重要的阶段,我们需要为特定的应用程序或功能准备尽可能多的测试用例。

步骤 5 - 停止

如果一切顺利,那么您的应用程序必须准备就绪并启动。因此,我们可以将此步骤视为 BDD 应用程序的结束。

例子

现在我们已经掌握了一些关于BDD框架工作原理的知识。让我们看看Jasmine在JavaScript测试线上是如何遵循这个BDD框架的。

正如屏幕截图所示,我们需要使用 Jasmine 框架测试 Abc.js。SpecRunner.html是输出文件,它将采用Spec.js(测试用例文件)、Abc.js(要测试的文件)、LIB 作为输入,运行规范文件中存在的所有测试用例,并将结果渲染到浏览器。

工作准则

Lib - 这些是内置的 JavaScript 文件,有助于测试我们项目中使用的不同函数和其他 JavaScript 文件。

Spec.js(测试用例文件) - 这是包含测试任何 JavaScript 函数或文件所需的所有测试用例的 JavaScript 文件。在 BDD 方法中,我们将首先编写测试,因此这是需要首先更新的文件。这肯定会失败,因为我们的项目中不存在可以测试的此类文件或函数。该文件可以无限次重构,直到所有功能都经过测试。

Abc.js(要测试的文件) - 这是包含将使用 Spec.js 和 Lib 文件进行单元测试的功能的文件。

SpecRunner.html - SpecRunner.html 是一个普通的 html 文件,它将借助嵌入的 JavaScript 代码呈现单元测试的输出。

JasmineJS - 测试构建块

在本章中,我们将讨论 Jasmine 测试的构建块。

套房楼

Jasmine 是一个 JavaScript 测试框架。Suite是 Jasmine 框架的基本构建块。为特定文件或函数编写的类似类型测试用例的集合称为一套。它包含另外两个块,一个是“Describe()”,另一个是“It()”

一个 Suite 块只能有两个参数,一个是“该套件的名称”,另一个是实际调用要测试的单元功能的“函数声明” 。

在下面的示例中,我们将创建一个套件,对add.js文件中的 add 函数进行单元测试。在这个例子中,我们有一个名为“calculator.js”的JS文件,它将通过Jasmine进行测试,对应的Jasmine规范文件是“CalCulatorSpec.js”

计算器.js

window.Calculator = { 
   
   currentVal:0,  
   varAfterEachExmaple:0, 
   
   add:function (num1) { 
      this.currentVal += num1; 
      return this.currentVal;    
   },     
   
   addAny:function () {    
      var sum = this.currentVal; 
		
      for(var i = 0; i < arguments.length; i++) { 
         sum += arguments[i]; 
      } 
      
      this.currentVal = sum; 
      Return  this.currentVal; 
   }, 
};

CalCulatorSpec.js

describe("calculator",function() { 
   
   //test case: 1  
   it("Should retain the current value of all time", function () {
      expect(Calculator.currentVal).toBeDefined();
      expect(Calculator.currentVal).toEqual(0);  
   }); 
   
   //test case: 2  
   it("should add numbers",function() {
      expect(Calculator.add(5)).toEqual(5); 
      expect(Calculator.add(5)).toEqual(10);  
   });         
    
   //test case :3   
   it("Should add any number of numbers",function () {
      expect(Calculator.addAny(1,2,3)).toEqual(6); 
   }); 
}); 

在上面的函数中,我们声明了两个函数。函数add将添加作为该函数参数给出的两个数字,另一个函数addAny应该添加作为参数给出的任何数字。

创建该文件后,我们需要将该文件添加到head 部分的“SpecRunner.html”中。成功编译后,将生成以下输出。

计算器规格

嵌套套房街区

套房块可以在另一个套房块内包含许多套房块。以下示例将向您展示如何在另一个套件块中创建不同的套件块。我们将创建两个 JavaScript 文件,一个名为“NestedSpec.js”,另一个名为“nested.js”

嵌套规范.js

describe("nested",function() { 
   
   // Starting of first suite block  
   // First block    
	
   describe("Retaining values ",function () {
   
      //test case:1    
      it ("Should retain the current value of all time", function () { 
         expect(nested.currentVal).toBeDefined();   
         expect(nested.currentVal).toEqual(0);   
      });    
   }); //end of the suite block   

   //second suite block 
   describe("Adding single number ",function () {     
   
      //test case:2 
      it("should add numbers",function() { 
         expect(nested.add(5)).toEqual(5); 
         expect(nested.add(5)).toEqual(10); 
      });         
   }); //end of the suite block  

   //third suite block 
   describe("Adding Different Numbers",function () {  
   
      //test case:3 
      it("Should add any number of numbers",function() {  
         expect(nested.addAny(1,2,3)).toEqual(6);  
      });    
   }); //end of the suite block 
});

嵌套.js

window.nested = { 
   
   currentVal: 0,
	
   add:function (num1) {  
      this.currentVal += num1;     
      return this.currentVal;    
   },
   
   addAny:function () { 
      Var sum = this.currentVal; 
		
      for(var i = 0;i < arguments.length; i++) { 
         sum += arguments[i]; 
      } 
		
      this.currentVal = sum; 
      return this.currentVal;    
   }  
};

在 head 部分添加该文件后,运行specRunner.html文件,上面的代码将生成以下输出。

SpecRunner 结果

描述块

正如前面所讨论的,描述块是套件块的一部分。与 Suite 块一样,它包含两个参数,一个是“描述块的名称”,另一个是“函数声明”。在接下来的示例中,我们将通过许多描述块来了解 Jasmine 套件块的工作流程。以下是完整描述块的示例。

describe("Adding single number ",function () { 
   
   it("should add numbers",function() { 
      expect(nested.add(5)).toEqual(5); 
      expect(nested.add(5)).toEqual(10); 
   });     
}

IT区块

与描述块一样,我们也介绍了 IT 块。它位于描述块内。这是实际包含每个单元测试用例的块。在下面的代码中,一个描述块内有一些IT块。

describe("Adding single number ",function () { 
   
   // test case : 1   
   it("should add numbers",function() {  
      expect(nested.add(5)).toEqual(5); 
      expect(nested.add(5)).toEqual(10); 
   });         
    
   //test case : 2 
   it("should add numbers",function() { 
      expect(nested.addAny(1,2,3)).toEqual(6); 
   });     
}

预期区块

Jasmine Expect允许您从所需的函数或 JavaScript 文件中编写您的期望。它属于IT块。一个 IT 块可以有多个 Expect 块。

以下是 Expect 块的示例。此 Expect 块提供了多种方法来对 JavaScript 函数或 JavaScript 文件进行单元测试。每个 Expect 块也称为匹配器。有两种不同类型的匹配器,一种是内置匹配器,另一种是用户定义的匹配器

describe("Adding single number ",function () {   
   
   // test case : 1 
   it("should add numbers",function() {
      expect(nested.add(5)).toEqual(5); 
      expect(nested.add(5)).toEqual(10);
   });          
   
   //test case : 2 
   it("should add numbers",function() {
      expect(nested.addAny(1,2,3)).toEqual(6); 
   });     
}

在接下来的章节中,我们将讨论 Expect 块的不同内置方法的各种用法。

JasmineJS - 匹配器

Jasmine 是一个测试框架,因此它始终旨在将 JavaScript 文件或函数的结果与预期结果进行比较。Matcher 在 Jasmine 框架中的工作原理类似。

匹配器是在实际输出和预期输出之间进行布尔比较的 JavaScript 函数。有两种类型的匹配器:内置匹配器自定义匹配器

内置匹配器

Jasmine框架内置的匹配器称为内置匹配器。用户可以轻松地隐式使用它。

以下示例展示了 Inbuilt Matcher 在 Jasmine 框架中的工作原理。我们在前一章中已经使用了一些匹配器。

describe("Adding single number ", function () {  

   //example of toEqual() matcher    
   it("should add numbers",function() { 
      expect(nested.add(5)).toEqual(5); 
      expect(nested.add(5)).toEqual(10); 
   });   
   
   it("should add numbers",function() { 
      expect(nested.addAny(1,2,3)).toEqual(6); 
   });
}

在示例中,toEqual() 是内置匹配器,它将add()addAny()方法的结果与传递给toEqual()匹配器的参数进行比较。

自定义匹配器

Jasmine 内置系统库中不存在的匹配器称为自定义匹配器。自定义匹配器需要显式定义()。在下面的示例中,我们将了解自定义匹配器的工作原理。

describe('This custom matcher example', function() {
   
   beforeEach(function() { 
      // We should add custom matched in beforeEach() function. 
      jasmine.addMatchers ({ 
         validateAge: function() { 
            Return {    
               compare: function(actual,expected) {
                  var result = {}; 
                  result.pass = (actual > = 13 && actual < = 19);
                  result.message = 'sorry u are not a teen ';
                  return result; 
               }   
            };   
         }    
      });    
   }); 
    
   it('Lets see whether u are teen or not', function() { 
      var myAge = 14; 
      expect(myAge).validateAge();         
   });   
    
   it('Lets see whether u are teen or not ', function() { 
      var yourAge = 18;
      expect(yourAge).validateAge();  
   });
});

在上面的示例中,validateAge()作为匹配器,实际上是在某个范围内验证您的年龄。在此示例中,validateAge() 用作自定义匹配器。将此 JS 文件添加到SpecRunner.html中并运行相同的文件。它将生成以下输出。

验证年龄

JasmineJS - 跳过块

Jasmine 还允许开发人员跳过一个或多个测试用例。这些技术可以应用于规范级别套件级别。根据应用的级别,该块可以分别称为Skipping SpecSkipping Suite

在下面的示例中,我们将学习如何使用“x”字符跳过特定的规范套件

跳过规格

我们将在前面的示例语句之前使用“x”来修改它。

describe('This custom matcher example ', function() { 
   
   beforeEach(function() { 
      // We should add custom matched in beforeEach() function. 
      
      jasmine.addMatchers({ 
         validateAge: function() { 
            return { 
               compare: function(actual,expected) { 
                 var result = {}; 
                 result.pass = (actual > = 13 && actual < = 19); 
                 result.message = 'sorry u are not a teen ';  
                 return result; 
               }  
            };   
         }    
      });    
   });  
    
   it('Lets see whether u are teen or not', function() { 
      var myAge = 14; 
      expect(myAge).validateAge();  
   });
   
   xit('Lets see whether u are teen or not ', function() {  
      //Skipping this Spec 
      var yourAge = 18; 
   });
});

如果我们运行此 JavaScript 代码,我们将在浏览器中收到以下输出结果。Jasmine 本身会使用“xit”通知用户特定的it块已暂时禁用

XIT 区块结果

跳绳套房

同样的,我们可以禁用describe块来实现Skipping Suite的技术。在下面的例子中,我们将了解跳过套件块的过程。

xdescribe('This custom matcher example ', function() {  
   
   //Skipping the entire describe  block  
   beforeEach(function() {  
   
      // We should add custom matched in beforeEach() function.  
      jasmine.addMatchers({  
         validateAge: function() {  
            return {   
               compare: function(actual,expected) {  
                 var result = {}; 
                 result.pass = (actual >=13 && actual<=19); 
                 result.message ='sorry u are not a teen '; 
                 return result;  
               }   
            };   
         }   
      });   
   });

   it('Lets see whether u are teen or not', function() {  
      var myAge = 14; 
      expect(myAge).validateAge(); 
   });  

   it('Lets see whether u are teen or not ', function() {  
      var yourAge = 18; 
      expect(yourAge).validateAge(); 
   });
});

上面的代码将生成以下屏幕截图作为输出。

跳绳套房

正如我们在消息栏中看到的,它显示了两个处于待处理状态的规格块,这意味着这两个规格块已使用“x”字符禁用。在下一章中,我们将讨论不同类型的 Jasmine 测试场景。

JasmineJS - 平等检查

Jasmine 提供了很多方法来帮助我们检查任何 JavaScript 函数和文件的相等性。以下是检查相等条件的一些示例。

等于()

ToEqual()是 Jasmine 内置库中最简单的匹配器。它只是匹配作为该方法的参数给出的操作结果是否与它的结果匹配。

以下示例将帮助您了解该匹配器的工作原理。我们有两个要测试的文件,名为“expectexam.js”,另一个需要测试的文件是“expectSpec.js”

Expectexam.js

window.expectexam = {    
   currentVal: 0,   
};

ExpectSpec.js

describe("Different Methods of Expect Block",function () { 
   
   it("The Example of toEqual() method",function () {   
      //this will check whether the value of the variable  
      // currentVal is equal to 0 or not.  
      expect(expectexam.currentVal).toEqual(0);  
   });
});

成功执行后,这些代码将产生以下输出。请记住,您需要按照前面示例中的指示将这些文件添加到specRunner.html文件的标头部分。

toEquals方法

not.toEqual()

not.toEqual() 的工作原理与 toEqual() 完全相反。当我们需要检查值是否与任何函数的输出不匹配时,使用not.toEqual() 。

我们将修改上面的示例来展示其工作原理。

ExpectSpec.js

describe("Different Methods of Expect Block",function () { 

   it("The Example of toEqual() method",function () {
      expect(expectexam.currentVal).toEqual(0);  
   });   
   
   it("The Example of not.toEqual() method",function () {  
      //negation  testing expect(expectexam.currentVal).not.toEqual(5); 
   }); 
});

Expectexam.js

window.expectexam = { 
   currentVal: 0,  
}; 

在第二个 Expect 块中,我们检查 currentVal 的值是否等于5,因为 currentVal 的值为零,因此我们的测试通过并为我们提供绿色输出。

不等于方法

成为()

toBe()匹配器的工作方式与 toEqual() 类似,但它们在技术上彼此不同。toBe() 匹配器与对象的类型匹配,而toEqual()与结果的等价性匹配。

以下示例将帮助您了解 toBe() 匹配器的工作原理。该匹配器与 JavaScript 的“===”运算符完全相同,而 toEqual() 与 JavaScript 的“==”运算符类似。

ExpectSpec.js

describe("Different Methods of Expect Block",function () {  

   it("The Example of toBe() method",function () { 
      expect(expectexam.name).toBe(expectexam.name1);     
   });
});

Expectexam.js

window.expectexam = {
   currentVal: 0, 
   name:"tutorialspoint", 
   name1:tutorialspoint  
};

我们将稍微修改我们的expectexam JavaScript 文件。我们添加了两个新变量namename1。请找出这两个添加的变量的区别,一个是字符串类型,另一个不是字符串类型。

下面的屏幕截图是我们的测试结果,其中红叉表示这两个值不相等,而预期是相等的。因此我们的测试失败了。

预期考试错误

让我们将变量namename1都转换为 String 类型变量,并再次运行相同的SpecRunner.html。现在检查输出。它将证明toBe()不仅与变量的等价性匹配,而且还与变量的数据类型或对象类型匹配。

not.toBe()

如前所述, not 只不过是 toBe() 方法的否定。当预期结果与函数或 JavaScript 文件的实际输出匹配时,它会失败。

以下是一个简单的示例,将帮助您了解 not.toBe() 匹配器的工作原理。

describe("Different Methods of Expect Block",function () { 
   it("The Example of not.toBe() method",function () { 
      expect(true).not.toBe(false);    
   });
});

这里 Jasmine 将尝试将 true 与 false 匹配。由于 true 不能与 false 相同,因此该测试用例将有效并通过。

待定法

JasmineJS - 布尔检查

除了相等性检查之外,Jasmine 还提供了一些检查布尔条件的方法。以下是帮助我们检查布尔条件的方法。

ToBeTruthy()

Jasmine 中使用此布尔匹配器来检查结果是否等于 true 或 false。

下面的例子将帮助我们理解toBeTruthy()函数的工作原理。

ExpectSpec.js

describe("Different Methods of Expect Block",function () {
   it("The Example of toBeTruthy() method",function () {   
      expect(expectexam.exampleoftrueFalse(5)).toBeTruthy();    
   });
}); 

Expectexam.js

window.expectexam = {  
   exampleoftrueFalse: function (num) {  
      if(num < 10)    
         return true;  
      else   
         return false;  
   },  
};

当我们传递小于 10 的数字 5 时,该测试用例将通过并给出以下输出。

真实方法

如果我们传递一个大于 10 的数字,那么这个绿色测试将变为红色。在第二个屏幕截图中,您可以看到在传递一些大于 10 的值时,预期的测试用例失败并生成红色输出,指出“预期 false 为 true”。

真实错误

toBeFalsy()

toBeFalsy() 的工作方式也与 toBeTruthy() 方法相同。它将输出匹配为 false,而 toBeTruthy 将输出匹配为 true。下面的例子将帮助您理解toBeFalsy()的基本工作原理。

ExpectSpec.js

describe("Different Methods of Expect Block",function() { 
   it("The Example of toBeTruthy() method",function () {
      expect(expectexam.exampleoftrueFalse(15)).toBeFalsy();   
   });
});

Expectexam.js

window.expectexam = {  
   exampleoftrueFalse: function (num) {  
      if(num < 10)    
         Return true;  
      else   
         return false; 
   },
}; 

上面的代码将通过 Jasmine 测试用例,因为我们传递的值超过 10 并且预计输出为 false。因此,浏览器将向我们显示一个绿色标志,这意味着它已经通过。

真实方法

JasmineJS - 顺序检查

Jasmine 还提供了不同的方法来提供 JS 输出的顺序性。以下示例展示了如何使用 Jasmine 实现顺序检查。

包含装有()

toContain()匹配器为我们提供了检查任何元素是否是同一数组或其他顺序对象的一部分的工具。下面的例子将帮助我们理解 Jasmine toContain() 方法的工作方法。让我们在之前创建的customerMatcherSpec.js文件中添加以下代码。

describe("Different Methods of Expect Block",function () {  
   it("The  Example of toContain() method",function () { 
      expect([1,2, 3, 4]).toContain(3);
   });
}); 

在上面的示例中,我们检查该数组中是否存在 3。当数组中存在 3 时,我们得到绿色输出。

包含方法

在上面的示例中,我们将 3 的值更改为 15,然后再次运行规范。我们将看到以下红色屏幕,因为 15 不属于我们作为该函数的参数传递的数组。

包含错误

ToBeCloseTo()

toBeCloseTo()匹配器匹配实际值是否接近期望值。在下面的示例中,我们将修改customerMatcherSpec.js文件并查看其实际工作原理。

describe("Different Methods of Expect Block", function () {  
   it("Example of toBeCloseTo()", function () { 
      expect(12.34).toBeCloseTo(12.3, 1);    
   });
});

在上面的描述块中,我们正在检查实际结果“12.3”是否更接近预期输出“12.34”。由于这满足了我们的要求,我们将得到以下绿色屏幕截图作为我们的输出。该方法的第二个参数是要比较的小数位数。

toBeCloseTo 方法

在上面的代码中,我们将期望值修改为 15 并运行SpecRunner.html

describe("Different Methods of Expect Block",function () { 
   it("Example of  toBeCloseTo()", function () { 
      expect(12.34).toBeCloseTo(15, 1);
   });
}); 

在这种情况下,15 与 15 相差甚远,因此它将生成错误并显示红色屏幕截图作为错误。

接近错误

匹配()

ToMatch()匹配器适用于 String 类型变量。确定预期输出中是否存在特定字符串很有帮助。以下是我们的customerMatcherSpec.js的样子。

describe("Different Methods of Expect Block",function () { 
   it("Example of toMatch()", function () { 
      expect("Jasmine tutorial in tutorials.com").toMatch(/com/);   
   });
});

这段代码将测试“com”是否存在于给定的预期字符串中。由于字符串中存在com ,因此会生成绿色截图并通过测试条件。

匹配方法

现在让我们将输出更改为其他字符串,该字符串不存在于预期值中。那么我们的customerMatcherSpec.js将如下所示。

describe("Different Methods  of Expect Block",function () { 
   it("Example of toMatch()", function () { 
      expect("Jasmine tutorial in tutorials.com").toMatch(/XYZ/);
   });
}); 

上面的代码将在预期值中找到“XYZ”字符串。由于它不存在于预期的字符串中,因此会抛出错误,并且输出屏幕将相应地变为红色。

匹配错误

JasmineJS - 空检查

Jasmine 提供了多种不同的方法来检查实际输出是否为 Null、已定义或未定义。在本章中,我们将学习如何实现不同的 Jasmine 方法来检查上述场景。

被定义为()

该匹配器用于检查代码中的任何变量是否是预定义的。让我们根据此示例修改customerMatcherSpec.js文件。

currentVal = 0;  

describe("Different Methods  of Expect Block",function () { 
   it("Example of  toBeDefined", function () {
      expect(currentVal).toBeDefined();
   });
});

在上面的代码中,toBeDefined()将检查变量currentVal是否在系统中定义。由于 currentVal 在开始时被定义为 0,因此该测试将通过并生成绿色屏幕截图作为输出。

待定义方法

再次在上面的示例中,让我们删除实际上定义“currentVal”的第一行并再次运行。然后我们将看到一个红色屏幕,这意味着测试实际上失败了,因为我们期望定义一个未定义的值。以下屏幕截图将是输出文件。

待定义错误

ToBe未定义()

这个匹配器有助于检查任何变量之前是否未定义,基本上它的工作原理与之前的匹配器 toBeDefined 相反。在下面的示例中,我们将学习如何使用这个匹配器。让我们使用以下条目修改我们的 Spec 文件,即customerMatcher.js文件。

describe("Different Methods of Expect Block",function () { 
   it("Example of toBeUndefine()", function () { 
      var undefineValue; 
      expect(undefineValue).toBeUndefined(); 
   });
}); 

在上一节中,我们将验证变量“undefineValue”是否实际上未定义。将此文件添加到 SpecRunner 后,我们将收到一个绿色屏幕截图作为输出,这告诉我们该值实际上之前并未定义。

toBeUndefine 方法

再次让我们用一些预定义值定义变量,看看它是否会抛出错误。新的customerMatcher.js如下所示。

describe("Different Methods of Expect Block",function () {
   it("Example oftoBeUndefine()", function () { 
      var undefineValue = 0;
      expect(undefineValue).toBeUndefined();
   });
});

上面的代码会抛出错误并生成红色屏幕截图,因为我们已经将“undefineValue”值定义为“0”并期望它未被定义。运行SpecRunner.html文件时将生成以下屏幕截图。

toBeUndefine 错误

toBeNull()

正如名称所示,该匹配器有助于检查空值。让我们使用以下代码再次修改customerMatcherSpec.js文件。

describe("Different Methods of Expect Block",function () { 
   var value = null; 
	
   it("Example of toBeNull()", function () { 
      expect(value).toBeNull();
   });
}); 

在上面的代码中,我们提到了一个变量“value”,并且我们明确将该值指定为 null。在expect块中,toBeNull()匹配器将检查这个值并给出相应的结果。以下是上述代码在 SpecRunner.html 文件的帮助下运行时的输出。

为空方法

现在让我们通过提供除 null 之外的一些定义值来进行测试。请相应修改customerMatcher.js文件。

describe("Different Methods of Expect Block",function () {
   var value = "TutorialsPoint"; 
	
   it("Example of  toBeNull()", function () { 
      expect(value).toBeNull();
   });
}); 

在上面的例子中,我们用“TutorialsPoint”修改了变量值,它不是空值。因此,此测试将失败并生成红色屏幕截图作为输出。

为空错误

JasmineJS - 不平等检查

到目前为止,我们已经讨论了 Jasmine 中的不同方法,这些方法可以帮助我们根据需求测试不同的场景。在本章中,我们将学习不同的匹配器,它们将帮助我们检查 JS 文件中的不等式条件。以下是用于此目的的匹配器。

ToBeGreaterThan()

顾名思义,这个匹配器有助于检查大于条件。让我们使用以下代码修改customerMatcher.js 。

describe("Different Methods of Expect Block",function () { 
   var exp = 8;  
	
   it("Example of  toBeGreaterThan()", function () {
      expect(exp).toBeGreaterThan(5);
   });
}); 

在上面的代码中,我们期望变量“exp”的值将大于5。现在由于变量“exp”的值是“8”,大于“5”,所以这段代码代码将生成绿色屏幕截图。

大于方法

现在,让我们再次将变量的值修改为“4”,并使该测试失败。为此,我们需要使用以下代码修改js文件。

describe("Different Methods of Expect Block",function () {  
   var exp = 4;  
	
   it ("Example of toBeGreaterThan()", function () {
      expect(exp).toBeGreaterThan(5); 
   });
});

此代码将失败,因为值 4 不能大于 5。因此它将产生以下输出。

大于错误

ToBe小于()

该匹配器有助于检查测试场景的小于条件。它的Behave与 toBeGreaterThan() 匹配器的Behave完全相反。现在让我们看看这个匹配器是如何工作的。让我们相应地修改customerMatcher.js文件。

describe("Different Methodsof Expect Block",function () { 
   var exp = 4;  
	
   it("Example of toBeLessThan()", function() { 
      expect(exp).toBeLessThan(5);    
   });
}); 

与前面的示例一样,我们有一个值为“4”的变量。在这段代码中,我们检查该变量的值是否小于 5。这段代码将生成以下输出。

小于法

现在为了让这个失败,我们需要为变量 exp 分配一些更大的数字。让我们这样做并测试该应用程序。我们将 25 作为exp的值,这肯定会抛出错误并产生以下红色屏幕截图。

小于误差

JasmineJS - 不是数字检查

Jasmine 提供了一个特殊的匹配器来检查这种特殊类型的测试场景,即toBeNaN()

让我们使用以下代码修改customerMatcher.js 。

describe("Different Methods of Expect Block",function () { 
   it("Example of toBeNaN()", function () { 
      expect(0 / 0).toBeNaN(); 
   });
});

这里我们要测试的是无法确定的“0/0”的值是多少。因此,这段代码将生成以下绿色屏幕截图。

托贝南

现在让我们再次使用以下逻辑修改代码,其中我们将一个变量exp分配给 25,并期望结果不是它除以 5 的数字 1。

describe("Different Methods of Expect Block",function () { 
   var exp = 25; 
	
   it("Example of toBeNaN()", function () { 
      expect(exp/5).toBeNaN(); 
   });
});

这段代码将产生以下输出。

托贝南输出

JasmineJS - 异常检查

除了不同的计算匹配器之外,Jasmine 还提供了一些有用的匹配器来检查程序的异常。让我们使用以下代码集修改 JavaScript。

var throwMeAnError = function() {   
   throw new Error(); 
};  

describe("Different Methods of Expect Block", function() {  
   var exp = 25; 

   it ("Hey this will throw an Error ", function() { 
      expect(throwMeAnError).toThrow(); 
   }); 
});

在上面的示例中,我们创建了一个方法,该方法故意从该方法引发异常,并且在 Expect 块中我们期望捕获错误。如果一切顺利,那么这段代码将产生以下输出。

异常块

现在,为了让这个测试用例失败,我们需要省略函数throwMeAnError中的 throw 语句。以下代码将生成红色屏幕截图作为输出,因为该代码不满足我们的要求。

var throwMeAnError = function() {   
   //throw new Error(); 
};   

describe("Different Methods of Expect Block",function() {  
   var exp = 25; 
   
   it("Hey this will throw an Error ", function() {  
      expect(throwMeAnError).toThrow();    
   }); 
});

可以看出,我们已经对方法抛出异常的那一行进行了注释。以下是成功执行 SpecRunner.html 时上述代码的输出。

异常错误

茉莉花.Any()

Any是当我们不确定输出时使用的特殊匹配器。在下面的示例中,我们将了解其工作原理。让我们使用以下代码修改customerMatcher.js 。

var addAny = function() {
   var sum = this.currentVal; 
	
   for (var i = 0; i < arguments.length; i++) { 
      sum += arguments[i]; 
   } 
	
   this.currentVal = sum;  
   return this.currentVal; 
} 

describe("Different Methods of Expect Block",function () { 
   
   it("Example of any()", function() { 
      expect(addAny(9,9)).toEqual(jasmine.any(Number)); 
   });
});

在这里,我们声明了一个函数,它将为我们提供作为参数提供的数字的总和。在expect块中,我们期望结果可以是任何东西,但它应该是一个数字。

由于总和后的 9 和 9 都为 18,因此该测试将通过,并将生成以下绿色屏幕截图作为输出。

任何方法

现在让我们根据以下代码更改代码,其中我们期望字符串类型变量作为函数AddAny()的输出。

var addAny = function() { 
   var sum = this.currentVal; 
	
   for(var i = 0; i < arguments.length; i++) { 
      sum += arguments[i]; 
   } 
	
   this.currentVal = sum; 
   return this.currentVal; 
}  

describe("Different Methodsof Expect Block",function () { 
   it("Example of any()", function () { 
      expect(addAny(9,9)).toEqual(jasmine.any(String));    
   });
});

以下是上述代码的输出。

任何错误

JasmineJS - beforeEach()

Jasmine 的另一个显着特征是每个函数之前和之后。使用这两个功能,我们可以在每个规范执行之前和之后执行一些代码。此功能对于运行应用程序中的通用代码非常有用。让我们创建一个如下所示的规范文件。

var currentVal = 0; 

beforeEach(function() { 
   currentVal = 5; 
});  

describe("Different Methods of Expect Block",function() { 
   it("after each function ", function() {
      expect(currentVal).toEqual(5);     
   });
});

在这里,虽然我们一开始就将一个变量声明为“0”,但我们期望该值在期望块中应等于 5。上面的代码将生成以下输出。

每个之前

在上面的代码中,在执行expect块之前, 5将被分配给变量currentVal 。因此,它会生成没有错误的绿色屏幕截图。

JasmineJS - afterEach()

与 beforeEach() 一样,afterEach() 的工作方式完全相同。它在执行spec块之后执行。让我们使用以下代码修改前面的示例。

var currentVal = 0; 

afterEach(function() { 
   currentVal = 5;  
});  

describe("Different Methods of Expect Block",function() { 
   it("first call ", function() { 
      expect(currentVal).toEqual(0);     
   });     
   
   it("second call ",  function() { 
      expect(currentVal).toEqual(5);     
   });
});

在上面的例子中,在运行第一个spec块时,currentVal的值为0。因此,它将通过测试用例,但在运行第一个it块之后,Jasmine编译运行了afterEach()块,这使得currentVal 为 5。因此它也满足第二种情况并产生绿色屏幕截图作为输出。

每个之后

JasmineJS - 间谍

Jasmine间谍是另一个功能,其功能与其名称完全相同。它将允许您监视您的应用程序函数调用。Jasmine 中有两种类型的间谍技术。第一种方法可以使用spyOn()来实现,第二种方法可以使用createSpy()来实现。在本章中,我们将更多地了解这两种方法。

暗中监视()

间谍On()内置于Jasmine库中,它允许您监视一段明确的代码。让我们创建一个新的规范文件“spyJasmineSpec.js”和另一个名为“spyJasmine.js”的js文件。以下是这两个文件的条目。

SpyJasmine.js

var Person = function() {}; 

Person.prototype.sayHelloWorld = function(dict) { 
   return dict.hello() + " " + dict.world(); 
}; 

var Dictionary = function() {}; 

Dictionary.prototype.hello = function() { 
   return "hello"; 
}; 

Dictionary.prototype.world = function() { 
   return "world"; 
}; 

SpyJasmineSpec.js

describe("Example Of jasmine Spy using spyOn()", function() { 
  
   it('uses the dictionary to say "hello world"', function() { 
      var dictionary = new Dictionary; 
      var person = new Person; 
		
      spyOn(dictionary, "hello");  // replace hello function with a spy 
      spyOn(dictionary, "world");  // replace world function with another spy 
		
      person.sayHelloWorld(dictionary);
      expect(dictionary.hello).toHaveBeenCalled();  
      // not possible without first spy 
  
      expect(dictionary.world).toHaveBeenCalled();  
      // not possible withoutsecond spy 
   }); 
});

在上面的代码中,我们希望 person 对象说“Hello world”,但我们也希望 person 对象应该咨询字典对象来为我们提供输出文字“Hello world”。

看一下 Spec 文件,您可以看到我们使用了spyOn() 函数,它实际上模仿了helloworld函数的功能。因此,我们实际上并不是在调用函数,而是模仿函数调用。这就是间谍的专长。上面的代码将产生以下输出。

间谍方法

创建间谍()

获取间谍功能的另一种方法是使用 createSpy()。让我们使用以下代码修改两个js文件。

SpyJasmine.js

var Person = function() {};    

Person.prototype.sayHelloWorld = function(dict) { 
   return dict.hello() + " " + dict.world(); 
}; 

var Dictionary = function() {}; 

Dictionary.prototype.hello = function() { 
   return "hello"; 
}; 

Dictionary.prototype.world = function() { 
   return "world"; 
}; 

SpyJasmineSpec.js

describe("Example Of jasmine Spy using Create Spy", function() { 
   
   it("can have a spy function", function() { 
      var person = new Person(); 
      person.getName11 = jasmine.createSpy("Name spy"); 
      person.getName11(); 
      expect(person.getName11).toHaveBeenCalled(); 
   }); 
}); 

看一下spec文件,我们正在调用Person对象的getName11()。尽管该函数不存在于间谍 Jasmine.js 的person 对象中,但我们没有收到任何错误,因此输出为绿色且为正值。在此示例中,createSpy() 方法实际上模仿了 getName11() 的功能。

上面的代码将生成以下输出。

创建间谍