创建一个新的CukeTest项目

如果你刚开始使用CukeTest,或许你需要这篇文章来了解如何创建CukeTest的项目,以及项目的更多知识。

创建项目

打开CukeTest,在“欢迎”界面选择“新建项目”,项目名称自定义,接着选择项目路径,完成创建即可。

选择合适的模板

目前有5个项目模板可以在创建新项目时进行选择:

  • Basic: 基本的Cucumber.js项目;
  • Web: 使用selenium-webdriver的Web测试项目;
  • API: API测试项目;
  • Qt: Qt测试项目;
  • Mobild: 移动端测试项目;

所有这5个模板都包含package.json文件,您可以根据需要添加依赖的NPM包。

新建项目对话框

  • Basic是基本模板,没有任何预先配置的依赖包。

  • Web 模板配置了“selenium-webdriver”,以及不同浏览器的驱动程序: “chromedriver”,“iedriver”,“geckodriver”。 使用这些依赖包,脚本可以分别自动化Chrome,IE和FireFox。如果你只需要自动化部分浏览器,可以将不需要的依赖包删除,具体操作请参见NPM包的管理

  • API模板配置了“got”包,这是一个流行的包,用于运行RESTful API测试。

  • Qt模板使用了CukeTest内置的Qt自动化库,以及自带的对象模型管理器。

  • Mobile模板使用了webdriverio的自动化库,可以通过操作Appium自动化iOS或Android原生应用。

在创建“Web”或“API”项目之后,您需要先下载npm依赖包,然后才能正常运行项目,如果你不需要模板中预设的依赖包,可以通过包管理器或编辑package.json文件删除不需要的依赖包配置。欲了解更多信息,请参阅 NPM包的管理

了解项目结构

CukeTest项目像NPM项目一样拥有package.json,作为自动化脚本管理工具,它对每个项目的要求非常宽松,除去运行项目必要的剧本文件和步骤定义脚本文件以外,其它的所有文件都是按需求添加的,这也和CukeTest项目的加载方式有关,在下一节运行项目中会展开来介绍。

下面我们创建一个CukeTest项目来介绍它的项目结构。假设项目名称为CukeTestProject,下面列出了目录树,其中的加~的文件的命名和内容只是一种建议的规范,有利于所有CukeTest使用者快速理解项目。

  1. CukeTestProject // 项目名称
  2. package.json // npm包管理文件,如果不引入自定义的JS库则不用修改
  3. └─ features // 项目的主体文件夹,根目录可以直接存放多个剧本文件
  4. feature1.feature // 剧本文件
  5. ├─ step_definitions // 脚本文件夹,存放步骤定义脚本和模型文件
  6. definitions1.js // 步骤定义脚本
  7. ~model1.tmodel // 模型文件
  8. └─~support // 存放项目的其它脚本和被调用资源
  9. ~env.js // 配置cucumber内核运行配置,默认修改了超时时间
  10. ~hook.js // 管理生命周期,或者称作钩子
  11. └─~data // 存放各类数据文件
  12. ~data.csv

新建文件

新建剧本文件/脚本文件

新建模型文件

在执行对应用的自动化操作前,需要先创建一个用于保存应用中各种控件对象的模型文件。模型文件有两种方法创建:

  1. 直接新建文件,并将扩展名改为.tmodel
  2. 在工具栏右侧打开模型管理器,在模型管理器中新建模型文件,如下:
    新建模型文件

启动应用

由于Qt Agent的机制,CukeTest自动化目标应用需要建立在目标应用以加载Qt Agent的方式启动的基础上。而CukeTest有以下几种方式来通过Qt Agent启动应用。

从模型管理器启动应用

在模型管理器中,在菜单栏的“操作”→“启动样例”来启动应用,选中目标可执行文件即可。

从命令行启动应用

从命令行中启动应用前先设置一个全局变量LD_PRELOAD,默认的路径值为: /usr/lib/cuketest/bin/agents/libqtagent.so(部分系统中为/opt/apps/com.leanpro.cuketest/files/lib/cuketest/bin/agents/libqtagent.so)。假设目标应用的路径为/usr/lib/cuketest/bin/sample,那么启动应用的命令为:

  1. $> export LD_PRELOAD=/usr/lib/cuketest/bin/agents/libqtagent.so
  2. $> /usr/lib/cuketest/bin/sample

由于在命令行中使用export指令设置的环境变量只会在当前命令行环境生效。
如果在设置该环境变量后启动的不是一个Qt应用,则不会生效,详见Qt Agent的引导

从脚本中启动应用

那么我们在编写自动化脚本的时候,可以使用leanpro.qt库中QtAuto模块提供的launchQtProcess()方法来加载Qt Agent并启动应用。

由于启动应用的脚本通常写在hooks.js文件中的BeforeAll生命周期,因此该脚本通常写作如下:

  1. const { BeforeAll} = require('cucumber');
  2. const { Util } = require('leanpro.common');
  3. const { QtAuto } = require('leanpro.qt');
  4. BeforeAll(async function () {
  5. QtAuto.launchQtProcess("/usr/lib/cuketest/bin/sample");
  6. })

这样的hook就能够实现在每次项目启动前将sample应用启动的功能了。

运行项目

CukeTest提供了各种粒度的运行,包括运行项目、运行剧本、运行脚本,以及运行场景和运行步骤。在了解这些运行的区别时,我们先了解一下CukeTest项目开始运行前是如何加载项目中的各个文件的。

通过env.js文件理解项目加载方式

打开或创建env.js文件,这个文件中通常只有以下两行代码:

  1. const { setDefaultTimeout } = require('cucumber');
  2. setDefaultTimeout(30 * 1000); //set step timeout to be 30 seconds

该代码是将步骤的超时时限设为30秒。CukeTest中缺省的超时时间为5秒,这可以避免在步骤出现异常时无限期的等待下去。因为有些步骤的运行会超过5秒,比如等待页面加载、等待文件上传之类比较费时的操作,可能会超过5秒误触超时。因此这里设置一个更长的超时时间,即在等待30秒以后就会自动停止并报错。

那么这句调用是如何生效的呢?这简单介绍一下Cucumber项目的加载方式,在开始运行(包括运行项目、剧本、场景、步骤,但不包括运行脚本)时,项目会加载所有的”features”目录下的文件,如果该文件是js文件,则加载过程会使其运行,这时暴露在函数体外的脚本都会运行生效(由于env.js中没有函数,所有的代码都在函数体外,因此会被直接运行)。

可以通过将env.js文件改为如下脚本后,点击运行剧本运行任意某个剧本文件:

  1. console.log("env.js was ran!\n");

输出结果如下,可以看到文件成功的被加载了: env.js输出结果

基于这个加载特性,我们可以轻松的将编写的辅助函数整理到一个文件中,但却不需要export/import即可使用。但同样的,定义在函数体外的变量会被其它地方加载,因此除去必要的情况(比如在项目开始前启动了一个应用,需要将应用的pid保存下来用于项目结束后停止该应用的进程),不要在函数体外定义变量,在同个场景的不同步骤间传递变量请使用World对象

调试与运行

CukeTest提供了各种粒度的运行,在工具栏中有以下三种运行方式:

  • 运行项目: 运行全部的剧本文件,运行顺序与文件顺序一致;可以下拉配置其它的项目运行配置;
  • 运行剧本/脚本: 取决与当前的视图,如果视图处在“只显示脚本列”,为运行脚本,否则为运行性本。可以通过工具栏右侧的倒数第二个按钮切换视图;
  • 运行场景/步骤: 在剧本列中,每个场景右侧都有一个运行标志,可以只运行该场景;右键点击步骤也可以看到运行步骤的按钮,可以只运行当前步骤。但是项目仍然是正常加载的,只是其它场景/步骤不运行。

关闭CukeTest

如果在未保存模型文件的情况下退出CukeTest,则会自动保存。