当前位置: 首页 > news >正文

荆州 商务 网站建设/百度客服

荆州 商务 网站建设,百度客服,wordpress数据库密码修改,属于网页制作平台的是什么「测试」是为了度量和提高软件质量,对测试软件进行工程设计、实施和维护的过程。测试的发展,逐步从“调试”为主,到“证明软件工作正确”,再到“证明软件存在错误”,再到今天的“预防”体系,经历了几十年的…

ba8d44ccef7b391f6e0d494c6efc172c.png

「测试」是为了度量和提高软件质量,对测试软件进行工程设计、实施和维护的过程。测试的发展,逐步从“调试”为主,到“证明软件工作正确”,再到“证明软件存在错误”,再到今天的“预防”体系,经历了几十年的过程。可以说,测试已经成为软件质量的守卫者角色。

近几年,自动化测试在前端领域日益活跃,各种前端测试工具层出不穷。但我们对自动化测试持有的态度却不尽相同,有的人认为测试只是一件政治正确的事情,实施起来,投入产出不成比例,因此部分项目里测试覆盖率不高,甚至没有。我们可能已经看过了很多介绍自动化测试的文章和教程,但如何理解测试,对于测试策略的制定更具有指导意义。

为什么要前端测试

随着互联网行业的迅猛发展,开发团队对敏捷性提出了更高的要求。早期的几个月发布一次,已经跟不上业务扩张的步伐。对需求更快研发,更快调整,是决定业务成败的生命线。如果没有严格的测试来验证软件的正确性,开发者将难以快速回归代码,导致的结果就是不敢重构(最近团队也有类似的困境),只能不断往上堆叠,最终代码腐化,然后在某个时刻崩塌。

理想的情况是,为应对频繁快速的迭代,增加人员投入,对新增或重构的功能进行完整回归。但现实总有局限性,其表现在以下几个方面:

  • 软件工程中,人力与开发时间不具有线性关系,过多的人力投入项目,如同建造一座巴别塔
  • 不符合 DRY 原则,每次完整回归需要投入大量重复性工作,同时,企业内一般都面临着测试人员短缺的处境
  • 人员流动是常态,新人进入前都有一个拼图阶段,这为持续迭代带来了更多挑战
  • 开发者也需要对自己的代码回归负责,不能只顾写代码,然后通通丢给测试同学,这会给测试与合作方带来“可测试程度不高”的不好印象
  • 人类(好吧我是指测试)总会失误,谁也不能保证测试结果一定可靠。有时万分之一的疏漏,就可能为线上带来灾难

良好的自动化测试,不仅为开发者提升了效率,形成正面影响(较好的测试用例通过率),也在另一个层面为测试者带来了价值。做好测试这一环,我们也才能进一步去考虑实现持续交付、持续部署的可能性,真正为业务的快速迭代给出答案。

制定测试策略

如果你认可自动化测试的价值,那么接下来的问题是如何制定测试策略。开发者一开始会疑惑,应该从哪个层面着手,写到什么程度为止,因为你永远能写出更高覆盖率的测试。

我们可以从测试的粒度来看:

单元测试: 针对程序最小单位进行测试,可以是一个函数,过程或一个方法(OOP)。单元测试是极限编程的基础,有很强的错误隔离能力,方便快速定位问题,同时由于其自低向上的测试路径,使软件集成变得简单。缺点是不能发现集成错误和性能问题

集成测试: 在单元测试基础上,集成多个模块,组成系统或子系统,这能发现一些单元测试时不能发现的问题

端到端测试: 在终端上以用户视角(黑盒)测试产品的整体质量,如业务逻辑,UI 等。这个阶段的测试结果更贴近于产品的最终形态,一般是正式或准正式环境。编写端到端测试成本会比较高,首先是需要花费更多的时间在依赖集成上,其次是运行环境复杂,比如大量的异步操作需要被处理,以及很多时候我们并没有一个完整的后端沙箱链路可以用来测试

不同开发领域,对这三个阶段的划分多有不同。典型的,前端相比于后端,会有组件测试、UI 测试等。更具体的场景,比如 Redux 体系还会包含 Action、Reducer 等维度的测试,但如果你以某个标准将其归纳入上述阶段,会基本符合以下规律:

350cfa89c546c749f35cf8417020f5a5.png

落地到项目时,由于单元测试更容易实施,收益相对直观,投入成本也能接受,所以优先编写单元测试是个好的选择。集成测试和端到端测试,因为依赖更多了,执行环境也愈加复杂,使得测试策略的编写更加困难。

虽然你可能在任何阶段出现 bug,但越接近终端运行阶段,bug 的数量会更少,而错误稳定性、错误隔离能力会降低,使得问题排查难度加大。同时,和测试策略一样,需求的变更与逻辑重构,在代码层面的影响也是自底向上的,这意味着越多上层的测试,带来的维护成本会变得更大,因此投入和产出比明显处于下降趋势。

下图是来自谷歌的测试金字塔:

a439591503f8b24ecd4219100a17848d.png

可以解读为,越往上走,软件测试的覆盖程度越大,意味着能发现更多的问题。但同时,宽度变窄,因为此时测试投入成本曲线变得陡峭,收益降低,应该缩减投入比例。Google 测试团队建议以 70%、20%、10% 的比例分别投入单元测试,集成测试和端到端测试。

测试建议

  • 编写测试代码时,建议以一种利于重构的方式去写,更多关注输入输出结果,保证工作正常,而不用对无关紧要的细节进行限制
  • 只对稳定的、需求确定的项目进行测试,否则代码将面临较大改动
  • 不建议测试 UI 样式,比如颜色,字体大小等,可以通过录制的方式快速 Review
  • 优先保证核心链路
  • 自动化测试不是银弹,重构不能完全依赖测试(毕竟你的测试代码也需要被测试)

React 测试落地

现在我们来看一下如何针对 React 项目进行测试。通常,一个前端项目的测试要求包含:完备的单元测试组件测试端到端测试能力。落地到 React 项目的测试覆盖面如下:

  • 最小化单元测试,如基础类方法、utils 工具库等
  • Redux actions、reducers、effects 测试
  • React 组件测试
  • 端内测试(考虑到后端可能没有全流程的沙箱链路,所以使用 mock 数据测试)

所需的最小工具集为:

  • Test Runner,用于测试策略的组织描述,生成报告等
  • 断言,用于判断测试结果是否符合预期,根据给定的表达式的值为 true 或者 false,决定是否打印错误信息以及生成测试报告,在编程或者测试中都会用到
  • 辅助工具,用于侵入运行时对象、库、类等,对测试过程有极大帮助
  • React 组件测试工具
  • 无头浏览器,用于贴近真实环境的端内测试
  • 其他如测试覆盖率工具等

工具对比

各类 Test Runner 和断言工具,差别不是很大,都能满足需求;
React 组件测试目前除了 Enzyme 没找到类似的工具;
无头浏览器有 Puppeteer 和 Selenium,前者比较轻量,API 简洁且功能强大,后者可测试多浏览器,不过要想覆盖到尽可能多的容器,需要在 Windows 中部署(e.g. IE),目前看来前者能较好满足基本需求,PhantomJS 不再维护,暂不考虑;
因为集成方案中,也是对这些工具的集成,一些增强的功能暂时不是强诉求。考虑通用性,轻量和灵活度,目前个人考虑是不用集成方案,而是使用自由组合的方式;

自选方案

在对比了各个集成方案后,我选择了 Mocha、Chai、jsdom、Enzyme、Sinon、Puppeteer 作为测试方案,以下是主观对比:

11112b03acc4fe9f197c8702a3398515.png

建议:编写待测试的代码时,尽量符合 SOLID 原则,不要直接依赖浏览器环境,便于在 Node.js 环境中直接测试。同时,考虑到在代码中进行单元测试、组件测试,对浏览器环境难免有要求,比如三方库需要访问 window、document、cookie、宿主类或接口,加载外部脚本等。所以测试时可以考虑使用 jsdom 内置浏览器对象到 global(比如使用 jsdom-global),或者将代码构建后,在浏览器中测试,Mocha 等 Test Runner 都支持在浏览器中执行测试。

单元测试

准备工作:因为涉及到 ES6 和 JSX 语法,请先加载 Require Hook:@babel/register 以动态编译不支持的语法。同时,IDE 的 debugger 能力有助于我们更高效地测试,需加以利用。

接下来我们以 DvaJS 项目为例,从单元测试开始,逐步覆盖各测试切面。如以下例子通过 Sinon 对方法进行 wrap:

'should call method once with argument': function () {var object = { method: function () {} };var spy = sinon.spy(object, 'method');object.method(1);assert(spy.withArgs(1).calledOnce);
}

测试 effects(这里使用了 Redux 推荐的 runSage 来一次性跑完 effects):

import { expect } from 'chai';
import { runSaga, effects } from 'dva/saga';describe('Account Manage', function() {describe('info', function() {const {state,effects: {edit}} = require('../src/account/models/info');it('should dispatch saveInfo action when editing', async function() {const dispatched = [];const payload = { username: 'name' };const result = await runSaga({dispatch: (action) => dispatched.push(action),getState: () => state}, edit, { payload }, effects).done;expect(dispatched).to.have.lengthOf(1);expect(dispatched[0]).to.have.property('type', 'saveInfo');});});
});

组件测试

Enzyme 使用虚拟浏览器技术,可以以不同的渲染方式测试你的组件:

  • shallow,只渲染当前层组件,子组件不会被渲染,其会调用部分周期方法,不会实际地渲染节点,适用于只测试当前组件的输入输出
  • mount,渲染高阶组件,包含整个组件树,这需要 DOM APIs(至少看起来像,如 jsdom 环境)
  • static,静态渲染组件,输出 HTML 并使用文档树解析工具 Cheerio 包裹

你可以很方便地使用 jQuery 风格的 selectors 选择节点,同时,chai-enzyme 可赋予 Chai 更多基于 Enzyme 的断言特性。

import { expect } from 'chai';
import React from 'react';
import { mount } from 'enzyme';
import { effects } from 'dva/saga';const { put } = effects;describe('Banner', function() {const Banner = require('../src/components/Banner');it('should render correctly', async function() {const wrapper = mount(put}/>);// wait async requestawait new Promise((resolve) => setTimeout(resolve, 2000));expect(wrapper.state('bannerData')).to.have.lengthOf.at.least(1);expect(wrapper.find('.slick-list')).to.have.lengthOf.above(1);});
});

E2E 测试

使用无头浏览器模拟用户的真实操作:

// launch server
import ready from '../../server';
import { expect } from 'chai';
import puppeteer from 'puppeteer';describe('Account', function() {// set a long timeoutthis.timeout(60000);describe('log in', function() {it('should log in correctly', async function() {const browser = await puppeteer.launch();const page = await browser.newPage();// wait dev server readyawait ready();await page.goto('http://localhost:8000/account/login', { 'waitUntil': 'networkidle0' });await page.type('#username', 'smalldragonluo');await page.type('#password', 'pwd');await page.click('#submit');// ...const result = await page.$eval('#result', (element) => {return element.innerHTML})expect(result).to.equal('Success!');await browser.close();});});
});

附:前端测试工具

列了一个测试工具横向对比,详情见:

https://blog.smalldragonluo.com/2019/05/04/%E7%BB%86%E8%AF%B4-React-%E6%B5%8B%E8%AF%95/?blog.smalldragonluo.com

参考资料

  • React 单元测试策略及落地
  • Just Say No to More End-to-End Tests
  • 单元测试 - 维基百科
  • React 项目 的 UI 测试

相关文章:

  • 接私活做网站/百度客服人工在线咨询