上次博客介绍了如何调用接口准备测试数据,此次课程将学习如何通过操作数据库准备测试数据。为了完成此次课程目标拆分了2个task。
- 操作mysql数据库准备测试数据
- 操作sqlserver或者oracle数据库准备测试数据
接下来就开始第一个task吧。cypress框架自身没有封装操作数据库的方法,所以,为了连接数据库,并对数据进行增删改查,需安装相应的依赖包。例如,如果要连接mysql,首先执行“npm install mysql”命令安装mysql包,安装完成后即可引入该包完成数据库操作。
在编写js脚本实现操作数据库前,请先在本地安装好mysql server,创建名称为“test”的数据库并保证能正常连通数据库,数据库创建后,执行如下的语句创建数据库表。
CREATE TABLE IF NOT EXISTS `user`(
`id` INT UNSIGNED AUTO_INCREMENT,
`username` VARCHAR(100) NOT NULL,
`age` INTEGER NOT NULL,
`create_date` DATE,
PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
初始化table成功后,即可开始编写操作数据库的脚本了,具体代码如下所示,同样,执行"npm run select-db-data"即可运行下面的案例。
数据库操作部分拆分了2个js文件,第一个js文件负责存放数据库的连接信息,第二个js文件才真正负责数据的增删改查。以下是第一个js文件“init-db.js”。
const mysql = require('mysql');
//安装mysql包后,引入mysql,供后面使用
const connection = mysql.createConnection({
host: "localhost",
user: "root",
password: "root123456",
database: "test"
});
//固定写法,这里用户名和密码请填写你本机安装mysql时设置的用户名和密码
connection.connect(function (err) {
if (err) {
console.error('error connecting: ' + err.stack);
return;
}
console.log('connected as id ' + connection.threadId);
});
//创建数据库连接,调试时可以调用该方法先保证connection能正常创建
module.exports = {
connection: connection
};
//导出常量connection,供其他js文件使用
以下是第二个js文件“select-db-data.test.js”,具体代码如下所示
const db = require('./init-db');
// 引入上面的js文件,因为要使用init-db.js中的connection常量
function getUserDataByUserName(username) {
db.connection.query('select * from user where username=?', [username], function (error, results) {
//connnection.query('sql',[value],function(){})固定写法,sql语句中需要传参的地方用?,[]中输入要传入的参数值
if (error) throw error;
console.log(JSON.parse(JSON.stringify(results[0])).username);
//调用JSON.parse()将查询的结果转化为Json对象,这样就可以获取结果中任意字段的值,这里是获取查询结果中username字段的值
});
}
function addUser(username, age) {
db.connection.query('insert into user(username,age) values (?,?)', [username, age], function (error) {
//往表里面增加数据
if (error) {
throw error
}
})
}
function updateUserAge(username, age) {
db.connection.query(
{
sql: 'update user set age=? where username=?',
timeout: 3000,
values: [age, username]
// query()的另外一种写法,用json字符串方式传入query()中需要的sql,value等信息,这里还可以指定执行sql的超时时间
}, function (error, results) {
if (error) {
throw error
}
console.log('update ' + results.affectedRows + ' rows');
//这里还可以获取此次sql执行,影响的行数
console.log('changed ' + results.changedRows + ' rows');
//获取此次sql执行,被修改的行数,changedRows与affectedRows的区别是,只有某行数据确实被修改,changedRow数据才会增加
}
)
}
function closeConnection() {
db.connection.end();
//关闭数据库连接
}
getUserDataByUserName('zhangshan');
addUser("lisi", '20');
updateUserAge('lisi', 66);
closeConnection();
调用上面的方法,执行结果如下图所示,可以看到通过username正确获取到了用户信息以及成功添加和更新table中信息。执行结果如下图所示
如果安装mysql 8,在执行过程中可能会运行失败并提示“Client does not support authentication protocol requested by server”。报此错误的原因是Nodejs中最新的mysql模块(即安装的mysql包)并未完全支持MySQL 8的“caching_sha2_password”加密方式,而“caching_sha2_password”在MySQL 8中是默认的加密方式,故运行的时候会报错。解决办法是执行如下语句,显示指定使用“mysql_native_password”的加密方式。
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root123456';
// 注意这里替换成自己本机安装的用户名和密码
以上就是操作mysql数据库案例,更过关于nodejs中mysql包的使用可查看官方文档“ GitHub - mysqljs/mysql: A pure node.js JavaScript Client implementing the MySQL protocol. ”。 上面的脚本演示了在js文件中直接调用mysql包提供的方法完成数据的查询、修改操作。如果UI测试选择cypress作为测试框架,想在测试脚本中操作数据库,需要借助cypress框架插件功能。
Cypress框架支持插件功能,大部分情况下,UI层的测试脚本都运行在浏览器内,但cypress本身也是个node程序,通过插件可以进入到node的进程中,这个进程是运行在浏览器外的。项目初始化后,在代码根目录下会默认生成文件夹plugins,plugins下面默认有index.js文件。使用插件相关的代码都放到该目录的index.js文件中。下面脚本将操作数据库的脚本添加到task插件中。
const mysql = require('mysql');
//引入mysql包
module.exports = (on, config) => {
//固定写法,config指cypress.json中的配置信息
const con = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'root123456',
database: 'test'
});
on('task', {queryDBWithParameter(sql) {
//设置task的名字,以及task中真正执行的任务脚本
return new Promise((resolve, reject) => {
con.query(sql,function (err, result) {
if (err) {
reject(err)
} else {
return resolve(result)
}
})
})
}
});
};
//下面的脚本调用封装好的task,完成数据查询操作
function getUserDataByUserName() {
cy.task('queryDBWithParameter',"select * from user where username='zhangshan'")
//调用task:cy.task(taskName,parameter)
.then(result => {console.log(result)});
}
describe("control mysql database",()=> {
it("get user info by username", ()=> {
getUserDataByUserName()
});
});
//如果要使用cy对象提供的方法,必须将脚本放到it("xxxx",()=> {})中执行,因为cypress底层使用了mocha来运行测试脚本。
同样,Test Runner中选择“controlMysqlWithTask_spec.js”即可运行上面的脚本,运行过程中打开浏览器的console界面,可以看到打印了返回的result对象值,说明数据查询成功。
操作sqlserver或者oracle数据库准备测试数据
如果需要连接sqlserver或者oracle数据库,可以安装“cypress-sql-server”或者“cypress-oracle-db”。虽然是连接两种不同的数据库,但使用方式上是一致的,故这里以sqlserver为例介绍如何操作sqlserver,通过cypress-sql-server包操作sqlserver数据库数据需要5个步骤
- 1:执行命令“npm install cyperss-sql-server”安装此包
- 2: plugin目录下index.js文件中添加如下内容。
const sqlServer = require('cypress-sql-server');
module.exports = (on, config) => {
tasks = sqlServer.loadDBPlugin(config.db);
on('task', tasks);
}
- 3: cypress.json文件中添加数据库连接信息,上面脚本中的config对象获取的就是cypress.json文件中的内容。
"db": { "userName": "root", "password": "root123456", "server": "localhost", "options": { "database": "test", "encrypt": true, "rowCollectionOnRequestCompletion" : true } }
- 4: support目录下的index.js文件中,添加如下内容。
import sqlServer from 'cypress-sql-server'; sqlServer.loadDBCommands();
- 5: 调用封装的命令完成数据库查询操作
cy.sqlServer(`SELECT 'test').should('eq', 'test');
通过上面的步骤可以看出,cypress-sql-server包完成的事情是:先通过task插件封装连接数据库的脚本,然后再把cy.task('taskName')封装成cy的命令。另外,因为数据库操作都大同小异,故这里没有创建真实的sqlserver数据库进行数据增删该查。大家掌握思路即可,如果在实际项目中使用的是sqlserver或者oracle数据库,那么可以用上面的思路通过操作数据库准备测试数据。