CoffeeScript构建设置支持单元测试?

时间:2012-09-30 16:53:35

标签: coffeescript build-process qunit

我想使用CoffeeScript来构建基本上是JavaScript库的东西。

我希望能够

  1. 使用继承定义一些类
  2. 将我的代码保存在多个文件中
  3. 编写一些单元测试(QUnit或其他任何工作,最好用CoffeeScript编写测试)
  4. (理想情况下)在我工作时自动观察和构建项目
  5. 这似乎合情合理,不是吗?我的计划是在浏览器中对已编译的JavaScript运行单元测试,但是如果我可以直接在node.js中运行它们,那就更好了。

    目前,我正在尝试使用CoffeeToasterQUnit,使用两种不同的CoffeeToaster配置,一种配有测试,另一种配备没有。它有效,但也许有人有更好的建议?我应该放弃CoffeeToaster并使用Cake吗?或者获得另一个单元测试框架?有人能指点我这个教程吗?我正在创建一个客户端JS库,所以我不想涉及Rails等。

1 个答案:

答案 0 :(得分:4)

我目前正在使用:

  • Mocha 作为测试运行者, should.js 用于断言;
  • Mockery拦截某些require调用使用所需库的模拟/存根进行隔离测试;
  • * JSCoverage用于检测代码覆盖率报告的代码。

我的代码位于src/,我在CoffeeScript中编写测试。我使用make来构建和测试代码。

  • make buildsrc/中的CoffeeScript编译为lib/中的JavaScript。
  • make test构建代码,然后在test/中运行测试。
  • make monitor会在更改后立即观察并运行测试。不幸的是,没有重新编译代码。我使用Vim键绑定来调用make,这也会触发Mocha重新运行测试。 修改:如果这让您感到困扰,可以运行coffee --watch -o lib/ -c src/
  • make coverage生成代码覆盖率报告并将其放入lib-cov/report.html

我的Makefile看起来有点像这样:

COFFEE = ./node_modules/.bin/coffee --compile
MOCHA = NODE_ENV=test ./node_modules/.bin/mocha
MOCHA_OPTS = \
    --compilers coffee:coffee-script \
    --require should \
    --colors
REPORTER = spec

build:
    @$(COFFEE) --output lib/ src/

test: build
    @$(MOCHA) --reporter $(REPORTER) $(MOCHA_OPTS)

monitor:
    @$(MOCHA) --reporter min $(MOCHA_OPTS) \
    --watch --growl

coverage: instrument
    @MYLIB_COV=1 $(MOCHA) $(MOCHA_OPTS) \
    --reporter html-cov > lib-cov/report.html

instrument: build
    @rm -rf ./lib-cov
    @jscoverage ./lib ./lib-cov

.PHONY: build test monitor coverage instrument

您可以使用上述内容,只需很少的修改。

要使用make coverage生成覆盖率报告,必须针对lib-cov/中的已检测代码而不是lib/中的代码运行测试。为了实现这一目标,需要做三件事:

  1. Makefile应设置环境变量,例如MYLIB_COV (根据需要更改名称)。

  2. 您的index.js应该相应地查看此环境变量require lib/lib-cov/

    // index.js
    module.exports = process.env.MYLIB_COV
      ? require('./lib-cov/mylib')
      : require('./lib/mylib');
    

    如果您需要从多个源文件导出,可以在此处将它们组合在一起。如果你的package.json中有index.js以外的其他内容作为'main',请不要忘记更改它。

  3. 您的测试应require '../'

    # test/test.user.coffee
    describe 'User', ->
      User = {}
    
      before ->
        {User} = require '../'
    
      describe '#equals()', ->
        describe 'when users have the same username and host', ->
          it 'should return true', ->
            user1 = new User 'user', 'some.host.foo'
            user2 = new User 'user', 'some.host.foo'
            user1.equals(user2).should.be.true
    
      # etc.
    
  4. 我会把它作为练习留给读者,以确定他们是否需要Mockery以及如果他们这样做如何使用它。不过,我会指出,上述测试代码段中的require调用是在before内完成的。

    快乐的编码!