From previous story, you may know how I utilised `yaml + ejs + faker + ava + superagent` to test api in declarative way.
In essence, it transfers imperative obj.function(parameter) into the following declarative format in yml file.
obj:
function:
name: value
so we can send http requests with superagent and assert with ava in following yml file.
superagent:
set:
Authorization: <%-$jwt%>
send:
pageIndex: <%-$pageIndex%>
pageSize: 10
ava:
is:
status: 200
However, ava has very basic yes/no assert. It has no function to assert a value in an array of [0, 1, 2], or to assert a value is non-empty string, or any other complex asserts. It means I have to code in imperative way which is not what I want.
Assert with Ramda JS
Ramda js emphasizes a purer functional style, it provides plentiful functional methods, such as pipe, flip, anyPass, allPass. It’s easy to digest any data set.
For example, it’s way more easy to build up a non-empty string or a specific array assert.
const _isNonEmptyString = R.allPass([
R.pipe(
R.type,
R.equals("String")
),
R.pipe(
R.isEmpty,
R.not
)
]);const _oneOf123 = R.flip(R.contains)([1, 2, 3])
After we have our assert methods by hand, we declare them in YML file.
assert:
status: 200
body:
list:
- id: R._number
title: R._nonEmptyString
pic: R._pic
type: R._oneOf123
Next we parse YML files, and run them with javascript eval() function.
if (!eval("R._number")(value)) {
test.fail(`${value} supposed to be a number`)
}
Prepares and Effects with EJS
When ava tests need runtime parameters, such as random page number, or when ava tests need inputs from previous ava tests, we have to build up a fixture to config ava tests when before or after it’s run.
#ava test in YML
prepare:
$pageIndex: <%-parseInt((Math.random()*10))%>... # http request and ava assert
effect:
$firstId: body.list[0].id
In conclusion, this mechanism of testing has following features:
- config test in declarative yml file, include name, api endpoint, http, asserts, effect…
- render global runtime parameters with EJS before any other test run, such as JWT token
- fake variety values for api test
- render local runtime parameters with EJS before next test run
- to assert api response functionally with Ramda JS
- test makes effect after run for later test to consume
- npm run test
What’s your story about API testing?