微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

初步了解Angular 2端到端的测试

【Angular2】Tour of Heroes 之 e2e测试:http://blog.csdn.net/Francis123580/article/details/72861818


背景

因为项目需要用到Angular2的端对端测试
所以先用官方网站的Tour of Heroes项目练手

流程

1.在e2e文件夹中的app.e2e-spec.ts文件中输入下面的代码
2.cd到本项目根文件
3.在控制台中输入 ng e2e

效果

代码

import { AngularTourOfheroesPage } from './app.po';
import { ComponentFixture,Testbed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { browser,element,by } from 'protractor';



describe('Tour of Heroes',function () {

  //测试:当访问网站的时候应该跳转到/dashboard这个路由
  it('should redirect index.html to http://localhost:4200/dashboard',function () {
    browser.get('').then(function (url) {
      expect(browser.getcurrenturl()).toBe('http://localhost:4200/dashboard');//断言
      browser.sleep(1000);//睡眠1秒,观察效果
    });
  });

  //测试Dashboard页面
  describe('Dashboard Heroes',function(){

    //每个测试用例it开始前执行
    beforeEach(function(){
      browser.get('http://localhost:4200');//浏览器导航到该地址
    });

    //测试:用户点击英雄,跳转显示该英雄的详细信息
    it('should show the details of hero which user clicked',function(){
      var heroes = element.all(by.className('col-1-4'));//获得4个Dashboard英雄元素

      heroes.get(0).click().then(function(){//点击第一个英雄
        expect(element(by.tagName('h2')).getText()).toBe('Narco details!');//断言
      });
    });

    //测试:对用户输入进行异步查询,点击查询结果可跳转到该英雄的详细信息
    it('should search the hero list as user types into the search Box',function(){
      var heroList = element.all('search-result'));//获得查询到的英雄
      var query = element(by.id('search-Box'));//输入框元素

      query.sendKeys('a');//输入框输入a
      expect(heroList.count()).toBe(8); //断言
      query.clear();//清空输入框

      query.sendKeys('b');//输入框输入b
      expect(heroList.count()).toBe(2);//断言

      heroList.get(//点击查询得到的第一个英雄
        expect(element('Bombasto details!');//断言
      });
    });
  });

  //测试Heroes页面
  describe('Heroes',function(){

    beforeEach(function(){
      browser.get('');
      element(by.linkText('Heroes')).click();
    });

    //测试:列表显示10个英雄
    it('should show 10 heroes',0); Box-sizing: border-Box;">'li'));
      expect(heroes.count()).toBe(10);
    });

    //测试:点击英雄显示View Details按钮,点击按钮显示该英雄详细信息
    it('should show Detail of Hero which user clicked',0); Box-sizing: border-Box;">'li'));

      heroList.get(0).click();
      element(by.buttonText('View Details')).click();
      expect(element('Mr. Nice details!');
    });

  });




  //测试Detail页面
  describe('Detail',function () {

    beforeEach(function () {
      browser.get('');
    });

    //测试:修改英雄名字,点击返回到Dashboard页面显示修改后的名字
    it('Dashboard Page: should show new name of hero after user edited',() => { var heroes = element.all('col-1-4')); heroes.get(then(() => { element('input')).clear(); element('input')).sendKeys('HuBa'); browser.sleep(1秒,观察效果 element('Back')).click(); var heroes = element.all('h4')); expect(heroes.get(0).getText()).toBe('Huba');//should be Huba }); }); //测试:修改英雄名字,点击返回到Heroes页面显示修改后的名字 it'Heroes Page: should show new name of hero after user edited',() => { element('Heroes')).click(); var heroes = element.all('li')); heroes.get(0).click(); element('View Details')).click(); element('BaBaLa'); browser.sleep('Back')).click(); expect(heroes.get('11 BaBaLa'); }); }); });






================================================================================================


http://developer.51cto.com/art/201611/521391.htm?utm_source=tuicool&utm_medium=referral


有许多原因使我过去不愿对自己的应用添加自动化测试。原因之一是不知道其中的效益成本比率,另一个原因是考虑到集成到现有生产环境的应用可能比较难。测试应用而不用从头重构代码,仅仅只是引入测试要怎么做呢?

首先我们先从简单区分测试的类型开始。应用测试有很多类型,但最为常见的是单元测试及端对端测试(亦称为集成测试)。单元测试是测试代码自身行为的一种测试。在用户看来什么也没有做,但可以确保其方法能达到期望的目的。集成测试是模仿用户行为的一种测试。比如说,登陆系统,创建帖子,退出系统等这些操作都可以自动化,并且你可以用眼睛看到其过程是怎么发生的。

这两种类型的测试,它们通常彼此结合使用。对于新的开发来说,这将是理想的。如果时间有限制,或继承于现有项目的情况下,端对端测试或许比单元测试更加合适。因为我们并不需要过多了解先前的代码库,同样可以覆盖更多场景,这将比单元测试更快,因为单元测试并不测试单个单元而是整个场景。

单元测试依然重要,但如果你必须要在开始的时候选择一个,我认为端对端测试会是更好的选择。在这文章中,我将测试一个现有的Angular 2的待办事项的项目。我将使用集成测试,并覆盖一系列的场景。

如果你需要熟悉Angular 2的入门,请看这篇文章Angular 2 article from Jscrambler

被测试的场景

  • 当应用初始化加载时,有3件待处理的事情
  • 需要加载新待办事项
  • 点击一个待办事项,然后跳到待办事项的详细页
  • 删除一个待办事项
  • 编辑一个待办事项标题,然后保存后,可以在首页的待办事项列表中看到新标题
  • 不允许保存一个空的待办事项,在点了禁用的保存按钮后,待办事项的列表依然还是原来的总数
  • 起初加载首页时,添加新待办事项的按钮应处于禁用状态
  • 保存待办事项的按钮仅应在输入待办事项标题后处于编辑状体

Todo 应用程序概述

让我们简单的描述一下Todo应用程序。应用程序将首先在主页上列出待办事项清单。有三个待办事项会详细列出。

这写数据不会由服务端提供,而是从设备文件硬编码中加载。

首页上,我们可以添加新的待办事项。我们可以通过点击代办事项的标题来访问其详细信息页面。在此页面上,我们可以编辑代办事项标题删除待办事项。

克隆并设置Todo 应用程序

1、首先克隆我已经推送到存储库这里但未经测试的应用程序,确保你是在主分支克隆的。接下来,你需要安装几个工具以便能进行下面的操作,在本教程中,使用Candidate已经发布的Angular 2,版本为2。

2、确保您已安装NodeJS的版本是Node 4.x.x或更高版本。

3、使用以下命令安装节点依赖项:

 
 
  1. npminstall

当然是在克隆的存储库中操作

4.使用Angular-CLI进行开发。安装Angular-CLI 全局使用下面命令:

  
  
  • npminstall-gangular-cli@latest
  • 5.Angular 2 端到端测试使用被称为protractor的工具来运行,安装protractor 全局使用下面命令:

      
      
  • npminstall-gprotractor
  • 6.安装所有依赖项后,使用以下命令启动开发服务器:

      
      
  • ngserve
  • 然后导航到浏览器地址:http://localhost:4200,您将看到三个待办事项列表。

    如果您在启动服务器时遇到问题,您可以参考stackoverflow issue解决问题。

    Angular 2测试相关的重要概念

    端对端测试的文件夹在e2e。 其中有一个已预备好的案列文件文件名为es2/app.e2e-spec.ts。

    其中的测试文件是用jasmine框架开发的。有很多方式模块化、组织Angular 2端对端测试,但这里为了方便,这篇文章都将在一个文件中进行。

    我们这个应用仅有一个功能那就是待办事项。为了满足大家的好奇心或有人在想比上述更复杂的情况,试想一个需要测试订单、用户配置等功能更复杂的应用的场景。对此测试的场景,我将在e2e文件夹中分别为每个待测试功能创建一个文件夹,并将各自测试文件放置其中。

    这种情况下,我们将有两个文件夹分别命名为e2e/orderse2e/userProfile。每个文件夹中仅会有一个测试文件,或者为了满足更多待测试功能的需要而创建多个测试文件。需要注意的一点是每个测试文件都以word e2e-spec.ts结尾,这样Protractor测试工具才可以加载到。

    Ok,还是回到我们简单的单个测试文件。如果你略有查看此文件,你会发现文件的头部有个导入声明(import statement)。导入是声明若干测试文件中所用的普通函数是源于哪里。然而这篇文章,我们不会使用这个,而将这个视为函数库。

    在引入声明(import statement)之后,我们有一个描述性代码块,它的两个函数调用beforeEach 和它里面的回调。

    在描述代码块内,每个回调传递给 beforeEach 都需要测试。

    每个测试再把里面的回调函数传递给它。

    让我们用命令运行当前的测试

      
      
  • protractor
  • 如果你在运行 protractor 两个命令中的一个时有问题,请参考这里。

      
      
  • ./node_modules/protractor/bin/webdriver-managerupdate
  • 或者

      
      
  • webdriver-manager 要是当前的测试失败,可能会在首页看到“app works”这样的文本提示。这并不是因为我们修改首页内容就出现这种情况。

    在我们开始编写我们的测试之前,让我们理解一些重要的通用函数,然后使用 Angular 2 的端到端测试。

    导航到页面

    在测试文件中,有一个browser全局变量。它使用import语句引入

      
      
  • import{browser,by}from'protractor/globals';
  • 你现在可以添加上。

    例如,我们使用下面语句导航到你的应用程序中可用的任何页面

      
      
  • browser.get('/');
  • 到你的主页,和

      
      
  • browser.get('/users');
  • 到users页面。请注意,这些网址是相对的URL,我们也可以使用绝对URL,但是我建议使用相对URL,因为如果你的域名改变,这更易于维护。

    选择元素

    通常的做法是在当前页面上选择元素。你可以通过一个叫做element的全局变量选择元素。它接受可以使用全局by创建的定位器。

    使用选择具有green类的p标签例子如下

      
      
  • letgreenParagraph=element(by.css('p.green'));
  • 选择多个元素,有些轻微的变化

      
      
  • letgreenParagraphs=element.all( 这将给出一个数组,而不是一个单一的元素。

    抓取元素文本

    要得到一个元素的文本,你必须先选择它,然后调用getText方法,想下面这样。

     
     
    1. letgreenParagraph=element(by.css('p.green'));
    2. lettext=greenParagraph.getText();

    点击元素

    点击元素可以使用下面的语法完成

      
      
  • letsubmitButton=element(by("form.submit-button"));
  • submitButton.click();
  • 统计元素

    我们也可以使用下面的语法来统计元素个数。

      
      
  • letblueParagraphsList=elements.by("p.blue"));
  • letcount=blueParagraphsList.count();
  • Test Scenarios测试方案

    对于那些不太寻常的概念,我们列出了上面覆盖的场景。

    确认要做的首要三件事

    当应用程序初次被加载的时候,我们有将要做三件事。

    在测试文件e2e/app.e2e-spec.ts的内部,beforeEach 代码块的下面,删除调用它的函数,并在下面添加

      
      
  • it("shouldshowthreetodoswhenwefirstloadthetodoapp",()=>{
  • browser.get("/");
  • lettodos=element.by.css(".todos.todo"));
  • expect(todos.count()).toEqual(3);
  • })
  • 不要忘记在这文件的顶部添加这个导入声明

     现在,当你运行 protractor 命令,另一个浏览器将会被打开且迅速关闭,在你的控制台上你能看到通过测试的时候显示为绿色。

    好的!我们刚刚已经写完了我们第一个通过 Angular 2 的端到端测试。

    添加一个新的待办事项

    现在进行下一个,我们可以添加一个待办事项。让我们用下面的代码添加一个测试块

      
      
  • it("shouldbeabletoaddanewtodo",()=>{
  • browser.get("/");
  • letnewTodoInput=element(by.css(".add-todoinput[type=text]"));
  • newTodoInput.sendKeys("Todo4");
  • letnewTodoSubmitButton=element(by.css(".add-todoinput[type=submit]"));
  • newTodoSubmitButton.click();
  • lettodos=element.count()).toEqual(4);
  • })
  • 我们在这里要做的是在待办事项输入框中输入文本并提交表单。然后我们检查是否有四个待办事项。 如果是的话,测试通过。

    我们刚刚介绍了另一个函数sendKeys,它可以访问一个选中的元素,常用于输入文本到输入框这类元素中。

    查看待办事项的详情页

    我们应该能单击一个待办事项转到该待办事项的详情页,让我们用下面的测试实现它吧。

      
      
  • it("shouldbeabletoclickonatodoonthehomepageandgettothedetailspage",()=>{
  • browser.get("/");
  • letfirstTodo=element.by.css(".todos.todo")).first();
  • letfirstTodoText=firstTodo.getText();
  • firstTodo.click();
  • letinputFieldText=element(by.css("todoinput[type=text]")).getAttribute("value");
  • expect(inputFieldText).toEqual(firstTodoText);
  • })
  • 删除一个待办事项

    我们应该能删除一个待办事项。现在让我们试着删除一个待办事项看看能不能成功。

    我们将转到待办事项页并单击删除链接,当我们返回主页时,我们能看到减少了一个待办事项。

      
      
  • it("shouldbeabletodeleteatodo",153); background-color:inherit; font-weight:bold">first();
  • firstTodo.click();
  • letdeleteLink=element(by.cssContainingText("span","Delete"));
  • deleteLink.click();
  • lettodosList=element.by.css(".todos.todo"));
  • expect(todosList.count()).toEqual(2);
  • })
  • 编辑一个待办事项的标题

    我们能编辑待办事项的标题,保存后能在主页的待办事项列表中显示标题

      
      
  • it("shouldbeabletoeditatodotitle",153); background-color:inherit; font-weight:bold">first();
  • firstTodo.click();
  • lettodoInputField=element(by.css("todoinput[type=text]"));
  • todoInputField.clear();
  • todoInputField.sendKeys("EdittedTodo1Title");
  • letsaveButton=element(by.css("todobutton[type=submit]"));
  • saveButton.click();
  • firstTodo=element.first();
  • letfirstTodoText=firstTodo.getText();
  • expect(firstTodoText).toEqual("EdittedTodo1Title");
  • })
  • 不能保存空的待办事项

    当我们想保存一个空的待办事项时,我们无法进行操作,并且单击禁用按钮时,待办事项列表依然保持同样的长度。

      
      
  • it("shouldnotbeabletosaveanemptytodo",153); background-color:inherit; font-weight:bold">by.css(".add-todoinput[type=text]"));
  • letnewTodoSubmitButton=element( 保存按钮在初始化时禁用

    初始化时添加待办事项按钮被禁用,所以我们添加下列代码

      
      
  • it("shouldhaveaddtodobuttonbedisabledinitially",()=>{
  • browser.get("/");
  • letnewTodoSubmitButton=element(by.css(".add-todoinput[type=submit]"));
  • expect(newTodoSubmitButton.isEnabled()).toEqual(false);
  • })
  • 当我们开始输入时启用保存按钮

    只用当我们开始输入待办事项标题时,待办事项保存按钮才被启用。

      
      
  • it("shouldonlyenablesavetodobuttonwhenwestarttypinganewtodotitle",153); background-color:inherit; font-weight:bold">by.css(".add-todoinput[type=submit]"));
  • letnewTodoInputField=element(by.css(".add-todoinput[type=text]"));
  • newTodoInputField.sendKeys("NewTodo4");
  • expect(newTodoSubmitButton.isEnabled()).toEqual(true);
  • })
  • 结论

    现在,我们来总结一下 Angular2 的“端对端”测试。即使您没有任何的编程基础,也可以快速上手编写“端对端”测试。对于那些被引入代码库而又可能存在漏洞的部分,“端对端”测试是一个高效便捷的方法来捕获问题所在。

    我们在概念部分中介绍了一些其他方法。您可以点击这里来浏览这些 Protractor API。并且可以在 GitHub repository 上找到这个应用的完整版和测试版。

    我希望您看完这个介绍之后,在您修改任何一行代码之前都能兴奋的开始您的前端应用测试。如果您高兴,和我们交流一些您在日常测试中的高见。或者是您关于 Javascript 框架及 Angular2 的想法。感谢您的阅读。

    【编辑推荐】

    原文地址:https://www.jb51.cc/angularjs/145651.html

    版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

  • 相关推荐