I'm trying to write some tests for a web application based on HTTP REST API. I used to verify the contents uploaded through a POST request with a GET request. But I realized that I've tested a request using other requests. In other words, my tests depended on each other in most cases. Because of this situation, whenever I changed an API spec, I often had to change all the tests indirectly affected.
For example,
testGetA() =>
expect(app.get('/A')).to.have.json('this', '{"foo":"bar"}')
testPostA() => {
expect(app.delete('/A')).to.have.status(200)
expect(app.post('/A', '{"foo":"bar"}')).to.have.status(200)
expect(app.get('/A')).to.have.json('this', '{"foo":"bar"}')
}
testPostA
uses DELETE, POST, and GET sequentially to test posting resource A
. But if I change the spec of GET /A
so that GET /A
responds with {"foo":"barzoo"}
, I must change not only testGetA
but also testPostA
.
For unit test of HTTP REST API, if POST
request returns 200 OK
, I don't think you need to verify the posted content via GET
. The purpose of HTTP API unit test is to verify the communication between client and server, not to verify the server side logic (like whether the posted data is stored in database).
Here are some detail reason:
POST /A
100% works but GET /A
works only in 90% case (due to some server side bugs). In this situation, the test case of POST /A
will fail sometimes, which does not make any sense.POST /A
only save data in one global variable and then just return 200 OK
? (This behavior is wrong, as the second POST /A
request will override the first one). In this situation, your POST
-GET
verification will pass, but obviously it can't guarantee any server side logic.In summary, unit test of HTTP API and unit test of server side logic are 2 different things. It is better to make HTTP API test only focus on communication (If POST /A
request is sent in correct format, it should get 200 OK
. If the format is wrong, it should get 400 BAD REQUEST
etc.), and make server side logic test focus on logic.