1.2.0 • Published 8 years ago
pseudo-test v1.2.0
Pseudo Test
If you need to confirm that your XML or JSON API is behaving as expected, this module is for you.
Test API routes using plain English
# Verify that API saves accounts as expected
POST 200 http://myapi.com/user WITH BODY {"firstName":'JP', "lastName":'Berd'}
TEST {"id":"10000","firstName":"JP","lastName":"Berd"} EQUALS RESPONSE.body
...and say goodbye to this
//wth!!!, I have a deadline. Who can write this much code just to test?????
var url = 'http://myapi.com';
it('should correctly update an existing account', function(done){
var body = {
firstName: 'JP',
lastName: 'Berd'
};
request(url)
.post('/user')
.send(body)
.expect('Content-Type', /json/)
.expect(200) //Status code
.end(function(err,res) {
if (err) {
throw err;
}
// Should.js fluent syntax applied
res.body.should.have.property('_id');
res.body.should.have.property('firstName');
res.body.should.have.property('lastName');
res.body.should.have.property('creationDate');
res.body.creationDate.should.not.equal(null);
done();
});
});
})
Additional Commands
Intentionally kept small. The point is to test your code and not learn a verbose language in the process
Command | Description |
---|---|
SET HEADER "key":"value" | Used to set custom http headers. |
SET VAR(IABLE) var = value | Set a local variable for use later |
SET HEADER "authkey":"1234"
SET VAR hostvar = http://jsonplaceholder.typicode.com
#Alternate form, more english like
Set variable hostvar = http://jsonplaceholder.typicode.com
Command | Description |
---|---|
GET|POST|PUT|DELETE HTTP.code (WITH BODY any valid json) | Execute HTTP Request and break if HTTP response code does not match user specified HTTP.code |
RESPONSE.body | Last successful HTTP response.body. |
#Retrieve list of users and test overwrite first user with new info
GET 200 ${hostvar}/users
PUT 200 ${hostvar}/user/${RESPONSE.body[0].id} WITH BODY {"id":"1","name":"Brent"}
Command | Description |
---|---|
TEST condition | If test condition fails, break |
TEST obj EQUALS obj | Test that two objects/arrays are equal. This is includes checking for expected type AND value for each member AND attribute |
TEST obj IS LIKE obj | Test two objects against each other. Only verify that attribute name and type of value match |
TEST RESPONSE.body[0].name == "Brent"
#Strict test. Response body must exactly match the expected result
TEST RESPONSE.body[1] EQUALS {id: 1,name: "Leanne Graham",username: "Lgraham"}
#lazy test. Response body must have same keys and types of values only
TEST RESPONSE.body[1] IS LIKE {id: 9999,name: "blah blah",username: "foo"}
Command | Description |
---|---|
Include path to module | Include a module and set local variable to module name. NOTE: slashes (/) and (-) are converted to (_) underscores |
Calll function | Execute a function from included module |
DEBUG any valid expression | Echo string to console |
LOOP list AS var ENDLOOP | Iterate over list and execute all test(s) against each member of the list. Break if failure. |
Include models/account
#Test Account balance
SET VAR balance = models_account.creditAccount('checking',1000.00)
SET VAR balance = models_account.debitAccount('checking',500.00)
TEST balance == 500.00
GET 200 http://jsonplaceholder.typicode.com/users
DEBUG "Number of users is ${RESPONSE.body[0]length}"
#Perform a couple of tests against each user returned in json array
LOOP RESPONSE.body AS user
TEST user.email != null
TEST typeof user.id == "number"
ENDLOOP
Latest Updates
Version | Change |
---|---|
1.2.0 | Include command added |
1.2.0 | Call command added |
1.1.5 | SETVAR command removed. Use SET VAR instead |
1.1.4 | Commands are now case insensitive. |
1.1.4 | LOOP command added |
1.1.4 | SET VAR(iable) command added |
How Can I get Started?
1.) Install from npm
npm install --save pseudo-test
2.) Edit package.json and add the following snippet to the scripts section
"scripts": {
"ptest": "./node_modules/.bin/ptest"
}
3) Save Test Case to your project directory/tests/myexample.test
Any files with *.test extension will be run
# My First Test Case <myexample.test>
# I'm testing that I receive a 200 from the user service
GET 200 http://jsonplaceholder.typicode.com/users/1
# Pro-tip: HTTP response is saved to global RESPONSE.body Object
# Access global object to test some conditions
TEST RESPONSE.body.username == "Bret" && typeof RESPONSE.body.id == "number"
# Or Compare a test object to the entire RESPONSE.body for exact match
SETVAR mytestobject = {id:1,name:"Leanne Graham",username:"Bret",email:"Sincere@april.biz",address:{street:"Kulas Light",suite:"Apt. 556",city:"Gwenborough",zipcode:"92998-3874",geo:{lat:"-37.3159",lng:"81.1496"}},phone:"1-770-736-8031 x56442",website:"hildegard.org",company:{name:"Romaguera-Crona",catchPhrase:"Multi-layered client-server neural-net",bs:"harness real-time e-markets"}}
TEST mytestobject EQUALS RESPONSE.body
#Pro-tip: Use TEST [someobj] IS LIKE RESPONSE.body to compare only key names and value types
# TEST mytestobject IS LIKE RESPONSE.body
4) Run the Test(s)
npm run ptest
5) View The Output...Did it pass?
Running test for file /Users/gregadmin/projects/cn-anything/tests/myexample.test
Calling URL http://jsonplaceholder.typicode.com/users/1
http_jsonplaceholder_typicode_com_users_1
Expecting a user specified response statusCode [200]
content-type is application/json; charset=utf-8
Evaluating RESPONSE.body.username == "Bret" && typeof RESPONSE.body.id == "number"
fuzzy match is false
Comparing objects [object Object]==> to [object Object]==> with key [address] testForFieldTypeOnly flag is false
Comparing objects Gwenborough==> to Gwenborough==> with key [city] testForFieldTypeOnly flag is false
Comparing objects [object Object]==> to [object Object]==> with key [geo] testForFieldTypeOnly flag is false
Comparing objects -37.3159==> to -37.3159==> with key [lat] testForFieldTypeOnly flag is false
Comparing objects 81.1496==> to 81.1496==> with key [lng] testForFieldTypeOnly flag is false
Comparing objects Kulas Light==> to Kulas Light==> with key [street] testForFieldTypeOnly flag is false
Comparing objects Apt. 556==> to Apt. 556==> with key [suite] testForFieldTypeOnly flag is false
Comparing objects 92998-3874==> to 92998-3874==> with key [zipcode] testForFieldTypeOnly flag is false
Comparing objects [object Object]==> to [object Object]==> with key [company] testForFieldTypeOnly flag is false
Comparing objects harness real-time e-markets==> to harness real-time e-markets==> with key [bs] testForFieldTypeOnly flag is false
Comparing objects Multi-layered client-server neural-net==> to Multi-layered client-server neural-net==> with key [catchPhrase] testForFieldTypeOnly flag is false
Comparing objects Romaguera-Crona==> to Romaguera-Crona==> with key [name] testForFieldTypeOnly flag is false
Comparing objects Sincere@april.biz==> to Sincere@april.biz==> with key [email] testForFieldTypeOnly flag is false
Comparing objects 1==> to 1==> with key [id] testForFieldTypeOnly flag is false
Comparing objects Leanne Graham==> to Leanne Graham==> with key [name] testForFieldTypeOnly flag is false
Comparing objects 1-770-736-8031 x56442==> to 1-770-736-8031 x56442==> with key [phone] testForFieldTypeOnly flag is false
Comparing objects Bret==> to Bret==> with key [username] testForFieldTypeOnly flag is false
Comparing objects hildegard.org==> to hildegard.org==> with key [website] testForFieldTypeOnly flag is false
Overall Status : ALL TESTS PASSED
Known Limitations
-- Multi-line commands are not supported.
-- Use ${varname} syntax if your variables will be enclosed in quotes
Ex. DEBUG "First Person is ${RESPONSE.body0.name}"
Pro-tip: Underscore.js functions are available in all tests
# Call underscore.js library _.sortBy and _.difference to make my life easier
# Test that my REST API /sort route works correctly
# http://underscorejs.org/
SET VAR sortedArray = _.sortBy([3,4,6,1,2,5],function(num){return num})
GET 200 http://myservice/sort WITH BODY [3,4,6,1,2,5]
TEST _.difference(sortedArray,RESPONSE.body) == []
DEBUG RESPONSE.body
Advanced Usage Example(s)
# Compare a JSON string to the response body
# Note: Nested objects are also supported.
GET 200 http://video-api.cartoonnetwork.com/version
TEST {name: "cn-go-api","version":"3.1.48"} EQUALS RESPONSE.body
.....
npm run ptest
Running TEST {name: "cn-go-api","version":"3.1.48"} EQUALS RESPONSE.body
Error processing the following action on line 32 of /projectx/tests/versioncheck.test
TEST {name: "cn-go-api","version":"3.1.48"} EQUALS RESPONSE.body
Error: Value of attribute [version==>3.1.48] does not match value of second object [version ==>3.1.47]
...
# Set less strict checking. I only care that the each object's
# keys match and the values are the correct type.
# Actual value for each key does not matter
TEST {name: "cn-go-api","version":"3.1.48"} IS LIKE RESPONSE.body
...
npm run ptest
Running TEST {name: "cn-go-api","version":"3.1.48"} IS LIKE RESPONSE.body
ALL TESTS PASSED
Pro-Tip: ENABLE GIT HOOKS
Setup your project to reject commits to git repo if your latest code changes cause a test to fail
# copy this file to [your project directory]/.git/hooks/pre-commit
# make it executable by typing chmod +x pre-commit
#!/bin/bash
killall node
PORT="${PORT:-3000}"
echo 'Starting local server at http://localhost and PORT' $PORT
node app.js &
sleep 2
node node_modules/pseudo-test/app.js
killall node
Attempting a commit automatically runs tests and rejects commit it tests fail
git commit -m "I made a quick change and I'm sure it works"
Running TEST {duration: "200","version":"3.1.47"} EQUALS ${RESPONSE.body}
Error processing the following action on line 32 of ~/myapi/tests/oldbusinessrules.test
TEST {duration: "200","version":"3.1.47"} EQUALS RESPONSE.body
Error: Encountered attribute in this object which is not the same attribute type in comparison object
duration is [number] in first object while duration attribute in second object is of type [string]
COMMIT ABORTED : FIX BUG AND TRY AGAIN
1.2.0
8 years ago
1.1.9
8 years ago
1.1.8
8 years ago
1.1.7
8 years ago
1.1.6
8 years ago
1.1.5
8 years ago
1.1.4
8 years ago
1.1.3
8 years ago
1.1.2
8 years ago
1.1.1
8 years ago
1.1.0
8 years ago
1.0.9
8 years ago
1.0.8
8 years ago
1.0.7
8 years ago
1.0.6
8 years ago
1.0.5
8 years ago
1.0.4
8 years ago
1.0.3
8 years ago
1.0.2
8 years ago
1.0.1
8 years ago
1.0.0
8 years ago