Как написать модульные тесты для Kanso - PullRequest
10 голосов
/ 25 ноября 2011

Я написал много приложений для django и привык к расширению unittest.TestCase и запуску python manage.py test app_name. Существует ли такой же простой способ модульного тестирования Kanso приложений? Пожалуйста, приведите минимальный пример.

Спасибо.

Ответы [ 3 ]

10 голосов
/ 04 мая 2012

Приложения Kanso являются приложениями CouchDB. Однако лучше всего проигнорировать CouchDB на данный момент. Важно следующее: приложения Kanso - это приложения Node.js . Протестируйте их так же, как и приложение Node.js. Проверьте, что они придерживаются документированного CouchDB API, и все будет в порядке.

В идеале, мы можем захотеть запустить тесты на самом деле в CouchDB . Механизмы JavaScript отличаются (V8 против SpiderMonkey); среды разные. Однако на практике гораздо проще протестировать код Node.js. (Кроме того, на обеих платформах отсутствует целый класс ошибок JavaScript: сторонний код, устанавливающий глобальные переменные, изменяющий встроенные типы, меняющий прототипы - все это проблемы браузера. Node.js и CouchDB являются нетронутыми и предсказуемыми.)

Пример

Давайте создадим простое приложение Couch, которое выводит «Hello world» в функции _show .

Файл kanso.json:

{ "name"   : "hello_world"
, "version": "0.1.0"
, "description": "A simple hello-world Couch app"
, "dependencies": { "node-couchapp": "~0.8.3" }
, "app": "app"
}

Следующий запуск kanso install, который включит зависимость "node-couchapp". (Обратите внимание, что использование команды kanso похоже на использование команды npm.)

Давайте сделаем очень простое приложение Couch, в ./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 push http://example.iriscouch.com/so_hello, и я вижу мое приложение здесь:

Добавление тестов

Мне нравится node-tap , так что давайте использовать это. Но главное, это всего лишь некоторый код Node.js. Протестируйте его любым удобным для вас способом.

Сначала быстрый package.json файл:

{ "name"   : "hello_world"
, "description": "A simple hello-world Couch app"
, "version": "0.1.0"
, "private": true
, "devDependencies": { "tap": "~0.2.3" }
}

Запустите npm install, чтобы получить пакет node-tap. (И у меня всегда есть ./node_modules/.bin в моем $PATH, когда я работаю на Node.js. Вместо глобальной установки, мне нравится иметь все, что мне нужно, прямо в проекте.

Далее, возможно, файл test/show_function.js:

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:

$ 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
6 голосов
/ 04 мая 2012

Как и JasonSmith, я также рекомендую вам по возможности тестировать с помощью Node.js.Однако из-за природы CouchApp вам часто приходится писать модульные тесты для запуска в браузере, либо потому, что они взаимодействуют с API-интерфейсами браузера, которые вы не хотите имитировать, либо потому, что вам нужно проверить, что он работает в различных браузерах..

При выполнении модульных тестов на основе браузера я использую несколько небольших пакетов Kanso, которые я взломал вместе, чтобы автоматически представить интерфейс для запуска наборов тестов узлов узла.Сейчас он немного грубоват, но выполняет свою работу.

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.

Перезаписывает

Вам необходимо вручную добавить 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 (его можно назвать любым, если он находится внутрикаталог тестов).

var foo = require('lib/foo');


exports['test for foo.hello'] = function (test) {
    test.equal(foo.hello('bar'), 'hello bar');
    test.done();
};

Если вы затем нажмете свое приложение и зайдете в браузер http://localhost:5984/example/_design/example/_rewrite/test, вам будет представлен базовый интерфейс для запуска наборов тестов в каталоге тестов, либо по отдельности.или все они один за другим.

Надеюсь, это поможет.

6 голосов
/ 04 мая 2012

У меня есть несколько проектов, которые могут помочь в тестировании приложений kanso:

Основной проект Dashboard

https://github.com/ryanramage/dashboard-core

Особенности:

  • Поддержка Travis .
  • PhantomJS безголовое тестирование с использованием NodeUnit
  • Поскольку это модуль, у нас есть папка test , которая является отдельным приложением kanso, использующим модуль.Обратите внимание, что в папке packages есть символическая ссылка на корень проекта.

Проект Node-Couchapp

https://github.com/kanso/node-couchapp

  • Поддержка Travis
  • На этот раз несколько тестовых проектов кансо в папке kanso.Снова используя трюк с символической ссылкой в ​​каталоге пакета
...