Creating Some Tests: Approaches

Get to know different approaches which can be used to test our application.

We'll cover the following

What should be tested in this application, considering that tests require minimal work to develop and be maximally informative?

Approach 1

One approach might be to create a collection of tests, one for each API route and HTTP method, that double-check that the database has been properly updated. For example, when a letter is guessed, has the game progressed correctly? Has it correctly identified whether the game is won or lost? This idea is tempting because it seems to provide a means of assuring that each step is correct. I would disagree. To capture the complexity of the updates, the test writer needs to revisit the original logic and essentially recreate it. This can be as much work as writing the original. And in the end, if the test was written with the same understanding as the actual API code was, then it will likely make the same logical errors and fail to detect those errors.

Approach 2

One approach that would be useful with this code would be to test the API against unexpected inputs, such as extra or missing JSON fields, unexpected types, invalid IDs, and so on. The solution to this is to begin each method by checking that the input is as expected. Alternatively, we could make use of data checking functionality, most notably Marshmallow. For example, the POST method of the Games resource expects a payload with both a username and a language specification. This can be checked with:

if not (games_api.payload and
        isinstance(games_api.payload, dict) and
        'username' in games_api.payload and
        isinstance(games_api.payload['username'], str) and
        'language' in games_api.payload and
        games_api.payload['language'] is in ('en', 'fr', 'es')):
    games_api.abort(400, 'New game POST requires valid username and language')

Get hands-on with 1200+ tech skills courses.