我们马上要开始进行express的服务器demo的开发了,但是再此之前要先处理好版本控制以及质量保证

1版本控制

1.1 git的安装和使用

首先确保你已经安装了git,git --version

然后在项目目录中使用git init创建git的本地库,创建.gitignore将node_modules文件夹隔离

git add -A 将所有的文件加入git,git有一个暂存区,当使用add命令时,对于文件的修改就会被存放在该区域中

git commit -m “Commit Description” 命令进行一次提交

1.2 npm

npm可以理解为一个包管理器,他将项目所需的所有依赖保存在node_modules目录下,package.json这个文件中列出了全部的依赖项,就算你把node_modules删除了,只要有package.json文件,就可以通过npm install --save来恢复全部依赖。

package.json的另一个作用是存放项目的元数据,例如项目的名称、作者、授权信息等

1.3 node模块

node提供的是模块化的依赖封装机制,比如我们在使用express时,是调用

let express = require(‘express’)

来引入express模块

我们也可以自定义模块进行封装

在项目目录下创建 lib/fortune.js

let fortunes = ["末吉","小吉","中吉","大吉"]
exports.getFortune = function(){return fortunes[Math.floor(Math.random()*fortunes.length)]
}

服务器主程序中:

let fortune = require('./lib/fortune.js')//引入模块
//使用模块
app.get('/about*', function (req, res) {res.render('about',{fortune:fortune.getFortune()})
})

2 质量保证

web开发中的质量可以分为四个维度

  • 到达率:即产品的市场普及程度,到达率和盈利能力成正相关,从开发角度看搜索引擎的优化(SEO)对到达率影响最大
  • 功能:网站提供的业务和服务的质量
  • 可用性:可用性的评估方案很简单就是人机交互(HCI),也就是他易用吗
  • 审美:好看

2.1 测试相关

测试主要分为单元测试和集成测试,单元测试针对单个组件确保其功能正确,集成测试则是关注多个组件乃至整个系统之间的交互。

  • 页面测试:测试页面和前端的功能,使用Mocha框架进行测试
  • 跨页测试:从一个页面转到另一个页面的测试(集成测试)使用Zombie.js
  • 逻辑测试:对逻辑域(业务逻辑)进行单元和集成测试
  • 去毛:寻找潜在的错误,使用JSHint
  • 链接检查:确保你的网站上没有破损的链接

2.2 页面测试

  • 首先安装mocha dev表示这个包安装在开发依赖中,使当我们发布软件时这部分依赖不会被发布
npm install --save-dev mocha

我们在public下创建一个vendor(养成将第三方依赖或资源统一管理的习惯)

将node_modules中的mocha.js和css拷贝到vendor中

  • 测试需要assert(或expect)函数,Node框架中没有,我们安装Chai断言库
npm install --save-dev chai
cp node_modules/chai/chai.js public/vendor
  • 我们将localhost:3000?test=1这个url作为测试路由,在所有路由前添加一个中间件
//测试url
app.use(function (req, res, next) {res.locals.showTests = app.get('env') !== 'production' && req.query.test === '1';next()
})

先不详细阐述上述代码的作用,你需要知道的是如果test=1出现在任何查询字符串中,

res.locals.showTests会被设置为true,res.locals就是要传给视图上下文的第一部分

  • 接下来在views/layouts/main.handlebars中引入测试框架
<head><title>Meadowlark Travel</title>{{#if showTests}} //如果url中出现了test=1就开启mocha测试模式<link rel="stylesheet" href="/vendor/mocha.css">{{/if}}<script src="//code.jquery.com/jquery-2.0.2.min.js"></script>
</head><body>{{{body}}}{{#if showTests}}<div id="mocha"></div><script src="/vendor/mocha.js"></script><script src="/vendor/chai.js"></script><script>mocha.ui('tdd');//设置mocha的ui模式var assert = chai.assert;</script><script src='/qa/tests-global.js'></script>{{#if pageTestScript}}<script src="{{pageTestScript}}"></script>{{/if}}<script>mocha.run()</script>{{/if}}
</body>

注意这一行 <script src=’/qa/tests-global.js’></script>

这表示我们写了一个test-global.js文件作为全局测试,项目中所有的url都会通过这项测试

  • test-global.js
//全局测试
suite('Global Tests', function () {test('page has a valid title', function () {assert(document.title && /\S/.test(document.title) && document.title.toUpperCase() !== 'TODO')})
})

assert函数内的表达式如果为true即为测试通过,上述代码的意思是我们希望所有的页面title满足三个条件:

  1. 有值
  2. 有空格
  3. 不能是TODO大小写都不行

访问 /about?test=1 结果如下图,左下角为当前的测试列表,右上角为测试信息的统计

再做一个练习,我们希望在about页面上总是有一个指向contact us的链接

创建 public/qa/tests-about.js,这里使用jquery进行dom元素的提取

//about测试
suite('About Tests', function () {test('about page has the \'contact us\' link', function () {assert($('a[href="contact us"]').length);})
})

在主程序meadowlark.js中修改about路由的配置代码

//关于页路由
app.get('/about*', function (req, res) {res.render('about', {fortune: fortune.getFortune(),pageTestScript: '/qa/tests-about.js'})
})

由于我们在main.handlebars里面写了绑定测试js的代码(如下),所以可以通过动态绑定的方式给每个路由设置自己的测试程序

    {{#if pageTestScript}}<script src="{{pageTestScript}}"></script>{{/if}}

目前about页面中没有链接标签故报错

添加链接即可测试成功

<h1>About Meadowlark,here's the about page</h1>
<div><p>your fortune today:</p><div>{{fortune}}</div><a href="contact us">contact us</a>
</div>

2.3 跨页测试

例如你的网站上有一个包含联系表单的Request Group Rate页面,营销部门想知道 客户是从哪个页面点击链接进入 Request Group Rate 页面的,他们想知道客户是否在查看 胡德河之旅或者俄勒冈海岸退潮。首先设置好场景。

  1. 胡德湖之旅页面 view/tour/hood-river.handlebars
<h1>Hood River Tour</h1>
<a class="requestGroupRate" href="/tours/request-group-rate">Request Group Rate</a>
  1. 团队预订页面 request-group-rate.handlebars

    跨页测试的原理就是看document.referrer返回的是一个URL,当前页面就是从这个URL返回来的。

<h1>Request Group Rate</h1>
<form><input type="hidden" name="referrer">Name: <input type="text" id="fieldName" name='name'><br>Group size: <input type="text" name='groupSize'><br>Email: <input type="email" name="email"><br><input type="submit" value="Submit">
</form>
<script>//当 DOM(文档对象模型) 已经加载,并且页面(包括图像)已经完全呈现时,会发生 ready 事件。$(document).ready(function(){//将document中的referrer值赋给referrer这个input框$('input[name="referrer"]').val(document.referrer)})
</script>
  1. 在meadowlark.js中创建路由
//hood-river
app.get('/tour/hood-river',function(req,res){res.render('tour/hood-river')
})
app.get('/tour/request-group-rate',function(req,res){res.render('tour/request-group-rate')
})

简单添加了一些css后简单看下效果


  1. 添加测试部分

我们可以通过手动点击链接并输入内容来完成这一部分的测试但是这太麻烦了,本书中采用zombie这个轻量的无头浏览器(无头浏览器就是不显示页面只显示数据传送的那种浏览器),但是windows不支持zombie,故笔记中只简单描述步骤。

  • 首先npm安装zombie

  • 在项目目录下创建一个新的qa/tests-corsspage.js

var Browser = require('zombie'),assert = require('chai').assert;
var browser;
suite('Cross-Page Tests', function () {setup(function () {browser = new Browser();});test('requesting a group rate quote from the hood river tour page' +'should populate the referrer field', function (done) {var referrer = 'http://localhost:3000/tours/hood-river';browser.visit(referrer, function () {browser.clickLink('.requestGroupRate', function () {assert(browser.field('referrer').value=== referrer);done();});});});test('requesting a group rate from the oregon coast tour page should ' +'populate the referrer field', function (done) {var referrer = 'http://localhost:3000/tours/oregon-coast';browser.visit(referrer, function () {browser.clickLink('.requestGroupRate', function () {assert(browser.field('referrer').value === referrer);done();});});});test('visiting the "request group rate" page dirctly should result ' +'in an empty referrer field', function (done) {browser.visit('http://localhost:3000/tours/request-group-rate',function () {assert(browser.field('referrer').value === '');done();});});
})

setup函数每次测试框架运行时就会执行,每个test就是一个浏览器实例。第一个测试的是点击跳转到requestGroupRate页面的功能,第三个是测试直接访问requestGroupRate页面,第二个描述的页面还没写,所以第二个会出错

开启meadowlark服务node meadowlark.js,全局安装mocha npm install -g mocha

之后通过下面命令启动zombie

mocha -u tdd -R spec qa/tests-crosspage.js 2>/dev/null

spec 会提供更多的报告,2>/dev/null 会丢弃错误输出,Mocha 会报告失败测试的全部堆栈跟踪

2.4 逻辑测试

我们的程序中有一个自定义的模块,为了测试其功能,创建文件qa/tests-unit.js

自定义模块fortunes

let fortunes = ["末吉","小吉","中吉","大吉"]
exports.getFortune = function(){return fortunes[Math.floor(Math.random()*fortunes.length)]
}

测试js tests-unit.js

let fortune = require('../lib/fortune.js')
let expect =require('chai').expectsuite('Fortune cookie tests',function(){test('getFortune() should return a fortune',function(){expect(typeof fortune.getFortune ==='string')})
})

调用Mocha来运行这个测试集

mocha -u tdd -R spec qa/tests-unit.js

2.5 去毛

本书采用JSHint(windows还是用不了)

安装

npm install -g jshint

然后直接指定源文件名调用

jshint meadowlark.js

如果我们在meadowlark.js中添加了

if( app.thing == null ) console.log( 'bleat!' );

再次运行jshint,他就会提示你要使用===代替==并需要添加大括号

2.7 链接检查

本书采用了LinkChecker,是一个跨平台软件还有图形界面

启动meadowlark服务后,在软件中填写localhost:3000,结果如下

如果链接出错就会在空白区域表示,我们的about页面中包含一个contact us的a标签,测试about页面时,LinkChecker也会进行测试a标签链接是否可用

2.8 Grunt实现自动化

上面讲了一堆测试工具,如果实际开发中需要一个个去配置那将是较差的开发体验,grunt可以自动化完成QA工具链,为我们节省一些时间(然而windows还是用不了)

  1. 安装
sudo npm install -g grunt-cli
npm install --save-dev grunt

安装插件

npm install --save-dev grunt-cafe-mocha
npm install --save-dev grunt-contrib-jshint
npm install --save-dev grunt-exec
  1. 然后项目下创建Gruntfile.js
module.exports = function (grunt) {//加载grunt插件['grunt-cafe-mocha','grunt-contrib-jshint','grunt-exec',].forEach(task => {grunt.loadNpmTasks(task)})//配置插件grunt.initConfig({cafemocha:{all:{src:'qa/test-*.js',options:{ui:'tdd'}}},jshint:{app:['meadowlark.js','public/js/**/*.js','lib/**/*.js'],qa:['Gruntfile.js','public/qa/**/*.js','qa/**/*.js']},exec:{linkchecker:{cmd:'linkchecker http://localhost:3000'}}});//注册任务grunt.registerTask('default',['cafemocha','jshint','exec'])
}

cafemocha插件需要知道test.js文件在哪里,我们用它来进行跨页和逻辑测试

对于JSHint必须制定要对哪些js文件去毛,避开第三方文件和node_modules的依赖

通配符/**/是”子目录中全部文件“的意思

grunt-exec是用来运行LinkChecker的

接下来了启动服务并直接执行grunt,上述的测试都会执行

2.9 持续继承

node 中可用的持续集成服务器是Travis CI(http://about.travis-ci.org/docs/ user/getting-started),本书中并未进行详细介绍。
kchecker http://localhost:3000’
}
}
});

//注册任务
grunt.registerTask('default',['cafemocha','jshint','exec'])

}


cafemocha插件需要知道test.js文件在哪里,我们用它来进行跨页和逻辑测试对于JSHint必须制定要对哪些js文件去毛,避开第三方文件和node_modules的依赖通配符/**/是”子目录中全部文件“的意思grunt-exec是用来运行LinkChecker的接下来了启动服务并直接执行grunt,上述的测试都会执行### 2.9 持续继承node 中可用的持续集成服务器是Travis CI(http://about.travis-ci.org/docs/ user/getting-started),本书中并未进行详细介绍。

Node与Express学习笔记3_版本控制与质量保证相关推荐

  1. Node.js+mongodb 学习笔记(三)swagger注释+用户管理

    Node.js+mongodb 学习笔记(三)swagger注释+用户管理 Node.js+mongodb 学习笔记(三)swagger注释+用户管理 用户注册 用户登录 修改密码 swagger注释 ...

  2. node express 学习笔记

    转载于:https://www.cnblogs.com/wxdcjm/p/9124589.html

  3. Express学习笔记(基本使用,中间件,模块化路由,请求处理)

    express笔记 这里不再提及express的定义或者作用等. 1.安装 使用 npm install express (--save) 进行安装 2.基本使用 1)开启服务器 const expr ...

  4. Express学习笔记

    注:该笔记来自于视频Node.JS-黑马程序员 概述 express是高度封装了http的第三方框架. express官网:http://expressjs.com/ 只需要像安装其他包那样,直接执行 ...

  5. ROS学习笔记3_发布者Publisher

    通过程序实现发布海龟的速度指令,让海龟运动. 这个系统中,通过ROS Master来管理所有节点,其中主要节点有二,一者为订阅者节点,turtlesim海龟仿真器,一者为发布节点Turtle Velo ...

  6. 【Git\GitHub\GitLab学习笔记】版本控制 Git 视频教程全集(62P)| 6 小时从入门到精通(P27-P41)

    目录 P27-Git基本原理-Hash算法简介 P28-GIt版本数据管理机制 - P33-为了测试远程交互初始化本地库 P34-创建远程仓库 P35-在本地创建远程库地址别名 P40-协同开发时冲突 ...

  7. node child_process模块学习笔记

    NodeJs是一个单进程的语言,不能像Java那样可以创建多线程来并发执行.当然在大部分情况下,NodeJs是不需要并发执行的,因为它是事件驱动性永不阻塞.但单进程也有个问题就是不能充分利用CPU的多 ...

  8. Express学习笔记(八)—— 文件上传与下载

    文件上传 安装:npm install multer --save 导入 let multer=require('multer') let fs=require('fs') 初始化上传对象 // 配置 ...

  9. R语言学习笔记3_探索性/描述性数据分析

    目录 三.探索性/描述性数据分析 3.1 直方图与密度函数的估计 3.1.1 直方图 3.1.2 核密度估计 3.2 单组数据的描述性统计分析 3.2.1 单组数据的图形描述 直方图 hist( ) ...

  10. JVM学习笔记3_类加载器

    JVM类加载器分为四种: 根类加载器(Bootstrap ClassLoader): 加载 JRE/lib/rt.jar 或者 Xbootclasspath选项指定的jar包,由C++实现,不是Cla ...

最新文章

  1. Android异步下载网络图片(其三:ExecutorService)
  2. android 字符串相似度对比,Android中的OpenCV图像比较和相似度
  3. hbase映射为hive表(转载+整理+自己验证)
  4. 数字怎么横 竖排_从这些数字更深入了解打包箱房
  5. 页面监听,一段时间内不操作网页,就自动跳转到登录页
  6. 搜狗浏览器中如何删除自带工具 搜狗浏览器删除自带工具的方法步骤
  7. websocket java 例子_java 实现websocket的两种方式实例详解
  8. java 二叉排序_java实现二叉排序树
  9. atlas 200 远程图形化桌面
  10. 从C#中传递object到lua的一个问题
  11. pcl1.8.1在VS2017中编译遇到pop_t找不到标识符的问题的解决办法
  12. 频谱感知1:未知确定信号的能量检测
  13. fbx文件批量格式转换(glb/gltf)与压缩
  14. 优先队列优化迪杰斯特拉
  15. 使用pandas的merge出现Empty DataFrame 和 Index: []
  16. uni-app uni.request简单封装(请求头配置及response处理)
  17. Unity打包webgl文本框不显示汉字
  18. Bootstrap基本结构
  19. 【工业大数据】工厂大数据之数据源分析;如何挖掘并驾驭大数据的价值,成为“大数据企业”?
  20. zuul灰度发布功能实现

热门文章

  1. 关于海康威视网络摄像机二次开发问题
  2. 网络空间安全 渗透 攻防5(文件共享服务器)
  3. Matlab求解椭球上运动的点B,满足到定点A、C的距离之和最短
  4. 【IT精英】IT传奇人物比尔盖茨的故事
  5. 移动硬盘变成RAW怎么办?跟我这样恢复数据
  6. [每日一氵] TensorRT中 GA和EA的不同
  7. 随机存取存储器与只读存储器
  8. Meltdown(熔断漏洞)- Reading Kernel Memory from User Space/KASLR | 原文+中文翻译
  9. 照片删除格式化恢复后损坏的碎片重组修复数据恢复方法
  10. Mysql --分表、分库、分区(横向纵向、分区列)的区别与详解