vowsjs / api-easy Goto Github PK
View Code? Open in Web Editor NEWFluent (i.e. chainable) syntax for generating vows tests against RESTful APIs.
Home Page: http://flatiron.github.com/api-easy
License: MIT License
Fluent (i.e. chainable) syntax for generating vows tests against RESTful APIs.
Home Page: http://flatiron.github.com/api-easy
License: MIT License
Hi!
One month ago I used api-easy to test an api built on Express (node package). But this don't work anymore. Before, I was able to make a suite of calls that reuse the session made by the login. Now, each call after the login fails and I received 401 (unauthorized).
My express api (server) code manage sessions like this :
req.session.loggedIn = true;
req.session.accountId = account._id;
res.send(200);
Code example that fails now (on the account/authenticated call) :
suite.discuss('Login attempt with good credentials')
.post('/login', null, {'email':'[email protected]', 'password':'12345'})
.expect(200)
.next()
.discuss('Validate session after the login')
.get('/account/authenticated')
.expect(200)
.export(module);
I can't figure out what have change or how to test my code with api-test now. Should I update something?
Thanks!
Just wanted to point out the project's URL is broken.
http://indexzero.github.com/api-easy - no longer works
http://flatiron.github.com/api-easy - i believe to be the new url.
Hi,
I started using api-easy today for doing a quick smoke test of my application which was super simple to get working.
I run the smoke test after a fresh deployment and usually in the first test run some of the tests might fail with a timeout but pass thereafter.
I was wondering if it would be possible to build in a retry mechanic - I'd be happy to put in the effort and submit a PR but would need a nudge in the right direction as I'm quite new to node.
Thanks
Neil
My tests against https fail with the message that indicates the query string isn't being passed.
The api requires a 'token' in the querystring.
The following call against HTTPS fails with a 403:
suite.use('api.example.com', 443, {secure:true})
.get('/accounts',{token:apitoken})
.expect(200, { ok: true })
.export(module);
But this code against HTTP works and returns a 200:
suite.use('api.example.com', 80)
.get('/accounts',{token:apitoken})
.expect(200, { ok: true })
.export(module);
Am I just trying to do HTTPS wrong?
This is no big deal, but sometimes a slash is needed to get a directory. That's what c9/vfs
(the vfs-http-adapter
) currently requires.
Hi,
I've tried to follow the instructions, but I keep on getting a "Permission denied" error:
Macintosh:foo tito$ npm test
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] No readme data.
> [email protected] test /Users/tito/Desktop/FooDevelopment/foo
> tests/*-test.js
sh: tests/connect-test.js: Permission denied
npm ERR! weird error 126
npm ERR! not ok code 0
Macintosh:foo tito$
I'm not sure what's wrong. This is what tests/connect-test.js looks like:
var APIeasy = require('api-easy');
var suite = APIeasy.describe('your/awesome/api');
suite.discuss('When using your awesome API')
.discuss('and your awesome resource')
.use('localhost', 8080)
.setHeader('Content-Type', 'application/json')
.post('/connection')
.expect(200)
.export(module);
The permissions look like this
-rw-r--r-- 1 tito staff 2311 Jul 7 20:39 connect-test.js
Any ideas? Thanks!
Please don't be too mad,
I couldn't find how to contact you privately so I had to ping you here.
Red Hat owns the trademark on RESTEasy based on our project of the same name that has existed for over 3+ years. Since you are starting your own business it seems at Nodejitsu, I hope that you can understand, as entrepreneurs, that Trademark is one of the few assets that an open source project has.
Please change the name.
Sincerely,
Bill Burke, founder Red Hat's RESTEasy project.
It would be great if APIEasy could take the hassle out of testing 2-legged & 3-legged OAuth resources (3-legged creating the biggest hassle.) Granted, there would have to be some DOM manipulation for entering u/p and submitting, but that would be easy to do with something like jsdom.
Server side code:
res.render('dashboard', {
layout: 'layouts/default'
, user: req.currentUser
}
api-easy test code
.get(urlRedir)
.expect(200)
.expect('get user infor', function(err, res, body){
in the body
, there are whole html element. Is there any better method to read it?
nt
Starting server in test mode
initializing routes
restify listing at http://0.0.0.0:8989
···✗✗✗✗
When posting an invalid worm is should 400 A POST to /worms/worms
✗ should respond with 400
» expected 400,
got 404 (==) // api-easy.js:290
✗ should have a proper 400 error body
»
actual expected
InvalidObjResourceNotFound
// server.coffee:33
When posting a valid worm it should save correctly A POST to /worms
✗ should respond with 200
» expected 200,
got 404 (==) // api-easy.js:290
✗ should have a proper post body
»
actual expected
SResourccessNotFound
// server.coffee:41
✗ Broken » 3 honored ∙ 4 broken (0.030s)
In the first instance the "InvalidObjResourceNotFound" I'm expecting a space between 'InvalidObj' and 'ResourceNotFound' also for some reason the first e, c, and t in 'ResourceNotFound' are black instead of Red.
In the second instance I have to assertions in the same callback and it looks like it's printing both failures on the same line and blending the characters, leading to gibberish and christmas colors (red, black and green all blended and crazy).
The tests producing strange output (written in coffeesript):
.expect('should have a proper 400 error body', (err, res, body) ->
body = JSON.parse body
assert.equal body.code, 'InvalidObject'
)
.expect('should have a proper post body', (err, res, body) ->
body = JSON.parse body
assert.equal body.code, 'Success'
assert.equal body.location, '/worms/1' #first worm posted
)
Hi,
I'm getting the following error
? Errored » Asynchronous Error
in api smoke test for myurl.org
in undefined
Errored » callback not fired
in When doing a smoke test on myurl.org A GET to /login
in api smoke test for myurl.org
I'm struggling to figure out if this is my fault or not. I'm running a suite more than once if it fails I retry it. Do you think this would cause an issue? Should I create a new suite for each run?
Running npm install without or without sudo as per the Readme doesn't install vows with the -g flag. But the -g flag is required to install vows CLI to allow tests to be run with the command line you document in the api-easy Readme. After I separately did an npm install -g vows then vows was recognized from the command line.
I noticed this while pulling in the s/querystring/qs/ pull request; however, the failing tests have little/nothing to do with it.
Please update vows version to 0.7.x permitting compatibility with node 0.10.0.
I'd be good to add a way to execute some hooks like setup, before and after each test and a tear down after all the tests, something like this:
suite.discuss('.....').use('localhost'. 3001)
.setup(function(){
// This should be executed once before starting with the tests
})
.beforeEach(function(){
// This should be executed before each .get(), .post(), etc
})
.afterEach(function(){
// This should be executed after each .get(), .post(), etc
})
.tearDown(function(){
// This should be executed after all the tests
})
.get('/').expect(....)
.get('/').expect(....)
.post('/').expect(....)
.export(module);
It'd be good if it has a way to execute those hooks in synchronous way, because some times one need to populate the DB and has to wait until the driver executes the callback, if it were async then the tests will continue running while the DB is still being populated.
I hope that makes sense.
I have a test that attempts to contact my REST service and submit a form, approximately like the following:
suite
.use('localhost', 3000)
.setHeader('Content-Type', 'application/json')
.discuss('When using the Thread API')
.post('/thread', {title: 'title-test', author: 'John Doe'})
.expect(302)
.next()
And the request handler under test (an Express method):
app.post('/thread', function(req, res) {
var newThread = new Thread({title: req.body.title, author: req.body.author});
newThread.save();
res.redirect('home');
});
When calling this through a browser or CURL, I get a neat '302' message. However, when trying this in api-easy, I get the following response:
When using the Thread API A POST to /thread
? should respond with 302
» expected 302,
got 404 (==) // api-easy.js:233
I went debugging and replaced my expect() with one that prints out the error, response and body contents, and the body content in particular seems to highlight the problem:
Cannot POST /
(where '/' is the homepage redirected to). It seems api-easy, or the library it uses to run POST-requests, re-uses the same request type when getting redirected after a post.
So, a few questions:
I have the need to use data gathered from one test in a subsequent test, and so far I've not found a convenient way to do this.
The use case I'd like to support is something like:
POST /myresource - this creates a new resource and returns identifier X
PUT /myresource/X - this updates the resource
I understand that I can use .next() to have on test run after the other, however as all the methods are chained together, parameters are evaluated before the tests run, not after. I have worked around this for now using a .before() function which finds tokens in the URL and request body and replaces them with values. This works, but I suspect there is a better way.
Hi,
First of all, thanks for your work on API-easy, I use it everyday! :)
For one of my project I upgraded node from 0.8 to 0.10 but I discovered some issues.
I tried the code below with different version of node and the latest version of API-easy.
var assert = require('assert'),
APIeasy = require('api-easy'),
suite = APIeasy.describe('api');
suite.discuss('Test Resource /users')
.use('localhost', 4001)
.expect(401)
.expect('Missing token', function (err, res, body) {
assert.equal(body, 'Missing Cookie auth');
})
.export(module);
Node v0.8.9 / API-easy v0.3.7. Everything is fine.
./node-v0.8.9-linux-x64/bin/node user.vows.js
·· ✓ OK » 2 honored (0.022s)
Node v0.9.9 / API-easy v0.3.7. No error message, but at least we know there is two errors.
./node-v0.9.9-linux-4/bin/node user.vows.js
✗ Errored » 1 errored
✗ Errored » 1 errored
Node v0.10.4 / API-easy v0.3.7. No error message and only one error...
./node-v0.10.4-linux-x64/bin/node user.vows.js
✗ Errored » 1 errored
Node v0.11.0 / API-easy v0.3.7. The same as previous.
./node-v0.11.0-linux-x64/bin/node user.vows.js
✗ Errored » 1 errored
Does anyone have the same issue?
FYI, I am using Ubuntu 12.04.
For my tests, although they rely on mongoose I'd like them not to run until something happens (in this case, mongoose triggers the "open" event.)
Although I use mongoose in this example, and blocking operations are a flamewar-earning topic in node.js, I think my question still stands.
At present there's no way to postpone the wrap the tests firing into a callback, and I think that'd be very useful. Even something like a setup
method that receives a callback function and tests won't proceed until the callback is triggered.
journey
still uses require.paths
(fixed in cloudhead/journey#18, but it's getting no attention from @cloudhead).
hi Charlie,
When I do a post operation and want to get the new url information from redirection. so I can do the new get operation.
I do not how to do that? Could you please help me?
code:
suite.discuss('now we create a project')
.use('localhost', 3000)
.setHeader('Content-Type', 'application/json')
.followRedirect(false)
.path('/projects')
.post( { information : 'good news'})
.expect(302)
.expect('redirect content', function(err, res, body){
...
I know that I can get the url from res.headers.location, but how can I do a get operation with this url??
Really need some better documentation. I would like to see some wiki pages please with examples.
Hey,
What do you think of supporting file uploading? I've found api-easy to be super useful for testing my RESTful API, but to test uploads I've been falling back on scripted curl requests.
There doesn't seem to be a DELETE
method.
Unable to pass data between chained APIEasy calls. This only works for outgoing headers. However, passing state to modify post request body of subsequent calls does not work. It appears that APIEasy is caching the post data to be sent at initialization and instead of late binding
Here is a gist with my use case
Failing use case
nt
I'm using APIEasy via grunt and the grunt-vows plugin.
Is there some way I could set up the different host names for different server environments as grunt task targets, then use the config info in the tests?
Alternatively, could I set some variables in a set of wrapper scripts which then require or include the actual tests?
Hi,
For certain assertions I'm making, I would rather so a looser equal on the result. I was wondering if there was a nice way of doing something like
....expect (200, { result { randomData: "*"}})
I basically want to assert on the structure of the response rather than the data/all of the data.
Thanks,
Chris
Just one test will be execute they have same method and uri.
example:
.post('/tests', { dynamic: true })
.expect(200, { dynamic: true })
.post('/tests', { dynamic: false })
.expect(200, { dynamic: false })
I think it's because of this line in api-easy.js
:
// Create the description for this test. This is currently static.
// **Remark _(indexzero)_**: Do users care if these strings are configurable?
//
this.current = ['A', method.toUpperCase(), 'to', fullUri].join(' ');
context = this._currentTest();
Looks that ng-page is down:
http://flatiron.github.io/api-easy
there is no gh-pages, and build is broken. Npm install failed at the travis, while locally it works pretty fine.
I guess the culprit can be testing against 0.4:
https://github.com/marcin-wosinek/api-easy/blob/master/.travis.yml
The codes are as bellows.
suite.discuss('...')
....
.post(...)
.expect('got the event', function(err, res, body){
suite1.discuss('....')
})
and suite1 is embedded in the suite, I want to know whether it is OK?
I did a http server like this:
var http = require('http');
http.createServer(function( req, res ) {
res.writeHead(302, {
'Content-Type' : 'text/html',
'Location' : 'http://www.google.com'
});
res.write('Yay');
res.end();
}).listen(9000);
and a test case like this:
var ApiEasy = require('api-easy');
var suite = ApiEasy.describe('Check if server is alive');
suite.discuss('GIVEN that I want to check the server\'s basic REST API')
.use('localhost', 9000)
.path('/')
.get()
.expect(302);
suite.export(module);
But it shows:
should respond with 302
» expected 302,
got 200 (==)
Can you provide an example of recursive calls. I'm interested in the case where you, let's say authenticate a call to an API and then use the token returned for future calls.
Thanks!
There is a small error in the assert.deepEqual
when testing the JSON body. The arguments passed to assert.deepEqual
should be swapped as result
is the expected value and not testResult
which is the actual value parsed from the body.
I'm having a look at your code, and I'm learning quite a few js tricks :-)
but I don't get why you issue
use: function (host /* [port, options] */) {
var args = Array.prototype.slice.call(arguments),
options = typeof args[args.length - 1] === 'object' ? args.pop() : {},
port = args[1];
instead of just
use: function (host, port, options) {
options = options || {};
In other places I see you use that tecnique to allow for a more flexible way of passing parameters...
ps: sorry for the offtopic question
I am new to apieasy, want to know how to get test reports in xml or html?
I'm testing an existing XML-based rest API. The XML string is not sent with:
.post("/my/uri", "xml")
I looked into api-easy.js, and I think I see the issue. The _request function expects data to be an object. Fixing this would not be as simple allowing the body to be either an object or string -- as this could possibly conflict with the uri parameter.
One possible solution is to have the body continue to be an object, but for unkown mime types, encapsulate the data in an object, like such: {"body": "xml"}.
If it's possible to use this inside a different, non-vows, test framework (eg nodeunit, expresso), could you please document that?
Hi there,
Nice testing library!
When running the example provided in the README and running tests against my own API implementation I get a callback not fired error.
Errored » callback not fired
What callback is this referring to as I am not testing for any callbacks being fired?
There is no way to configure the .use() directive to use https.
I have tryied with host and port 443 without success.
This is a little test suite i use to test a simple API:
var APIeasy = require('api-easy');
var suite = APIeasy.describe('API');
suite.use('localhost', 3000)
.path('/users')
.get()
.expect(200)
.next()
.put({ firstName: 'Testibus', lastName: 'Testman' })
.expect(200)
.export(module)
However, the .get()
works as expected but the .put()
results in an error:
A PUT to /users
✗ should respond with 200
» expected 200,
got undefined (==) // api-easy.js:290
✗ Broken » 1 honored ∙ 1 broken (0.304s)
Am i missing something?
Just as there is a befores implementation it would be nice to have an afters function as I am trying to wrap the library in a promise and resolve it at the end of the function.
return new Promise(function(resolve, reject) {
suite.discuss('When authenticating')
.discuss('with no username or password')
.after(resolve) // this part
.next();
});
Leaving the "Content-Type" header set for all requests (including GET which does not have any body) seems to confuse the Express.js router and a simple GET to /resource after a POST to /resource with 'Content-Type': 'application/json' returns 400.
Would it be right to remove the header for GET requests? If so I'll make a pull request.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.