Unit testing 如何为Kanso编写单元测试

Unit testing 如何为Kanso编写单元测试,unit-testing,couchdb,couchapp,kanso,Unit Testing,Couchdb,Couchapp,Kanso,我已经编写了很多django应用程序,并且习惯于扩展unittest.TestCase并运行python manage.py test app\u name。有没有类似的简单方法来对应用程序进行单元测试?请提供一个简单的例子 谢谢。Kanso应用程序是CouchDB应用程序。然而,对于巴克来说,最好的办法是暂时忽略CouchDB。重要的是:Kanso应用程序是Node.js应用程序。测试它们的方法与测试Node.js应用程序的方法相同。测试它们是否符合文档化的CouchDB API,您就会没事了

我已经编写了很多django应用程序,并且习惯于扩展
unittest.TestCase
并运行
python manage.py test app\u name
。有没有类似的简单方法来对应用程序进行单元测试?请提供一个简单的例子


谢谢。

Kanso应用程序是CouchDB应用程序。然而,对于巴克来说,最好的办法是暂时忽略CouchDB。重要的是:Kanso应用程序是Node.js应用程序。测试它们的方法与测试Node.js应用程序的方法相同。测试它们是否符合文档化的CouchDB API,您就会没事了

理想情况下,我们可能希望在CouchDB中实际运行测试。JavaScript引擎是不同的(V8与SpiderMonkey);环境是不同的。然而在实践中,测试Node.js代码要容易得多。(另外,两个平台上都没有一类JavaScript错误:第三方代码设置全局变量、更改内置类型、更改原型——这些都是浏览器的问题。Node.js和CouchDB都是原始的、可预测的。)

例子 让我们制作一个简单的沙发应用程序,以一种简单的方式输出“Hello world”

kanso.json
文件:

{ "name"   : "hello_world"
, "version": "0.1.0"
, "description": "A simple hello-world Couch app"
, "dependencies": { "node-couchapp": "~0.8.3" }
, "app": "app"
}
{ "name"   : "hello_world"
, "description": "A simple hello-world Couch app"
, "version": "0.1.0"
, "private": true
, "devDependencies": { "tap": "~0.2.3" }
}
var tap = require('tap')

tap.test('The Couch app loads', function(t) {
  t.doesNotThrow(load_app, 'No problem loading the app.js file')
  t.end()

  function load_app() {
    var app = require('../app')
  }
})

tap.test('The show function', function(t) {
  var app = require('../app')
    , hello = app.shows.hello

  t.type(hello, 'function', 'Show function "hello" in the couch app')

  var doc = {}
    , null_req = {'query':{}}
    , john_req = {'query':{'who':'John Doe'}}

  t.equal(hello(doc, null_req), 'Hello, world', '"Hello world" by default')
  t.equal(hello(doc, john_req), 'Hello, John Doe', 'Supports ?who query string')
  t.end()
})
下一步运行kanso install,它将引入“node couchapp”依赖项。(注意使用
kanso
命令与使用
npm
命令类似。)

让我们在
/app.js
中制作一个非常简单的沙发应用程序:

// A Couch app that just says hello in a _show function.
module.exports = {
  'shows': {
    'hello': function(doc, req) {
      var who = req.query.who || "world"
      return "Hello, " + who
    }
  }
}
我跑了
kanso-pushhttp://example.iriscouch.com/so_hello
我可以在这里看到我的应用程序:

添加测试 我喜欢,所以让我们用这个。但要点是,这只是一些Node.js代码。使用您喜欢的任何方法进行测试

首先,一个快速的
package.json
文件:

{ "name"   : "hello_world"
, "version": "0.1.0"
, "description": "A simple hello-world Couch app"
, "dependencies": { "node-couchapp": "~0.8.3" }
, "app": "app"
}
{ "name"   : "hello_world"
, "description": "A simple hello-world Couch app"
, "version": "0.1.0"
, "private": true
, "devDependencies": { "tap": "~0.2.3" }
}
var tap = require('tap')

tap.test('The Couch app loads', function(t) {
  t.doesNotThrow(load_app, 'No problem loading the app.js file')
  t.end()

  function load_app() {
    var app = require('../app')
  }
})

tap.test('The show function', function(t) {
  var app = require('../app')
    , hello = app.shows.hello

  t.type(hello, 'function', 'Show function "hello" in the couch app')

  var doc = {}
    , null_req = {'query':{}}
    , john_req = {'query':{'who':'John Doe'}}

  t.equal(hello(doc, null_req), 'Hello, world', '"Hello world" by default')
  t.equal(hello(doc, john_req), 'Hello, John Doe', 'Supports ?who query string')
  t.end()
})
运行
npm install
获取node tap包。(当我在node.js上工作时,我的
$PATH
中总是有
/node\u modules/.bin
。我喜欢在项目中有我需要的一切,而不是全局安装

接下来,可能是一个
test/show_function.js
文件:

{ "name"   : "hello_world"
, "version": "0.1.0"
, "description": "A simple hello-world Couch app"
, "dependencies": { "node-couchapp": "~0.8.3" }
, "app": "app"
}
{ "name"   : "hello_world"
, "description": "A simple hello-world Couch app"
, "version": "0.1.0"
, "private": true
, "devDependencies": { "tap": "~0.2.3" }
}
var tap = require('tap')

tap.test('The Couch app loads', function(t) {
  t.doesNotThrow(load_app, 'No problem loading the app.js file')
  t.end()

  function load_app() {
    var app = require('../app')
  }
})

tap.test('The show function', function(t) {
  var app = require('../app')
    , hello = app.shows.hello

  t.type(hello, 'function', 'Show function "hello" in the couch app')

  var doc = {}
    , null_req = {'query':{}}
    , john_req = {'query':{'who':'John Doe'}}

  t.equal(hello(doc, null_req), 'Hello, world', '"Hello world" by default')
  t.equal(hello(doc, john_req), 'Hello, John Doe', 'Supports ?who query string')
  t.end()
})
通过运行
点击测试来测试:

$ tap test
ok test/show_function.js ................................ 5/5
total ................................................... 5/5

ok
我将更改代码以返回硬编码的“Hello,world”(即忽略
req.query.who
参数)。请注意失败的测试:

$ tap test
not ok test/show_function.js ............................ 4/5
    Command: "node" "show_function.js"
    ok 1 No problem loading the app.js file
    ok 2 Show function "hello" in the couch app
    ok 3 "Hello world" by default
    not ok 4 Supports ?who query string
      ---
        file:   /private/tmp/j/test/show_function.js
        line:   23
        column: 5
        stack:  
          - getCaller (/private/tmp/j/node_modules/tap/lib/tap-assert.js:403:17)
          - assert (/private/tmp/j/node_modules/tap/lib/tap-assert.js:19:16)
          - Function.equal (/private/tmp/j/node_modules/tap/lib/tap-assert.js:160:10)
          - Test._testAssert [as equal] (/private/tmp/j/node_modules/tap/lib/tap-test.js:86:16)
          - Test.<anonymous> (/private/tmp/j/test/show_function.js:23:5)
          - Test.<anonymous> (native)
          - Test.<anonymous> (events.js:88:20)
          - Test.emit (/private/tmp/j/node_modules/tap/lib/tap-test.js:103:8)
          - GlobalHarness.<anonymous> (/private/tmp/j/node_modules/tap/lib/tap-harness.js:86:13)
          - Array.0 (native)
        found:  Hello, world
        wanted: Hello, John Doe
        diff:   |
          FOUND:  Hello, world
          WANTED: Hello, John Doe
                         ^ (at position = 7)
      ...
    ok 5 test/show_function.js

    1..5
    # tests 5
    # pass  4
    # fail  1

total ................................................... 4/5

not ok
$tap测试
不正常测试/显示功能js 4/5
命令:“节点”“show_function.js”
ok 1加载app.js文件没有问题
ok 2在沙发应用程序中显示功能“hello”
ok 3默认情况下为“Hello world”
不正常4支持?谁查询字符串
---
文件:/private/tmp/j/test/show_function.js
第23行
栏目:5
堆栈:
-getCaller(/private/tmp/j/node_modules/tap/lib/tap assert.js:403:17)
-assert(/private/tmp/j/node_modules/tap/lib/tap assert.js:19:16)
-Function.equal(/private/tmp/j/node_modules/tap/lib/tap assert.js:160:10)
-Test._testAssert[as equal](/private/tmp/j/node_modules/tap/lib/tap Test.js:86:16)
-测试。(/private/tmp/j/Test/show_function.js:23:5)
-测试(本地)
-测试。(events.js:88:20)
-Test.emit(/private/tmp/j/node_modules/tap/lib/tap Test.js:103:8)
-全局线束。(/private/tmp/j/node_modules/tap/lib/tap-harness.js:86:13)
-Array.0(本机)
发现:你好,世界
通缉犯:你好,约翰·多伊
差异:|
发现:你好,世界
通缉犯:你好,约翰·多伊
^(位置=7时)
...
ok 5测试/显示功能.js
1..5
#测试5
#通过4
#失败1
总计……4/5
不好

我有一些项目可以帮助showcase测试kanso应用程序:

仪表板核心项目

特点:

  • 无头测试
  • 因为这是一个模块,所以我们有一个,这是一个使用该模块的独立kanso应用程序
节点Couchapp项目

  • 特拉维斯支持
  • 这一次,kanso文件夹中有多个测试kanso项目。再次在包目录中使用符号链接技巧

与JasonSmith一样,我也建议您尽可能使用Node.js进行测试。但是,由于Couchapp的性质,您通常不得不编写单元测试以在浏览器中运行,这可能是因为它们与您不想模拟的浏览器API交互,也可能是因为您需要测试它在一系列浏览器中的工作情况

在进行基于浏览器的单元测试时,我使用了一些我拼凑在一起的Kanso小软件包来自动提供一个运行nodeunit测试套件的界面。目前有点粗糙,但完成了工作

kanso.json

将nodeunit和nodeunit testrunner包添加到kanso.json文件中,并运行kanso install从存储库中获取它们

{
    "name": "example",
    "version": "0.0.1",
    "description": "example app with unit tests",
    "modules": ["lib", "tests"],
    "load": "lib/app",
    "dependencies": {
        "modules": null,
        "properties": null,
        "nodeunit": null,
        "nodeunit-testrunner": null
    }
}
请注意,我已将“tests”目录作为模块路径包含在内。放入该目录的任何模块都将用作nodeunit测试套件,并由nodeunit testrunner UI显示

重写

您需要手动将nodeunit testrunner包的重写添加到您的应用程序中,在我的示例中,这意味着编辑lib/app.js,如下所示:

exports.rewrites = [
    require('nodeunit-testrunner/rewrites')
];
添加一些测试

假设我们有一个模块lib/foo.js,如下所示:

exports.hello = function (name) {
    return 'hello ' + name;
};
我们可以通过在tests/test-foo.js添加一个模块来添加一个测试(只要它在tests目录中,就可以命名为任何名称)

如果您随后推送应用程序并在浏览器中访问,您将看到一个基本界面,用于运行tests目录中的测试套件,可以单独运行,也可以逐个运行


希望这能有所帮助。

顺便说一句,我把所有的工作都转换成了Kanso,因为它更容易进行单元测试。您可能还想看看:for help testing