基础
#
方法
TDD # Test-Driven Development
阶段
单元测试阶段
单元测试
集成测试阶段 # 出厂测试
冒烟测试 # 测主流程
功能测试
黑盒
灰盒 # 集成测试阶段,黑盒但关注程序内部
白盒
回归测试
系统测试阶段 # 第三方测试
验收测试阶段
性能测试 # PTS(Performance Testing Service)
压力测试 # 系统失效的负载点
常规模式 # 稳定并发
梯度模式 # 并发梯度递增
目标模式 # 并发梯度递增,达到预设指标(CPU、用户数、TPS、RT等)
负载测试 # 满足性能指标情况下,最大负载
疲劳强度测试 # 长时间执行最大工作量,保证持续业务量指标
基准测试 # 统计多少时间内执行了多少次某个方法
大数据量测试
独立测试 # 针对存储、传输、统计、查询测试
综合测试 # 大数据量下压测,负载,疲劳结合
全链路压测
灰度发布 # 金丝雀发布
A/B测试
蓝绿测试
前端测试
structure/behavior(数据结构/行为)问题
# 判断是否有此耦合,用一个测试验证: 是否为应用逻辑编写一个单元测试而不需要dom结构存在
## angular中没有这种问题,因为所有定位元素和处理事件的工作都是在angular内部完成的
## 在测试时创建dom,就增加了测试的复杂性。而且页面变化时有更多维护要做。访问dom的操作很慢,测试反馈时间长
数据库
#
sysbench
# mysql 压测
--db-driver=mysql --mysql-host=visitor-bench.ctysoosgzk4k.rds.cn-north-1.amazonaws.com.cn --mysql-user=root --mysql-password=12345678 --threads=512 --events=1000000 --time=0 --report-interval=15 ./bench_visit_page_insert.lua run
接口
#
jmeter
#
压测场景
HEAP="-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m"
jmeter -n -t [jmx file] -l [results file] -e -o [Path to web report folder]
loadrunner
#
脚本参数
get
web_url("login",
"URL=http://192.168.0.14:9081/ryx-login/sso/login",
"Resource=0",
"RecContentType=text/html",
"Referer=",
"Snapshot=t1.inf",
"Mode=HTML",
EXTRARES,
"Url=../ycls/img/banner1.jpg", ENDITEM,
"Url=../ycls/img/banner2.jpg", ENDITEM,
"Url=../ycls/img/banner3.jpg", ENDITEM,
"Url=../ycls/img/userinput.png", ENDITEM,
"Url=../ycls/img/sawtooth.png", ENDITEM,
"Url=../ycls/img/tip2.png", ENDITEM,
"Url=../ycls/img/pwdinput.png", ENDITEM,
"Url=../ycls/img/login_back.png", ENDITEM,
"Url=../ycls/img/tip1.png", ENDITEM,
"Url=../ycls/img/codeinput.png", ENDITEM,
"Url=../ycls/img/loading-small2.gif", ENDITEM,
"Url=/favicon.ico", "Referer=", ENDITEM,
LAST);
post参数
web_submit_data("getActivityParameter",
"Action=http://192.168.0.14:9081/tobacco/retail/lottery/getActivityParameter?jsonp=jQuery19109862107675272699_1401335732777",
"Method=POST",
"RecContentType=text/html",
"Referer=http://192.168.0.14:9081/tobacco/retail/index;jsessionid=7BBAFC6DE481FBCB1CB88D738BD7EE71",
"Snapshot=t6.inf",
"Mode=HTML",
ITEMDATA,
"Name=requestType", "Value=ajax", ENDITEM,
LAST);
post直接传数据
web_custom_request("dataservice",
"URL=http://202.110.222.207:7080/rtserver/rest/resource/tobacco/dataservice",
"Method=POST",
"Resource=0",
"RecContentType=text/plain",
"Referer=",
"Snapshot=t1.inf",
"Mode=HTML",
"Body= {\"trans_code\":\"1006\",\"end_date\":\"20140701\",\"source\":\"appkey\",\"data\":\"eyJiZWdpbl9kYXRlIjoiMjAxNDA2MDEiLCJlbmRfZGF0ZSI6IjIwMTQwNzAxIiwicG9zX2lkIjoiODg1MDAzMTAiLCJzb3VyY2UiOiJhcHBrZXkiLCJjdXN0b21lcl9pZCI6IjM3MDExMjEwNzQ2NyIsImFjY2Vzc190b2tlbiI6IiJ9\",\"begin_date\":\"20140601\",\"mac\":\"123\",\"pos_id\":\"88500310\",\"customer_id\":\"370112107467\",\"access_token\":\"\"}",
LAST);
phoenix
#
介绍
web自动化测试工具
特点
分布式执行
无脚本模式执行
无人值守模式执行
自定模式执行
模块
数据维护模块
部署模式
server-client
仅windows下可用
socket通信
web部署
server与client放到tomcat或webLogic下部署
http通信
web页面控制与监控client端执行
wireshark
siege
siege -c 200 -r 100 http://www.google.com
# 200并发,发送100次请求
tcpcopy
# 基于tcp packets的请求复制工具, 在线流量导入到测试系统中
ab
内网测试, apache自带的压力测试工具, 安装apache后在bin目录中找到
ab -n1000 -c100 http://www.google.com/a.html
# 100并发, 发送1000次请求
locust
# 外网性能测试
http_load
# 压测
http_load -rate 5 -seconds 10 http://www.baidu.com
# -p 并发
# -f 总计访问数
# -r 每秒访问频率
# -s 总计访问时间
yslow
# firefox插件,网页性能测试工具
gatling
# dsl脚本, 生成报表
wrk
# 压测
wrk -R5000 -d10s "http://internal-rope-api-1875734411.cn-north-1.elb.amazonaws.com.cn/online_agents/1"
swagger
# 文档与测试用例
fortio
# istio压测工具
hey
# http压测
js
#
heapdump
# 堆内存快照
jslint
supertest
# 测http接口
sinon.js
# 非运行测试,延时测试等
vows
# asynchronous BDD(behaviour drven development) for Node
chai
# js断言
mock.js
# 模拟生成接口假数据
benchmark
#
介绍
测试代码执行性能
使用
var Benchmark = require('benchmark');
var suite = new Benchmark.Suite;
var int1 = function(str){
return +str;
};
var int2 = function(str){
return parseInt(str, 10);
};
var int3 = function(str){
return Number(str);
};
// 开始测试
var number = '100';
suite
.add('+', function(){
int1(number);
});
.add('parseInt', function(){
int2(number);
});
.add('Number', function(){
int3(number);
});
.on('cycle', function(event){ // 每个测试跑完后输出信息
console.log(String(event.target));
})
.on('complete', function(){
console.log('Fastest is' + this.filter('fastest').pluck('name'));
})
.run({'async': true}); // 这里async与时间计算有关,默认为true
travis
#
介绍
项目node版本测试,在基本依赖下跑
使用
在travis上授权仓库,每当push代码到github, 会自动跑测试
配置根目录下的.travis.yml文件来配置测试内容,如
language: node_js
node_js:
-'0.8'
-'0.10'
-'0.11'
script: make test
services:
mongodb
# 一个使用了mongodb的nodejs应用,用0.8、0.10、0.11三个版本来跑,跑测试的命令是make test
travis测试的项目,可以得到一个图片地址,显示项目当前的测试通过状态,把这个图片添加到项目的README中
jasmine
#
介绍
编写单元测试
使用
describe("A suite", function(){
var foo;
beforeEach(function(){
foo = 0;
foo += 1;
});
afterEach(function(){
foo = 0;
});
it("contains spec with an expectation", function(){
expect(true).toBe(true);
});
});
should
#
介绍
兼容性测试
安装
npm install should --save-dev
使用
var should = require('should');
user.should.have.property('name', 'jack')
# should(user).have.property('name','jack');
user.should.have.property('pets').with.lengthOf(4);
# 判断数组
should.not.exist(err);
should.exist(result);
result.bar.should.equal(foo);
(5).should.be.exactly(5).and.be.a.Number();
user.should.be.an.instanceOf(Object).and.have.property('name', 'jack');
this.obj.should.have.property('id').which.is.a.Number();
memwatch
#
介绍
监控内存leak, stats,leak在连续5次垃圾回收后内存没释放时触发, stats事件在垃圾回收时触发
o-> 堆内存比较
var memwatch = require('memwatch')
var leakArray = []
var leak = function () {
leakArray.push('leak' + Math.random())
}
var hd = new memwatch.HeapDiff()
for (var i = 0; i < 10000; i++) {
leak()
}
var diff = hd.end()
console.log(JSON.stringify(diff, null, 2))
muk
#
var muk = require('muk')
before(function () {
muk(fs, 'readFileSync', function (path, encoding) {
throw new Error('mock readFileSync error')
})
muk(fs, 'readFile', function (path, encoding, callback) {
process.nextTick(function () {
# 模拟异步
callback(new Error('mock readFile error'))
})
})
})
after(function () {
muk.restore()
})
rewire
#
介绍
测试私有方法
o->
it('limit should return success', function () {
var lib = rewire('../lib/index.js')
var litmit = lib.__get__('limit')
litmit(10).should.be.equal(10)
})
mocha
#
介绍
单元测试框架
命令
mocha
# --reporters 查看所有报告样式, 默认dot, 常用spec, json, html-cov
# -R <reporter>采用某报告样式
# -t <ms>设置超时时间
使用
npm install -g mocha
// package.json
{
"scripts": {
"test": "mocha test"
"blanket": {
"pattern": "//^((?!(node_modules|test)).)*$/",
"data-cover-flags": {
"debug": false
}
}
}
}
mocha test
o-> bdd风格
describe('Array', function() {
before(function() {})
# 钩子函数还有after, beforeEach, afterEach
it('should return -1 when not present', function (done) {
[1,2,3].indexOf(4).should.equal(-1)
this.timeout(500)
# 500ms后超时
done()
# 用done来测试异步
})
})
o-> bdd风格
suite('Array', function() {
setup(function () {})
# 钩子函数还有teardown
suite('$indexOf()', function () {
test('should return -1 when not present', function() {
assert.equal(-1, [1,2,3].indexOf(4))
})
})
})
istanbul
#
介绍
名字是依斯坦布尔,用来白盒覆盖用例测试
支持的use cases有unit tests, browser tests, server side code embedding
使用
instanbul cover test.js
phantomjs
#
介绍
前端测试工具
webkit js测试工具,支持多web标准, dom, css, json, canvas和svg
o-> 使用1
npm install mocha-phantomjs
mocha-phantomjs index.html
o-> 使用2
phantomjs hello.js
// hello.js
console.log('Hello, world');
phantom.exit();
browserstack
#
介绍
前端测试工具
内建webdriver的api
使用
npm install browserstack-runner --save-dev
./node_modules/.bin/browserstack-runner init
// browserstack.json
"test_framework": "mocha",
"timeout": 60,
"test_path": "public/index.html"
https://www.browserstack.com/accounts/automate
得到username 和 access key
复制到browserstack.json中的username和key
browserstack-runner
https://www.browserstack.com/automate 查看结果
karma
#
介绍
是google Testacular的新名字,自动化完成单元测试
使用
npm install -g karma
karma start
karma init
# 初始化karma配置文件
npm install karma-jasmine
jscover
#
介绍
覆盖率测试
使用
npm install jscover -g
jscover lib lib-cov
# 把lib下的源码编译到lib-cov下,新代码在每一行加上了执行次数统计
index.js中
module.exports = process.env.LIB_COV ? require('./lib-cov/index') : require('./lib/index')
export LIB_COV=1
mocha -R html-cov > coverage.html
# 生成结果
blanket
#
介绍
比jscover更好的测试工具
使用
package.json中
"scripts": {
"blanket": {
"pattern": "eventproxy/lib"
# 要测试的源码目录
}
}
mocha --require blanket -R html-cov > coverage.html
python
#
nose
# 注解测试
selenium
# 自动化测试
go
#
gomock
# 官方mock库, 对接口mock
monkey
#
介绍
对函数mock
Patch()
Unpatch()
PatchInstanceMethod()
UnpatchInstanceMethod()
问题
内联函数不能mock
测试时禁止内联, go test -gcflags=all="-N -l"
java
#
hamcrest
#
# 自然语法
mockito
#
页面
#
jsperf
# js性能分析
jasmine
# js单元测试
移动
#
robotium
# android自动化测试