You must be logged in to edit this page
__Note:__ This has been copied from JasonSmith's answer on Stack Overflow, for the original post, see here: http://stackoverflow.com/a/10441680/387592
-------------
Kanso apps are CouchDB apps. However the best bang-for-buck is to ignore CouchDB for now. The important thing is this: **Kanso apps are Node.js apps**. Test them the same way you would test a Node.js app. Test that they adhere to the documented CouchDB API and you will be fine.
Ideally, we might want to run tests *actually in CouchDB*. The JavaScript engines are different (V8 vs. SpiderMonkey); the environments are different. However in practice, it is so much easier to test Node.js code. (Also, a whole class of JavaScript bugs are absent on both platforms: third-party code setting global variables, changing built-in types, changing prototypes—those are all browser issues. Node.js and CouchDB are both pristine and predictable.)
## Example
Let's make a simple Couch app that outputs "Hello world" in a [_show function][show].
The `kanso.json` file:
{ "name" : "hello_world"
, "version": "0.1.0"
, "description": "A simple hello-world Couch app"
, "dependencies": { "node-couchapp": "~0.8.3" }
, "app": "app"
}
Next run `kanso install` which will pull in the "node-couchapp" dependency. (Notice how using the `kanso` command is similar to using the `npm` command.)
Let's make a very simple Couch app, in `./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
}
}
}
I ran `kanso push http://example.iriscouch.com/so_hello` and I can see my app here:
* http://example.iriscouch.com/so_hello/_design/hello_world/_show/hello
* http://example.iriscouch.com/so_hello/_design/hello_world/_show/hello?who=Stack+Overflow
## Adding Tests
I like [node-tap][tap] so let's use that. But the main point is, this is just some Node.js code. Test it using whatever method your prefer.
First, a quick `package.json` file:
{ "name" : "hello_world"
, "description": "A simple hello-world Couch app"
, "version": "0.1.0"
, "private": true
, "devDependencies": { "tap": "~0.2.3" }
}
Run `npm install` to get the node-tap package. (And I always have `./node_modules/.bin` in my `$PATH` when I work on Node.js. Rather than a global install, I like to have everything I need right there in the project.
Next, perhaps a `test/show_function.js` file:
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()
})
Test it by running `tap test`:
$ tap test
ok test/show_function.js ................................ 5/5
total ................................................... 5/5
ok
I'll change the code to return "Hello, world" hard-coded (i.e., ignore the `req.query.who` parameter). Notice the failing test:
$ 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]: https://github.com/isaacs/node-tap
[show]: http://wiki.apache.org/couchdb/Formatting_with_Show_and_List