上次博客介绍了如何连接数据库准备测数据,此篇博客将介绍如何管理配置信息。为什么要管理配置信息呢?因为一套完善的自动化脚本肯定需要在多个测试环境中运行,不同环境的baseUrl、数据库连接等信息肯定不同,如果要实现在持续集成平台上通过环境变量就完成环境切换,那么必须把环境相关的配置信息在文件中管理起来。此篇博客中会给大家演示如何用json文件管理配置信息,为了完成此次课程目标分了2个task
- 根据环境变量值读取配置信息
- 整合数据准备和配置信息管理,完成一个完整的自动化测试场景
接下来就开始第一个task吧。
根据环境变量值读取配置信息
为了读取json文件中的内容,直接调用nodejs中fs模块即可,无需安装新的依赖包。同样,执行“npm run readJson”即可运行下面的案例。
假设存在dev和st两个测试环境,配置文件内容如下所示。
{
"active": "dev",
"dev": {
"baseUrl": "http://www.dev.com",
"db": {
"host": "localhost",
"username": "root",
"password": "root123456"
}
},
"st": {
"baseUrl": "http://www.st.com",
"db": {
"host": "localhost",
"username": "root",
"password": "root123456"
}
}
}
读取配置文件脚本如下所示
const fs = require('fs');
function getConfigs() {
const allConfigs = JSON.parse(fs.readFileSync('testdata/config.json'));
//调用fs模块读取文件内容,且这里使用同步读取的方法readFileSyn(),通常情况下,配置文件内容不会太多,所以这里使用同步调用应该不会造成用例运行时间太长
let activeEnv;
let configs = allConfigs.dev;
//默认使用dev环境下的配置信息
process.env['ACTIVE_ENV'] = 'st';
//调用process模块,指定环境变量,环境变量名称是“ACTIVE_ENV”,环境变量中指定环境值是“st”;process模块无需使用require()即可使用
process.env.ACTIVE_ENV ? activeEnv = process.env.ACTIVE_ENV : activeEnv = allConfigs.active;
//兼容处理,当存在环境变量时,优先读取环境变量中指定的环境值,如果环境变量不存在,则使用配置文件中指定的环境值
if (activeEnv == "dev") {
configs = allConfigs.dev
} else if (activeEnv == "st") {
configs = allConfigs.st
}
return configs
}
//以上是根据环境值,把配置文件中不同环境下的配置信息赋值给configs变量,后面需要使用配置信息时,调用该方法即可
console.log(getConfigs());
console.log(getConfigs().baseUrl);
执行上面的案例,当注释掉“process.env['ACTIVE_ENV'] = 'st';”,可以看到打印出的baseUrl是dev的baseUrl,说明可以根据环境变量读取不同的配置信息。在后续的章节中还会讲解如何在持续集成平台上例如jenkins上通过设置环境变量,模拟切换到不同环境上运行自动化案例。
可以看到配置信息的管理很简单,就是把环境相关的信息存放到json文件中,实现根据环境变量值或者配置文件中设置的环境值读取json文件中内容即可。上面讲解了如何读取json文件中内容,接下来我们把之前学过的数据准备和配置信息管理整合使用。
整合数据准备和配置信息管理,完成一个完整的自动化测试场景
还是以之前的“给帖子添加comment”为例,假设不同环境中可登陆使用的用户信息不同,创建帖子时输入的帖子名称、内容等信息不同环境下内容一致。测试脚本需要完成不同环境下数据准备工作,即不同环境下使用不同的用户登陆并完成“创建帖子”。
为了完成此脚本,testdata目录下,按环境名称创建dev和st目录,dev和st目录下创建userInfo.csv文件,userInfo里面存放登陆应用的用户信息。同样,执行“npm run add-comment-for-blog”即可运行如下案例。
首先看下代码的structure,example下包含case,config,testdata三个目录。
case里面又包含page和具体的测试脚本,真实项目case目录下应该按业务场景创建目录管理对应场景的脚本。演示的案例中目前只有一个场景所以case下面直接是page和测试案例脚本。page里面存放该场景所涉及的每个页面脚本,如果某些页面多个场景共用,那么该page需要放到common或者util的目录下管理。
config目录下管理配置文件信息,配置文件以及读取配置文件的脚本。
testdata目录管理测试数据,测试数据文件和准备测试数据。
另外,自动化测试中还需考虑一个点是测试案例分组运行,即testSuite划分,在UI层测试中testSuite划分比较简单,只需在package文件中用通配符配置即可,相同目录下的所有*.test.js都可以划分到一个testSuite中运行。
整合后的测试脚本代码如下所示,可以看到因为方法都包在了各个脚本中,这样测试案例的脚本就比较简洁,在实际项目中尽量做到看到方法名即可知道该方法具体要完成的内容,降低代码阅读成本。
const blogManage= require('../testdata/dataManage/blog-manage');
const loginPage = require('./page/loginPage');
const globalFeedPage=require('./page/globalFeedPage');
const blogEditPage=require('./page/blogEditPage');
//上面是包好的各个脚本,引入供测试案例脚本调用
describe("add comment test scenario", ()=> {
it("should favorite and add comment for blog successfully", async() => {
await blogManage.addBlogToPrepareTestData();
// 数据准备部分,调用接口创建一个帖子供后面的场景使用
await loginPage.loginWithUserData();
// 打开web应用并登陆,登陆的用户信息从userInfo文件中读取
await globalFeedPage.gotoGlobalFeed();
//登陆后切换到GlobalFeed界面
await globalFeedPage.favoriteBlog();
//将帖子设置为喜欢的帖子
await globalFeedPage.goToAddComment();
await blogEditPage.addComment('commentForUITest');
//给帖子添加comment
await blogEditPage.shouldAddCommentSuccessfully('commentForUITest');
//校验comment是否被成功添加
})
});
下面是截取部分脚本中包装的方法进行讲解,以下是准备测试数据部分的脚本,blog-manage.js
async function addBlog(username,password,title,content,desc) {
await getToken.getToken(username,password).then(token => {
const option = {
method: "POST",
uri: configsManage.getConfigs().apiBaseUrl+'api/articles/',
headers: {
"Content-Type": "application/json",
"Authorization": 'Token ' + token
},
body: {
"article": {
"tagList": [],
"title": title ,
"description": desc ,
"body": content
}
},
json: true
};
rp(option).then(function (parseBody) {
})
})
};
//上面是获取token,然后通过接口创建帖子,前面调用接口准备测试数据章节时已讲过,这里不再进行单独说明
async function addBlogToPrepareTestData() {
let filePath=configsManage.getConfigs().dataBasePath+'/common/blog-details.csv';
let blogData = await csvToJson().fromFile(filePath);
filePath=configsManage.getConfigs().dataBasePath+'st/userInfo.csv';
let userData=await csvToJson().fromFile(filePath);
await addBlog(userData[0].username,userData[0].password,blogData[0].title,blogData[0].content,blogData[0].desc)
}
//上面代码是读取userInfo和blog-details文件中的内容来创建帖子,另外,这里把测试数据文件的basePath也放到配置文件中管理,当需要修改时,只需修改配置文件即可
运行上述案例,可以看到运行成功,如下图所示。大家可以通过修改配置文件信息切换到不同环境进行运行,查看运行结果。另外,案例中userInfo不同环境中使用的是相同的内容,大家可以自行修改成不同的user,然后切换环境运行案例。
至此,本篇博客就结束了,此篇博客主要讲解了如何管理配置信息以及如何把数据准备和配置信息管理整合到自动化案例中,通过接口准备测试数据可以提高整个UI层测试脚本稳定性,通过管理配置信息可实现多环境切换运行。另外,需要注意一点,上面案例中只演示了通过接口准备测试数据,实际删除测试数据也可以通过调用接口完成,实现的思路和准备数据思路一致,这里不再做更多的介绍。下篇博客将学习如何从脚本层面提高UI层自动化测试稳定性。