Best practice for writing API tests

Currently I am automating API tests and I have some questions about “best practices”.

  1. When describing the tests, do you prefer to validate the request response by creating multiple test blocks (it) or do you prefer to validate the entire request response in a single test block?

multiple test blocks (it)

let res;

const randomAccount = {
  'email': 'automation17@yahoo.com',
  'password': '123456',
};

describe('Create accounts with email and password', function() {
  describe('should create a valid account', function() {
    before(function() {
      return accountsHelper.createNewAccount(randomAccount)
        .then(function(response) {
          res = response;
        });
    });

    it('should return status code 200', function(done) {
      expect(res.status).to.equal(commonData.statusCode.ok);
      done();
    });

    it('should return response', function(done) {
      expect(res.body.admin).to.equal(false);
      done();
    });

    after(function() {
      return accountsHelper.deleteAccount();
    });
  });
});

in a single test block (it)

let res;

const randomAccount = {
  'email': 'automation17@yahoo.com',
  'password': '123456',
};

describe('Create accounts with email and password', function() {
    it('should create a valid account', function() {
      return accountsHelper.createNewAccount(randomAccount)
        .then(function(res) {
          expect(res.status).to.equal(commonData.statusCode.ok);
          expect(res.body.admin).to.equal(false);
        });
    });

    after(function() {
      return accountsHelper.deleteAccount();
    });
});

Multiple test blocks (it)

Advantages - In the report, it is more readable for those reading the tests to know what exactly failed: if was the status code, if was the response or even if a property should return number but returned string, since those tests will be written separately
Disadvantages - depends on the before hook to receive the response

In a single test block (it)

Disadvantages - when the test fails, it is not very readable if the status, response or data type failed because the whole test will be in a single block

So how are you doing? What do they suggest? Any material on this subject?

I tend to go with the multiple assertions - it’s way more expensive to make dozens of requests to check each part of a complicated response object than to have all the assertions after a single request.

I don’t know Javscript or what framework you’re using there, but if the errors are hard to read, I assume that expect() allows you to pass custom error messages to add verbosity to increase the clarity of the failure.

I’ve also seen folks use error aggregators so that tests don’t blame on the first fail, but check the whole response so if there are multiple discrepancies, they’ll know that upfront, rather than fixing the first, running the test, and then finding the next assertion fails as well.