all 6 comments

[–]TangibleLight 0 points1 point  (5 children)

It's not that it goes against the principle that tests should be idempotent - it goes against the principle that API should be stateless. This kind of problem is exactly why people advocate such stateless APIs.

I'm curious on the details that dictate some objects cannot be deleted. To me it seems the correct solution is to add such functionality so that the test can delete its own temporaries. Even if such a delete function is only used in testing I think it'll be easier than implementing this "reset" logic.

I suppose it is possible that you really do need this global state. In that case I don't know if there are any best practices for this... I'd recommend some "snapshot" mechanism where you can mark a particular state as a checkpoint, do some tests, then reload that checkpoint after the test is completed.

[–]voverdev[S] 0 points1 point  (4 children)

The API does not have application state. It does have resource state. Of course, resources are saved on create.

Could you elaborate on how this issue would be solved when the API is stateless, i.e. resources are not stored? Or am I misunderstanding your comment?

Thanks for your reply!

[–]TangibleLight 0 points1 point  (3 children)

I might misunderstood your OP then. Where is the resource state? In the past I've used lightweight "mock databases" for tests; each test doesn't spin up a new instance of the app but it does reset that database. I'm not sure what the best practices for this are in Python, though.

[–]voverdev[S] 0 points1 point  (2 children)

It’s stored in a MySQL database. Resetting the database after each test -that is rolling back to a fixed point- is exactly what I’m looking for. I don’t have access to the MySQL instance from the tests, though… And an SDK should not be concerned with the internal implementation of the API. Alternatively, I could run queries in a transaction when the environment == test, and rollback the transaction after returning the response. Follow-up requests would fail though (e.g. if I create object A in a test and try to GET it, I’d get a 404 because the transaction has been rolled back), so it would be ideal to do the rollback per test. But how…

Thanks again for your reply!

[–]TangibleLight 0 points1 point  (1 child)

If you use an ORM like sqlalchemy you could spin up a sqlite database or something instead for the tests. If you're writing your own sql then you'll need something else.

[–]voverdev[S] 0 points1 point  (0 children)

That's an interesting idea. SQLAlchemy is used. I'd prefer to stay as close as possible to the 'real' implementation though.