×

EmberJS 教程

EmberJS 概述EmberJS 环境配置EmberJS 应用EmberJS 对象模型EmberJS 模板EmberJS 路由器EmberJS 组件EmberJS 模型EmberJS 视图EmberJS 控制器EmberJS 测试EmberJS 指定查询参数

Ember 对象模型

Ember 类的定义 初始化 继承Ember 类的扩展Ember 计算属性Ember 观察者Ember 数据绑定Ember 枚举Ember 第一章对象模型小结

Ember handlebars模板

Ember handlebars基础Ember handlebars条件表达式Ember handlebars遍历标签Ember handlebars显示对象键Ember handlebars属性绑定Ember {{link-to}} 助手Ember 路由 模板执行渲染顺序Ember {{action}} 助手Ember 表单元素Ember 调试助手Ember 工具类的助手Ember 第二章模板小结

Ember 路由

Ember 路由定义Ember 指定与路由关联的模型Ember 模板渲染Ember 路由重定向Ember 路由终止挑战和激活Ember loading error子路由Ember 查询参数Ember 异步路由

Ember 组件

Ember 组件定义Ember 属性传递Ember 包裹内容自定义包裹组件的HTML标签Ember 处理事件Ember action触发变化

Ember 控制器

Ember 控制器Ember 管理控制器的依赖关系

Ember 模型

Ember model简介Ember 定义模型Ember 记录查询Ember 新建、更新、删除记录Ember 设置记录到StoreEmber model的关联关系处理Ember 元数据Ember 自定义适配器Ember 自定义序列号器

Ember 测试

Ember 测试简介Ember 验收测试Ember 单元测试

Ember 验收测试


验收测试

使用ember generate acceptance-test创建一个验收测试,比如:

ember g acceptance-test login

执行完毕命令之后得到如下文件内容:

//tests/acceptance/login-test.js

import { test } from 'qunit';
import moduleForAcceptance from 'people/tests/helpers/module-for-acceptance';

moduleForAcceptance('Acceptance | login');

test('visting /login', function(assert) {
  visit('/login');

  andThen(function() {
   assert.equal(currentURL(), '/login');
  });
});

moduleForAcceptance用来启动、终止程序。最后几行test中包含了一个示例。

几乎所有的测试都有一个路由请求,用于和页面交互(通过helper)并检查DOM是否按照期望值进行改变。

举个例子:

test('should add new post', function(assert) {
  visit('/posts/new');
  fillIn('input.title', 'My new post');
  click('button.submit');
  andThen(() => assert.equal(find('ul.posts li:first').text(), 'My new post'));
});

大体意思为: 进入路由/posts/new,在输入框input.title填入My new post,点击button.submit,期望的结果是: 在对应列表下ul.posts li.first的文本为My new post.

测试助手

在测试web应用中的一个主要的问题是,由于代码都是基于事件驱动的,因此他们有可能是异步的,会使代码无序运行。

比如有两个按钮,从不同的服务器载入数据,我们先后点击他们,但可能结果返回的顺序并不是我们点击的顺序。

当你在编写测试的时候,你需要特别注意一个问题,就是你无法确定在发出一个请求后,是否会立刻得到返回的响应。因此,你的断言需要以同步的状态来等待被测试体。例如上面所举的例子,应该等待两个服务器均返回数据后,这时测试代码才会执行其逻辑来检测数据的正确性。

这就是为什么在做断言的时候,Ember测试助手都是被包裹在一个确保同步状态的代码中。这样做避免了对所有这样的代码都去做这样的包裹,并且因为减少了模板代码,从而提高了代码的可读性.

Ember包含多个测试助来辅助进行验收测试。一共有2种类型:异步助手asynchronous和同步助手synchronous

异步测试助手

异步测试助手可以意识到程序中的异步行为,使你可以更方便的编写确切的测试。

同时,这些测试助手会按注册的顺序执行,并且是链式运行。每个测试助手的调用都是在前一个调用结束之后,才会执行下一个。因此,你可以不用当心测试助手的执行顺序。

  • click(selector)
    • 点击一个元素,触发该元素所绑定的click事件,返回一个异步执行成功的promise
  • fillIn(selector, value)
    • 用执行成功的promise值填充到选中的input元素上。使用作为时,记得元素的value是标签所指定的值,并不是标签显示的内容。
  • keyEvent(selector, type, keyCode)
    • 模拟键盘操作。比如选中的元素检测按键keypress,按键按下keydown,按键弹起keyup事件的keyCode
  • triggerEvent(selector,type,keyCode)
    • 在指定元素上触发给定事件,比如blurddlclick等事件...
  • visit(url)
    • 访问路由并返回promise执行成功的结果。

同步测试助手

同步测试助手,当触发时会立即执行并返回结果.

  • currentPath()
    • 返回当前路径
  • currentRouteName()
    • 返回当前激活的路由名称
  • currentURL()
    • 返回当前URL
  • find(selector, context)
    • 寻找应用根元素中的指定下上文(可选)的元素。将其域定义到根元素可以有效的避免与测试框架的冲突。当上下文没有指定的时候,会按照默认方式完成。

等待助手

andThen测试助手将会等待所有异步测试助手完成之后再执行.举个例子:

//  tests/acceptance/new-post-appears-first-test.js

tese('should add new post', function(assert) {
  visit('/posts/new');
  fillIn('input.title', 'My new post');
  click('button.submit');
  andThen(() => assert.equal(find('ul.posts li:first').text(), 'My new post'));
  });

首先,我们访问/posts/new地址,在有titlecss类的input输入框内内填入内容“My new post”,然后点击有CSS类submit的按钮。

等待签名的异步测试助手执行完(具体说,andThen会在路由/posts/new访问完毕,input表单填充完毕,按钮被点击之后)毕后会执行andThen助手。注意andThen助手只有一个参数,这个参数是一个函数,函数的代码是其实测试助手执行完毕之后才执行的代码。

andThen助手中,我们最后会调用assert.equal断言来判定对应位置的值是否为My new post

自定义测试助手

使用命令ember generate test-helper来创建自定义测试助手。

下面的代码是执行命令ember g test-helper shouldHaveElementWithCount得到的测试例子:

//tests/helpers/should-have-element-with-count.js

export default Ember.Test.registerAsyncHelper(
    'shouldHaveElementWithCount', function(app){}
);

Ember.Test.registerAsyncHelperEmber.Test.registerHelper'是当startApp被调用时,会将自定义测试助手注册。两者的区别在于,前者Ember.Test.registerHelper`会在之前任何的异步测试助手运行完成之后运行,并且后续的异步测试助手在运行前都会等待他完成.

测试助手方法一般都会以当前程序的第一个参数被调用,其他参数,比如assert,在测试助手被调用的时候提供。测试助手需要在调用startApp前进行注册,但ember-cli会帮你处理,你不需要担心这个问题。

下面是一个非异步的测试助手:

//tests/helpers/should-have-element-with-count.js

export default Ember.Test.registerHelper('shouldHaveElementWithCount',
  function(app, assert, selector, n, context){
    const el = findWithAssert(selector, context);
    const count = el.length;
    assert.equal(n, count, 'found ${count} times');
  }
);

//shouldHaveElementWithCount(assert, 'ul li', 3);

下面是一个异步的测试助手:

export default Ember.Test.registerAsynHelper('dblclick',
  function(app, assert, selector, context){
    let $el = findWithAssert(selector, context);
    Ember.run(() => $el.dblclick());
  }
);

//dblclick(assert, '#persion-1')

异步测试助手也可以让你将多个测试助手合并为一个.举个例子:

//tests/helpers/add-contact.js
export default Ember.Test.registerAsyncHelper('addContact',
  function(app,name) {
    fillIn('#name', name);
    click('button.create');
  }
);

//addContact('Bob');
//addContact('Dan');

最后, 别忘了将你的测试助手添加进tests/.jshintrctests/helpers/start-app.js中、在tests/.jshintrc中,你需要将其添加进predef块中,不然就会得到jshint测试失败的消息.

{
  "predef": [
    "document",
    "window",
    "locaiton",
    ...
    "shouldHaveElementWithCount",
    "dblclick",
    "addContact"
  ],
  ...
}*

你需要在tests/helpers/start-app.js引入测试助手,这些助手将会被注册到应用中。

import Ember from 'ember';
import Application from '../../app';
import Router from '../../router';
import config from '../../config/environmnet';
import './should-have-element-with-count';
import './dblclick';
import './add-contact';

分类导航

关注微信下载离线手册

bootwiki移动版 bootwiki
(群号:472910771)