学习了MOCHA官网的示例,将学习成果记录一下。【原文+例子:使用mocha测试

mocha是什么

Mocha是一个跑在node和浏览器上的javascript测试框架,让异步测试变得简单有趣, 并提供灵活精确的报告。

安装

使用npm全局安装

$ npm install --global mocha

作为项目开发依赖安装

$ npm install --save-dev mocha

开始

创建测试文件learn-mocha

$ npm install mocha -g // 全局安装mocha
$ mkdir test // 创建test文件夹
$ touch test.js // 创建test文件

例子

var assert = require('assert');
describe('Array', function() {
describe('#indexOf()', function() {
it('should return -1 when the value is not present', function() {
assert.equal([1,2,3].indexOf(4), -1);
});
});
});

例子中使用了测试集定义函数describe()和测试用例定义函数it(),先引入nodeassert模块的eaual()方法用来验证两数是否相等:[1,2,3].indexOf(4) == -1

learn-mocha git:(master) ✗ mocha

  Array
#indexOf()
✓ should return -1 when the value is not present 1 passing (7ms)

在终端输入mocha,可以看到测试用例通过了。

Mocha的执行会找到当前命令执行目录下的test目录。./test/*.jsMocha寻找的目标。 也可以在package.json中设置如下设置,就可以使用npm test命令行开启Mocha测试

"scripts": {
"test": "mocha"
}

断言ASSERTIONS

Mocha支持各种断言库来验证功能,例如should.js、chai、expect.js、better-assert、unexpected等

异步模式

在mocha中测试异步代码并不容易。通过给it()加一个回调函数(通常命名为done),mocha将会知道异步代码执行之后需要调用done来表示测试完成。

describe('User', function() {
describe('#save()', function() {
it('should save without error', function(done) {
var user = new User('Luna');
user.save(function(err) {
if (err) done(err);
else done();
});
});
});
});

当done()可以接受异步代码错误的时候,上面代码还可以简化为

describe('User', function() {
describe('#save()', function() {
it('should save without error', function(done) {
var user = new User('Luna');
user.save(done);
});
});
});

使用PROMISES

除了使用回调函数done(), 你还可以返回Promise

beforeEach(function() {
return db.clear()
.then(function() {
return db.save([tobi, loki, jane]);
});
}); describe('#find()', function() {
it('respond with matching records', function() {
return db.find({ type: 'User' }).should.eventually.have.length(3);
});
});

使用async/await

如果js环境支持 async/await, 你可以这样写异步测试

beforeEach(async function() {
await db.clear();
await db.save([tobi, loki, jane]);
}); describe('#find()', function() {
it('responds with matching records', async function() {
const users = await db.find({ type: 'User' });
users.should.have.length(3);
});
});

同步模式

当测试同步代码时,mocha会自动的执行下一个测试用例

describe('Array', function() {
describe('#indexOf()', function() {
it('should return -1 when the value is not present', function() {
[1,2,3].indexOf(5).should.equal(-1);
[1,2,3].indexOf(0).should.equal(-1);
});
});
});

箭头函数

不建议在mocha中使用箭头函数,因为箭头函数对this的绑定会使测试用例无法访问Mocha上下文中的一些方法。

describe('my suite', () => {
it('my test with arrow function', () => {
// should set the timeout of this test to 1000 ms; instead will fail
this.timeout(1000);
assert.ok(true);
});
}); describe('my suite', function () {
it('my test without arrow function', function() {
// set the timeout of this test to 1000 ms; passing
this.timeout(1000);
assert.ok(true);
});
});

HOOKS

Mocha提供了四种hooks用来做测试准备和测后清理工作

  • before() 在所有测试套件运行之前运行
  • after() 在所有测试套件运行之后运行
  • beforeEach() 在每个测试用例运行之前运行
  • afterEach() 在每个测试用例运行之后运行
var assert = require('assert');
describe('hooks', function() { before(function() {
console.log('runs before all tests in this block')
}); after(function() {
console.log('runs after all tests in this block')
}); beforeEach(function() {
console.log('runs before each test in this block')
}); afterEach(function() {
console.log('runs after each test in this block')
}); it('test 1', function(){
assert.ok(true)
}) it('test 2', function(){
assert.ok(true)
}) });
➜  learn-mocha git:(master) ✗ mocha test/hooks.js

  hooks
runs before all tests in this block
runs before each test in this block
✓ test 1
runs after each test in this block
runs before each test in this block
✓ test 2
runs after each test in this block
runs after all tests in this block 2 passing (8ms)

描述HOOKS

任何钩子在回调前都有一个可选的描述,在测试中能更简单定位到错误。如果一个钩子是命名函数,在没有描述时,将会使用函数名。

beforeEach(function() {
// beforeEach hook
}); beforeEach(function namedFun() {
// beforeEach:namedFun
}); beforeEach('some description', function() {
// beforeEach:some description
});

异步HOOKS

所有hooks(before(), after(), beforeEach(), afterEach()) 都有可能是同步或者异步,就像一个常规的测试。例如,您可能希望在每个测试之前填充虚拟内容的数据库:

describe('Connection', function() {
var db = new Connection,
tobi = new User('tobi'),
loki = new User('loki'),
jane = new User('jane'); beforeEach(function(done) {
db.clear(function(err) {
if (err) return done(err);
db.save([tobi, loki, jane], done);
});
}); describe('#find()', function() {
it('respond with matching records', function(done) {
db.find({type: 'User'}, function(err, res) {
if (err) return done(err);
res.should.have.length(3);
done();
});
});
});
});

延迟根suite

如果你需要在所有suites运行之前执行异步操作,你可能会延迟根suite。用--delay运行mocha。这将把一个特殊的回调函数,run()附加到全局上下文中:

setTimeout(function() {
// do some setup describe('my suite', function() {
// ...
}); run();
}, 5000);

待定测试(PENDING TESTS)

待定测试将包括在测试结果中,并且标记为pending。未决测试不被认为是失败的测试。不添加回调函数callback即可。

  describe('#indexOf()', function() {
// pending test below
it('should return -1 when the value is not present');
});
});
learn-mocha git:(master) ✗ mocha test/pending.js

  Array
#indexOf()
- should return -1 when the value is not present 0 passing (5ms)
1 pending

it()中没有回调函数,就会显示 0 passing 1 pending

独有测试(EXCLUSIVE TESTS)

可以通过添加.only()describe()it()函数中,来指定测试套件。测试套件和测试用例可以多次定义。如果在测试套件和测试用例同时都加上了.only()的时候,测试用例的执行是优先的。例如suite 2中,只执行了test case 5

const assert = require('assert')

describe('suite 1', function () {

  describe('sub suite 1', function () {

    it('test case 1', function () {
assert(true)
}) it('test case 2', function () {
assert(true)
})
}) describe.only('sub suite 2', function () { it('test case 3', function () {
assert(true)
})
})
}) describe.only('suite 2', function () {
it('test case 4', function () {
assert(true)
}) it.only('test case 5', function () {
assert(true)
})
})
➜  learn-mocha git:(master) ✗ mocha test/exclusive.js

  suite 1
sub suite 2
✓ test case 3 suite 2
✓ test case 5 2 passing (7ms) (5ms)

跳过测试(INCLUSIVE TESTS)

与 .only() 相反,通过给describe()it()加上.skip(), mocha 会忽略这些测试套件或者测试用例。这些被跳过的测试都会被标记为pending

const assert = require('assert')

describe('suite 1', function () {

  describe('sub suite 1', function () {

    it('test case 1', function () {
assert(true)
}) it('test case 2', function () {
assert(true)
})
}) describe.skip('sub suite 2', function () { it('test case 3', function () {
assert(true)
})
})
}) describe.skip('suite 2', function () {
it('test case 4', function () {
assert(true)
}) it.skip('test case 5', function () {
assert(true)
})
}) let checkTestEnviroment = false
describe('suite 3', function () {
it('test case 6', function () {
if (checkTestEnviroment) {
assert(true)
} else {
this.skip()
}
}) it('test case 7', function () {
assert(true)
})
})

从执行结果来看,test case 3 和 suite 2 和 test case 6 套件都进入了 pending 待定状态。 test case 3 是因为测试用例 it.skip 。 suite 2 是因为测试套件 describe.skip 。 test case 6 是因为使用了 this.skip() ,模拟环境 checkTestEnviroment 有问题,需要跳过测试,最后跳过的测试会被标记为 pending 。

➜  learn-mocha git:(master) ✗ mocha test/inclusive.js

  suite 1
sub suite 1
✓ test case 1
✓ test case 2
sub suite 2
- test case 3 suite 2
- test case 4
- test case 5 suite 3
- test case 6
✓ test case 7 3 passing (9ms)
4 pending

使用 .skip() 是比注释更好的能够不执行指定测试的方法。

重跑测试(RETRY TESTS)

可以选择 this.retries(number) 来重新执行失败的测试到一定的次数。这个函数是为了处理资源不容易被模拟和截断的 end-to-end 测试而设计的,所以不推荐在单元测试里使用。

this.retries(number) 作用在 beforeEach/afterEach hooks中,但是不作用在 before/after hooks中。

describe('retries', function() {
// Retry all tests in this suite up to 4 times
this.retries(4); beforeEach(function () {
browser.get('http://www.yahoo.com');
}); it('should succeed on the 3rd try', function () {
// Specify this test to only retry up to 2 times
this.retries(2);
expect($('.foo').isDisplayed()).to.eventually.be.true;
});
});

动态生成测试(DYNAMICALLY GENERATING TESTS)

mocha 使用 Function.prototype.call 和函数表达式来定义测试套件和测试用例,这样能简单动态的生成测试用例。不需要特别的语法,只需 javascirpt 就能实现类似参数化测试的功能。

var assert = require('chai').assert;

function add() {
return Array.prototype.slice.call(arguments).reduce(function(prev, curr) {
return prev + curr;
}, 0);
} describe('add()', function() {
var tests = [
{args: [1, 2], expected: 3},
{args: [1, 2, 3], expected: 6},
{args: [1, 2, 3, 4], expected: 10}
]; tests.forEach(function(test) {
it('correctly adds ' + test.args.length + ' args', function() {
var res = add.apply(null, test.args);
assert.equal(res, test.expected);
});
});
});
➜  learn-mocha git:(master) ✗ mocha test/dynamically-generate.js

  add()
✓ correctly adds 2 args
✓ correctly adds 3 args
✓ correctly adds 4 args 3 passing (11ms)

测试持续时间(TEST DURATION)

在许多测试报告里会显示测试时间,当测试时间过长,会被特殊标记出来。可以使用 slow() 方法,来定义被认为 slow 的测试时间长度。

describe('something slow', function() {
this.slow(10000); it('should take long enough for me to go make a sandwich', function() {
// ...
});
});

测试超时(TIMEOUTS)

套件级别(SUITE-LEVEL)

在套件级别describe()定义this.timeout(numer),将会被运用于该套件下的所有嵌套套件和测试用例。

describe('a suite of tests', function() {
this.timeout(500); it('should take less than 500ms', function(done){
setTimeout(done, 300);
}); it('should take less than 500ms as well', function(done){
setTimeout(done, 250);
});
})

上面的代码定义了超时时间是500ms,然后测试执行时间都没有超过,所以测试可以通过

➜  learn-mocha git:(master) ✗ mocha test/timeouts/suite-level.js

  a suite of tests
✓ should take less than 500ms (306ms)
✓ should take less than 500ms as well (251ms) 2 passing (564ms)

如果把时间从this.timeout(500)改成this.timeout(300),,就会的到超时错误

➜  learn-mocha git:(master) ✗ mocha test/timeouts/suite-level.js

  a suite of tests
1) should take less than 300ms
✓ should take less than300ms as well (253ms) 1 passing (569ms)
1 failing 1) a suite of tests
should take less than 300ms:
Error: Timeout of 300ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (/blog/learn-mocha/test/timeouts/suite-level.js)

用例级别

在测试级别it()中使用方法也差不多。在it()中使用this.timeout(0)可以重载/消除测试套件定义的超时时间。

it('should take less than 500ms', function(done){
this.timeout(500);
setTimeout(done, 300);
});
➜  learn-mocha git:(master) ✗ mocha test/timeouts/test-level.js

  ✓ should take less than 500ms (302ms)

  1 passing (308ms)

钩子级别(HOOK-LEVEL)

在钩子级别HOOK-LEVEL中使用方法也差不多。使用this.timeout(0)也可以s禁用hook的超时。

describe('a suite of tests', function() {
beforeEach(function(done) {
this.timeout(3000); // A very long environment setup.
setTimeout(done, 2500);
}); it('it', function(done) {
setTimeout(done, 20);
})
});
➜  learn-mocha git:(master) ✗ mocha test/timeouts/hook-level.js

  a suite of tests
✓ it 1 passing (3s)

DIFFS

mocha支持来自断言库的有err.expected 和 err.actual 实际属性的任何AssertionErrors错误 。mocha将自动显示预期和实际之间的差异。下面是一个“字符串”差异的例子:

const assert = require('assert')

describe('suite 1', function () {
it('test case 1', function () {
assert.equal(-1, [1, 2, 3].indexOf(4))
}) it('test case 2', function () {
assert.equal('test', [1, 2, 3].toString())
})
})
➜  learn-mocha git:(master) ✗ mocha test/diffs.js

  suite 1
✓ test case 1
1) test case 2 1 passing (9ms)
1 failing 1) suite 1
test case 2: AssertionError [ERR_ASSERTION]: 'test' == '1,2,3'
+ expected - actual -test
+1,2,3 at Context.<anonymous> (test/diffs.js:9:12)

使用命令(USAGE)

➜  learn-mocha git:(master) ✗ mocha --help

  Usage: mocha [debug] [options] [files]

  Options:

    -V, --version                           output the version number
-A, --async-only force all tests to take a callback (async) or return a promise
-c, --colors force enabling of colors
-C, --no-colors force disabling of colors
-G, --growl enable growl notification support
-O, --reporter-options <k=v,k2=v2,...> reporter-specific options
-R, --reporter <name> specify the reporter to use (default: spec)
-S, --sort sort test files
-b, --bail bail after first test failure
-d, --debug enable node's debugger, synonym for node --debug
-g, --grep <pattern> only run tests matching <pattern>
-f, --fgrep <string> only run tests containing <string>
-gc, --expose-gc expose gc extension
-i, --invert inverts --grep and --fgrep matches
-r, --require <name> require the given module
-s, --slow <ms> "slow" test threshold in milliseconds [75]
-t, --timeout <ms> set test-case timeout in milliseconds [2000]
-u, --ui <name> specify user-interface (bdd|tdd|qunit|exports) (default: bdd)
-w, --watch watch files for changes
--check-leaks check for global variable leaks
--full-trace display the full stack trace
--compilers <ext>:<module>,... use the given module(s) to compile files (default: )
--debug-brk enable node's debugger breaking on the first line
--globals <names> allow the given comma-delimited global [names] (default: )
--es_staging enable all staged features
--harmony<_classes,_generators,...> all node --harmony* flags are available
--preserve-symlinks Instructs the module loader to preserve symbolic links whenresolving and caching modules
--icu-data-dir include ICU data
--inline-diffs display actual/expected differences inline within each string
--no-diff do not show a diff on failure
--inspect activate devtools in chrome
--inspect-brk activate devtools in chrome and break on the first line
--interfaces display available interfaces
--no-deprecation silence deprecation warnings
--exit force shutdown of the event loop after test run: mocha willcall process.exit
--no-timeouts disables timeouts, given implicitly with --debug
--no-warnings silence all node process warnings
--opts <path> specify opts path (default: test/mocha.opts)
--perf-basic-prof enable perf linux profiler (basic support)
--napi-modules enable experimental NAPI modules
--prof log statistical profiling information
--log-timer-events Time events including external callbacks
--recursive include sub directories
--reporters display available reporters
--retries <times> set numbers of time to retry a failed test case
--throw-deprecation throw an exception anytime a deprecated function is used
--trace trace function calls
--trace-deprecation show stack traces on deprecations
--trace-warnings show stack traces on node process warnings
--use_strict enforce strict mode
--watch-extensions <ext>,... additional extensions to monitor with --watch (default: js)
--delay wait for async suite definition
--allow-uncaught enable uncaught errors to propagate
--forbid-only causes test marked with only to fail the suite
--forbid-pending causes pending tests and test marked with skip to fail the suite
--file <file> include a file to be ran during the suite (default: )
--exclude <file> a file or glob pattern to ignore (default: )
-h, --help output usage information Commands: init <path> initialize a client-side mocha setup at <path>

解释几个常用的选项

  • -V, --version 版本号
  • -b, --bail 只对第一个抛出异常处理
  • -d, --debug 开启node的debug模式,对标记了debugger语句的代码进行调试
  • -t, --timeout <ms>指定测试用例的超时时间。默认是2000毫秒。
  • -w, --watch 用来监测测试文件的变化
  • -s, --slow <ms> 指定测试用例执行时间为慢的阈值。默认是75毫秒。

接口(INTERFACES)

mocha 的接口系统允许开发人员选择自己的DSL风格。mocha 拥有 BDDTDDExportsQUnit 和 Require风格的接口。

BDD

BDD 接口 提供 describe()context()it()specify()before()after()beforeEach()afterEach()。 describe() = context()it() = specify() 前面的例子都是用的 BDD 接口。

describe('Array', function() {
before(function() {
// ...
}); describe('#indexOf()', function() {
context('when not present', function() {
it('should not throw an error', function() {
(function() {
[1,2,3].indexOf(4);
}).should.not.throw();
});
it('should return -1', function() {
[1,2,3].indexOf(4).should.equal(-1);
});
});
context('when present', function() {
it('should return the index where the element first appears in the array', function() {
[1,2,3].indexOf(3).should.equal(2);
});
});
});
});

TDD

提供 suite()test()suiteSetup()suiteTeardown()setup()teardown()

suite('Array', function() {
setup(function() {
// ...
}); suite('#indexOf()', function() {
test('should return -1 when not present', function() {
assert.equal(-1, [1,2,3].indexOf(4));
});
});
});

EXPORTS

类似于 mocha 前身 expresso。关键字 beforeafterbeforeEachafterEach 是special-cased。 测试套件是对象,函数是测试用例。

module.exports = {
before: function() {
// ...
}, 'Array': {
'#indexOf()': {
'should return -1 when not present': function() {
[1,2,3].indexOf(4).should.equal(-1);
}
}
}
};

QUNIT

类似QUnit。测试套件单独定义在测试用例之前,像TDD一样支持suite()和test(),像BDD一样支持hooks。同样包括before()after()beforeEach()afterEach()

unction ok(expr, msg) {
if (!expr) throw new Error(msg);
} suite('Array'); test('#length', function() {
var arr = [1,2,3];
ok(arr.length == 3);
}); test('#indexOf()', function() {
var arr = [1,2,3];
ok(arr.indexOf(1) == 0);
ok(arr.indexOf(2) == 1);
ok(arr.indexOf(3) == 2);
}); suite('String'); test('#length', function() {
ok('foo'.length == 3);
});

REQUIRE

允许通过require()来导入describe()it()的方法。可以自己定义别名。注意:只能用mocha命令执行,node不行。

var testCase = require('mocha').describe;
var pre = require('mocha').before;
var assertions = require('mocha').it;
var assert = require('chai').assert; testCase('Array', function() {
pre(function() {
// ...
}); testCase('#indexOf()', function() {
assertions('should return -1 when not present', function() {
assert.equal([1,2,3].indexOf(4), -1);
});
});
});

报告(REPORTERS)

Mocha提供了多种console端报告模式

  • mocha --reporter spec 这是默认模式。是一个按照测试套件和用例分层次的视图
  • mocha --reporter dot 显示一个由点组成的矩阵。点的颜色代表着不同的测试结果
  • mocha --reporter nyan 显示了一个图。。。。。
  • mocha --reporter tap 基于Test Anything Protocol (TAP)
  • mocha --reporter landing 模拟飞机降落
  • mocha --reporter list 以列表的形式显示每一个测试用例
  • mocha --reporter progress 以进度条的形式显示
  • mocha --reporter json 输出json格式的报告
  • mocha --reporter min 只输出summary。可以与mocha -w一起使用
  • mocha --reporter doc 输出HTML格式的报告
  • mocha --reporter markdown 输出HTML格式的报告

参照链接:

使用mocha测试的更多相关文章

  1. 添加 node mocha 测试模块

    1.mocha  支持TDD 和 BDD两种测试风格 2.引用assert模块  此模块是node的原生模块,实现断言的功能,作用是声明预期的结果必须满足 3.mocha测试用例中可以使用第三方测试库 ...

  2. mocha测试框架-truffle

    https://mochajs.org/
学习网址:
https://www.jianshu.com/p/9c78548caffa
https://www.jb51.net/article/10646 ...

  3. mocha测试接口类型及测试报告收集

    记录参考: 参考文档: 测试报告以及es6: http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html 测试接口 ...

  4. Nodejs Mocha测试学习

    参考大神阮一峰的文章<测试框架 Mocha 实例教程> 目前在使用Nodejs,但写完的程序很容易出错,那怎么办?需要引入单元测试去做基础的测试 目前Nodejs用来做单元测试的工具接触的 ...

  5. mocha测试es6问题

    平时在写完正常的逻辑代码后,需要使用单元测试去测试逻辑代码,现在比较流行的是使用mocha进行测试 现在都是使用es6的写法,如果直接使用mocha test\某个文件,会出现下面的错误,原因是因为m ...

  6. Mocha测试框架,保证代码质量

    mocha mocha是JavaScript的一种单元测试框架,既可以在浏览器环境下运行,也可以在Node.js环境下运行. 使用mocha,我们就只需要专注于编写单元测试本身,然后,让mocha去自 ...

  7. 从零开始使用mocha测试

    mocha 需要在node环境下跑,请确保已经安装了node   1.新建一个文件夹 test   2.命令行切换到test目录下,执行命令:npm init ,出现选择按enter,一系列选择完成之 ...

  8. Mocha测试

    mocha中文名叫做摩卡,是javascript测试的一种常见手段. 其他的类似的测试还有jasmine.karma.tape等. 1. 测试脚本怎么写 // add.js function add( ...

  9. mocha测试框架

    中文翻译文档:https://www.jianshu.com/p/9c78548caffa 阮一峰:http://www.ruanyifeng.com/blog/2015/12/a-mocha-tut ...

随机推荐

  1. UVA 1400."Ray, Pass me the dishes!" -分治+线段树区间合并(常规操作+维护端点)并输出最优的区间的左右端点-(洛谷 小白逛公园 升级版)

    "Ray, Pass me the dishes!" UVA - 1400 题意就是线段树区间子段最大和,线段树区间合并,但是这道题还要求输出最大和的子段的左右端点.要求字典序最小 ...

  2. 解决win10下git闪退

    网上找了很多方法,只有这个是有用的,记录下来. 问题描述 在git官网下载了软件,安装之后,git Bash出现闪退现象,同时在当前文件夹下面会生成一个mintty.exe.stackdump的文件. ...

  3. JavaWeb 之 AJAX

    Ajax ajax:AJAX 是与服务器交换数据的艺术,它在不重载全部页面的情况下,实现了对部分网页的更新 AJAX:Asynchronous JavaScript and XML,异步 javasc ...

  4. java getenv getProperties区别

    网上很多使用的是getProperties.说获得系统变量,但是其实不正确.getProperties中所谓的"system properties"其实是指"java s ...

  5. 【DLX算法】hdu3498 whosyourdaddy

    题意:给你一个01矩阵,让你选择尽可能少的行数,使得这些行的并集能够覆盖到所有列. DLX算法求解重复覆盖问题模板,使用估价函数进行剪枝. #include<cstdio> #includ ...

  6. 【2-SAT】HDU3622-Bomb Game

    [题目大意] 给n对炸弹可以放置的位置(每个位置为一个二维平面上的点),每次放置炸弹是时只能选择这一对中的其中一个点,每个炸弹爆炸的范围半径都一样,控制爆炸的半径使得所有的爆炸范围都不相交(可以相切) ...

  7. bzoj 1004 Cards 组合计数

    这道题考察的是组合计数(用Burnside,当然也可以认为是Polya的变形,毕竟Polya是Burnside推导出来的). 这一类问题的本质是计算置换群(A,P)中不动点个数!(所谓不动点,是一个二 ...

  8. cordova安卓手机<a href="tel:xxx"></a>无法进入拨号界面问题

    在使用cordova开发跨平台APP时,可能会用到点击某个按钮进入拨号界面的问题,HTML中的a标签提供了这个功能,但在部分安卓手机中却没有作用,点击没有反应,解决的方法如下:(在config.xml ...

  9. VK Cup 2016 - Qualification Round 1 (Russian-Speaking Only, for VK Cup teams) C. Promocodes with Mistakes 水题

    C. Promocodes with Mistakes 题目连接: http://www.codeforces.com/contest/637/problem/C Description During ...

  10. ROS知识(3)----功能包package编译的两种方式

    ROS的包编译有两种方法(我知道的),一种是用rosmake,这种方法简单:另一种是用catkin_make,这种方法更方便包的管理和开发.这两种方法都是先建立工作空间workspace(类似于vs下 ...