A new approach to explicitly wait DB responses using Screenplay Pattern

Updated: Jul 28

Context.

Have you ever tested on a system that makes asynchronous calls to a DB? If so, you might see that your tests are prone to not being repeatable (they will pass and fail for no “apparent reason”). There are many reasons why we need to check the DB status, even if this is an action that you don’t expect a user to perform. For example, imagine that you are automating a subcutaneous test because during the process you don’t have a UI to test on, so in part of that process you need to check if a record was saved correctly in the BD, but how do you do it? Do you know exactly when it was saved? How do you make an explicit wait for that operation?




Then...

You realize that there are no Serenity BDD Screenplay tasks or interactions to perform explicit waits on the DB and they just exist for UI purposes, which is expected but does not always apply in real situations. So, if you are using Java, for example, you would try to implement a Thread.sleep(). This might work, but when our steps are artificially slowed down by the Thread.sleep() declarations, it takes more time to not only run and troubleshoot existing tests but also to develop new ones.


Good, now, what do I do?...

If we are writing automated tests that interact with databases, we are forced to use Thread.sleep() when the automation is faster than database operations. This causes the test to fail when it queries a record that is being processed in the DB, causing problems that slow down the entire suite, making the tests more fragile and can hide application problems.

Fortunately, db-digging-automation is here to help you implement explicit waits and ensure that your automated tests do not fail if the database log is not present when we try to query




1. Download the db-digging-automation library.


Let's go to the following link https://mvnrepository.com/artifact/co.com.devco/db-digging-automation and download the library as a dependency in your project.


2. So easy to write, so easy to implement.


Just write the following line of code so that your test does not fail if the database record is not present when it tries to query it.


DigUntil.executeThe(query).withIntervalsOf(1).forNoMoreThan(5).seconds().andReturnResult();

The previous line will execute the "query" with intervals of 1 second until the time limit of 5 seconds (it is recommended to set the system timeout) and it will return the result.


3. The function of each piece of code.


DigUntil - It's our first interaction.
executeThe(query) - receives the query of type PreparedStatement or Statement.
withIntervalsOf(1) - how often will the query be executed, milliseconds or seconds (this is an optional method, the default interval is 100 milliseconds)
forNoMoreThan(5) - time limit for waiting, milliseconds or seconds.
milliseconds() - how do you want to handle the wait, you can put seconds().
andReturnResult() - method that execute the query.


…Our database query is now optimized!



So, what happens when we implement db-digging-automation?


Well... the library can run the query continuously until it finds the result or until the agreed time limit is reached, handling exceptions such as: not finding a record, SQL exceptions, runtime exceptions, and throwable exceptions.

And that's it… I encourage you to check it out today! If you have any questions or comments, let me know.



Thank you for reading!






404 views0 comments