本文作者:伏晓,声网Agora Web引擎研发工程师。本文先简略介绍了Cypress测试平台,之后介绍基于模型的测试(Model-Based Testing)办法,并应用其对风行的TodoMVC利用进行建模和测试。最初指出这一测试Demo的可改良之处,同时瞻望了基于模型测试的将来倒退。

Cypress介绍

Cypress是为古代Web App打造的下一代前端测试工具。应用古代JavaScript框架构建Web应用程序的开发人员或QA工程师都能够采纳Cypress疾速编写和运行E2E(端到端)测试、集成测试和单元测试。

Cypress 的 Time travel 性能是它的最大亮点,反对回退至任意工夫的 Snapshot, 像是在回放电影一样,将测试运行过程中的每个细节重现进去 。能够十分疾速的定位问题,极大的进步了调试自动化测试的体验。让它不同凡响的是它的运行机制:大多数测试工具(如Selenium)通过在浏览器内部运行并在网络上执行近程命令来运行,Cypress恰恰相反——Cypress在与你的应用程序雷同的生命周期里执行。其余方面劣势能够在https://docs.cypress.io/zh-cn... 看到。

在它的运行界面中能够看到每一步的操作,只需点击你想重现的步骤即可看到该步的截屏。如下图所示,点击“找到蕴含 type 的元素”这一行代码,右侧就会呈现出此时的场景,并高亮出这个元素。

具体的介绍能够到Cypress.io官网查看。也能够间接下载Cypress Real World App进行实在利用场景的测试体验。在这一展现场景中,运行100个测试(包含约30个API测试和70个端到端测试)须要5分30秒,这一速度曾经比很多手工冒烟测试还要快。而他是齐全主动并可调式的。

须要留神的是必须期待Node.js服务器和React开发服务器启动结束后能力运行Cypress进行测试。

基于模型的测试

基于模型的测试(Model-based Testing)属于软件测试畛域的一种测试方法。依照此办法,测试用例能够齐全或局部的利用模型主动产生。 MBT 则容许软件开发人员和测试人员,只关注建设零碎的正确性以及模型的规范性,再通过专门的 MBT 工具依据不同的测试用例设计策略从零碎模型生成牢靠的测试用例。
测试Case是由模型生成,而不是由源代码生成。因而,基于模型的测试又经常被当作黑盒测试的一种模式。对于简单的软件系统中,如何利用基于模型的测试还在摸索中,在测试学术界曾经有一些对于主动生成测试模型的论文发表。

长处

  1. 测试用例的保护更轻松:保护好模型,无需关注测试用例的细节
  2. 软件缺陷发现的更早:在构建被测系统模型的过程中,须要对被测系统有比拟全面的了解,那么在晚期建模过程中就能够发现被测系统中的一些问题,不须要等到执行大量用例时才发现;
  3. 测试自动化的程度更高:建模后,MBT能够主动生成测试用例,不须要人工编写测试文档;
  4. 测试覆盖率变得更高,使得彻底的测试(即:穷尽测试)成为可能:传统测试设计的过程中依赖人工,MBT生成测试门路时会防止人工设计测试用例时的思维局限性,生成更丰盛的测试门路用例,然而是否须要执行“彻底”的测试由漏测对业务的影响决定。MBT只是从技术上提供了穷尽测试可能性。
  5. 基于模型间接保护测试用例的形式更高效:传统保护时须要依赖人工,须要消耗大量的人力和工夫老本,从新测试设计。应用MBT只须要保护好测试模型即可,生成测试用例的工作能够由MBT工具主动实现;

毛病

  1. 学习老本较高:要求开发人员、测试人员都精通建模,和工具的选型;
  2. 应用MBT的初期投资较大:已有的MBT工具不肯定适宜本人产品,定制的话须要思考扩展性,和解决简单逻辑,也就是要花费大量工夫和精力;
  3. 用例爆炸

应用@xstate/test对TodoMVC进行基于模型的测试

Todo MVC是前端风行的一个用于展现古代JavaScript 框架和状态治理性能的Web App。它的Spec能够在https://github.com/tastejs/todomvc/blob/master/app-spec.md找到。
@xstate/test是由微软的David Khourshid编写的一个基于模型的测试生成工具,它是基于Statecharts这一无限状态机模型衍生出的工具。但它不仅能用于测试应用xstate编写的软件,对所有能被模型化的Web App根本都能通过这一工具进行基模测试。

应用@xstate/test对某一零碎进行基于模型的测试有如下几个步骤:

  1. 创立对该利用形容的Statecharts形象模型
  2. 通过可视化工具等办法确保模型的一致性
  3. 在模型的状态中增加确保零碎处在该状态的断言
  4. 提供利用状态转换的事件与实在操作
  5. 应用测试框架运行主动生成的测试

上面我尝试应用xstate软件对有一个Todo我的项目的状况进行简略建模。该TodoMVC代码fork自Cypress的官网示例:GitHub - cypress-io/cypress-example-todomvc: The official TodoMVC tests written in Cypress.。

对Todo Item进行建模

其中Unknown是一个两头过渡状态,它能够确保该Todo状态机正确保留了外部的状态并进行转换。能够参考:

  • https://xstate.js.org/docs/guides/history.html
  • https://xstate.js.org/docs/guides/transitions.html#transient-transitions
    该模型的代码能够在这个GitHub Gist上看到:todo.machine.js · GitHub

TodoMVC的Todo Item的Statecharts模型——通过xstate可视化工具生成

增加状态的断言

在要测试的状态节点(Unknown的过渡状态除外)中增加确保App处在这一状态的断言:

Editing: {  meta: {    test: () => {      cy.get('.todo-list li').should('have.class', 'editing');      cy.get('.main').should('be.visible');      cy.get('.footer').should('be.visible');    },  },}

这里用到了Cypress的选择器和断言工具,确保在编辑状态时的UI状态是正确的。这样顺次增加实现所有状态的断言。

增加状态转换事件

在状态模型中定义的形象状态转换事件并不能使测试App的实在状态产生转换,所以要在测试模型中注入能使该事件正确产生的UI办法调用。

  •  应用Cypress提供的函数产生转换事件

生成用例和运行测试

有了下面这些筹备,当初@xstate/test就能够主动生成并运行测试:

const testPlans = testModel.getSimplePathPlans();testPlans.forEach((plan) => {  plan.paths.forEach((path) => {    it(path.description, () => {      return cy        .get('.new-todo')        .type('Hello World!{enter}')        .then(() => {          return path.test(cy);        });    });  });});

同时你也能够调用Test Model上的testCoverage办法取得不同状态的覆盖率报告:

it('coverage', () => {  testModel.testCoverage({    filter: (stateNode) => !stateNode.id.startsWith('Todo.Unknown'),  });});

应用@xstate/test + cypress进行测试的界面

问题与瞻望

因为对该利用定义的状态非常复杂,所以只能执行最短门路用例生成,不能执行简略门路用例生成,否则会因为状态太多生成过多测试用例,导致利用卡死。

简略门路的图示

最短门路的图示

但这也只是Todo MVC最简略(只有一个Todo我的项目)的状态机,如果Todo数量减少,状态数量将呈指数增长。所以如果要将该测试方法利用到理论,还须要更高阶层的形象或者更加自动化的办法来生成测试对象的状态模型。

举荐资源

  • xstate作者对于Model-Based Testing的演讲:Write Fewer Tests! From Automation to Autogeneration - David Khourshid - React Rally 2019
  • 应用Learning-Based Testing办法主动生成Todo MVC的状态模型的文章:Model-Based Testing Without Models: The TodoMVC Case Study