Node.js 单元测试和集成测试
我目前正在开发一个nodejs/expressrestapi(个人项目),我想从这个项目中学到尽可能多的东西 因此,在我的项目中,我使用了Node.js 单元测试和集成测试,node.js,unit-testing,express,testing,mocha.js,Node.js,Unit Testing,Express,Testing,Mocha.js,我目前正在开发一个nodejs/expressrestapi(个人项目),我想从这个项目中学到尽可能多的东西 因此,在我的项目中,我使用了sequelize作为ORM层,我有一个名为'bus'的模型,我为这个模型构建了CRUD端点 现在我想对我开发的这个模型/api进行一些测试,我阅读了一些关于测试的教程,发现有多种类型的测试分为两大类:白盒和黑盒 因此,我编写了一些测试api的集成测试(集成测试是黑盒测试) 我想知道如何编写一些单元测试,但我不知道要测试什么,bus模型是一个Sequelize
sequelize
作为ORM
层,我有一个名为'bus'的模型,我为这个模型构建了CRUD端点
现在我想对我开发的这个模型/api进行一些测试,我阅读了一些关于测试的教程,发现有多种类型的测试分为两大类:白盒和黑盒
因此,我编写了一些测试api的集成测试(集成测试是黑盒测试)
我想知道如何编写一些单元测试,但我不知道要测试什么,bus
模型是一个Sequelize模型,所以我要测试的所有东西都已经在Sequelize
库中进行了测试。api端点的测试是通过集成测试完成的
PS:这是我第一次写测试
我正在使用以下技术:nodejs
,sequelize
,express
,mocha
,chai
公交车型号定义
const Sequelize = require('sequelize');
module.exports = function(sequelize) {
let Bus = sequelize.define('bus', {
name: {
type: Sequelize.STRING,
},
});
Bus.associate = function(models) {
Bus.hasOne(models.LaneBus, {
foreignKey: 'busId'
});
};
return Bus;
}
总线Api端点测试
const request = require('superagent');
const expect = require('chai').expect;
const app = require('../../src/app');
var http = require('http');
const models = require('../../src/models');
describe("bus", function () {
var bus_id;
it('should create bus', function (done) {
request.post('http://localhost:3000/bus')
.type('form')
.send({
name: 'bus_test_1',
}).set('Accept', 'application/json')
.set('Authorization', global.JWT_TOKEN_TEST_ADMIN)
.end((err, res) => {
expect(res.status).to.be.eq(201, 'invalid return code');
expect(res.body.status).to.be.eq('success', 'invalid retun status');
bus_id = res.body.id;
done();
})
});
it('should get list of bus', function (done) {
request.get('http://localhost:3000/bus')
.set('Accept', 'application/json')
.end((err, res) => {
expect(res.status).to.be.eq(200, 'invalid return code');
expect(res.body.metadata).to.not.be.undefined
done();
})
});
it('should modify bus', function (done) {
request.put(`http://localhost:3000/bus/${bus_id}`)
.type('form')
.send({
name: 'bus_test_2'
})
.set('Authorization', global.JWT_TOKEN_TEST_ADMIN)
.end((err, res) => {
expect(res.status).to.be.eq(200, 'invalid return code');
expect(res.body.status).to.be.eq('success', 'invalid retun status');
done();
});
});
it('modify bus should get error because bus dont exists', function (done) {
request.put(`http://localhost:3000/bus/aaa`)
.type('form')
.send({
name: 'bus_test_2'
})
.set('Authorization', global.JWT_TOKEN_TEST_ADMIN)
.end((err, res) => {
expect(res.status).to.be.eq(404, 'invalid return code');
expect(res.body.status).to.be.eq('failure', 'invalid return code');
done();
});
});
it('should get bus', function (done) {
request.get(`http://localhost:3000/bus/${bus_id}`)
.end((err, res) => {
expect(res.status).to.be.eq(200, 'invalid return code');
expect(res.body.name).to.be.eq('bus_test_2');
done();
});
});
it('get bus should return error because bus dont exist', function (done) {
request.get(`http://localhost:3000/bus/aaaa`)
.end((err, res) => {
expect(res.status).to.be.eq(404, 'invalid return code');
expect(res.body.status).to.be.eq('failure', 'invalid return code');
done();
});
});
it('user role cannot create bus', function (done) {
request.post('http://localhost:3000/bus')
.type('form')
.send({
name: 'bus_test_1',
}).set('Accept', 'application/json')
.set('Authorization', global.JWT_TOKEN_TEST_USER)
.end((err, res) => {
expect(res.body.status).to.be.eq('failure', 'invalid retun status');
done();
})
})
it('user role cannot modify bus', function (done) {
request.put(`http://localhost:3000/bus/${bus_id}`)
.type('form')
.send({
name: 'bus_test_2'
})
.set('Authorization', global.JWT_TOKEN_TEST_USER)
.end((err, res) => {
expect(res.body.status).to.be.eq('failure', 'invalid retun status');
done();
});
})
it('user role cannot delete bus', function (done) {
request.delete(`http://localhost:3000/bus/${bus_id}`)
.set('Authorization', global.JWT_TOKEN_TEST_USER)
.end((err, res) => {
expect(res.body.status).to.be.eq('failure', 'invalid return code');
done();
});
})
it('should delete bus', function (done) {
request.delete(`http://localhost:3000/bus/${bus_id}`)
.set('Authorization', global.JWT_TOKEN_TEST_ADMIN)
.end((err, res) => {
expect(res.status).to.be.eq(200, 'invalid return code');
done();
});
});
it('delete bus should get error because bus dont exist', function (done) {
request.delete(`http://localhost:3000/bus/${bus_id}`)
.set('Authorization', global.JWT_TOKEN_TEST_ADMIN)
.end((err, res) => {
expect(res.status).to.be.eq(404, 'invalid return code');
expect(res.body.status).to.be.eq('failure', 'invalid return code');
done();
});
});
});
不明确的需求/异常使代码难以测试。有时候,你只是不知道什么会破坏你的代码。这种情况在现实世界中经常发生。你不知道什么会破坏你的密码;否则,你就把它修好了 在任何情况下,我建议使用代码覆盖率进行测试,例如。确保您的代码至少经过80%的测试。稍后,当您更新代码或修复bug时,您可以看到哪些未被测试,并添加相应的测试
Feature: Simple maths
In order to do maths
As a developer
I want to increment variables
这些是我的建议,但请随便看看,选择您最喜欢的库进行测试。只需确保区分集成测试和单元测试 这就是我所做的:),我想知道一件简单的事情,如果一些函数/操作测试数据库连接或一些复杂的依赖关系,最好使用集成测试来测试它,对吗?单元测试用于简单的功能,理想情况下,通过单元测试,然后开始集成测试。在大型项目中,当需求和设计是可靠的(这需要时间),功能是直接的和可测试的时,就需要进行单元测试。1) 单元测试是关于应用程序的;2) 集成测试是关于系统的;3) 相比之下,集成测试需要花费更多的时间和资源。你在这里说的是用真正的数据库连接进行单元测试。当我们急于发布项目时,它变得越来越普遍。许多CI都支持它。不过,如果可能的话,我还是建议大家按照课本上的内容去做。这关乎质量和态度。