A new approach to explicitly wait DB responses using Screenplay Pattern

Context.

Have you been testing on a system that makes asynchronous calls to a DB? If so, you will face that your tests are prone to not be repeatable (they will pass and fail for no “apparent reason”). There are too 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 a part of that process you need to check if a record was saved correctly in the BD, how to 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 not Serenity BDD Screenplay tasks or interactions to perform explicit waits on the DB, they exist just for UI purposes, that is expected, but 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 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, make 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 it.




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 has the ability to run the query continuously until it finds the result or until the agreed time limit is met, handling exceptions such as: not finding a record, sql exceptions, runtime exceptions, 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!






385 views0 comments