Needless to say, these tests can become monsters to try and read through and understand:
var vows = require('vows'); vows.describe("Floozle Workflow").addBatch({ "Go to login page" : { topic : function () { zombie.visit("http://widgetfactory.com", this.callback); }, "then login" : { topic : function (browser) { browser .fill("#username", "testuser") .fill("#password", "testpass") .pressButton("Login", this.callback); }, "then navigate to Floozle listing" : { topic : function (browser) { browser.click("Floozles", this.callback); }, "should be on the Floozle listing" : function (browser) { assert.include(browser.text("h3"), "Floozles"); }, "should have a 'Create Floozle' link" : function (browser) { assert.include(browser.text("Create Floozle")); }, "then click 'Create Floozle'" : { topic : function (browser) { browser.click("Create Floozle"); }, "then fill out Floozle form" : { topic : function (browser) { browser .fill("#name", "Klaxometer") .fill("#whizzbangs", "27") .choose("#rate", "klaxes per cubic freep") .pressButton("Save", this.callback); }, // .... Continue on from there, with more steps } } } } } }).export(module);So we created prenup, a syntactic sugar library for easily creating Vows tests. Prenup provides a fluent interface for generating easy to read test structures as well as the ability to reuse and chain testing contexts.
Here is the above test written with prenup:
var vows = require('vows'), prenup = require('prenup'); var floozleWorkflow = prenup.createContext(function () { zombie.visit("http://widgetfactory.com", this.callback); }) .sub("then login", function (browser) { browser .fill("#username", "testuser") .fill("#password", "testpass") .pressButton("Login", this.callback); }) .sub("then navigate to Floozle listing", function (browser) { browser.click("Floozles", this.callback); }) .vow("should be on the Floozle listing", function (browser) { assert.include(browser.text("h3"), "Floozles"); }) .vow("should have a 'Create Floozle' link", function (browser) { assert.include(browser.text("Create Floozle")); }) .sub("then click 'Create Floozle'", function (browser) { browser.click("Create Floozle"); }) .sub("then fill out Floozle form", function (browser) { browser .fill("#name", "Klaxometer") .fill("#whizzbangs", "27") .choose("#rate", "klaxes per cubic freep") .pressButton("Save", this.callback); }) .root(); vows.describe("Floozle Workflow").addBatch({ "Go to login page" : floozleWorkflow.seal() }).export(module);Every `sub()` call generates a new sub-context, and every `vows()` call attaches a vow assertion to the most recent context. `parent()` can be called to pop back up the chain and attach parallel contexts. If a context is saved, it can be reused in other chains. When `seal()` is called, it will generate the same structure as the original test.
More examples, including branching and reusing contexts, are given in the documentation. Prenup is available on NPM via `npm install prenup`
No comments:
Post a Comment