You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This question is a broad followup to the response to an enhancement issue. Perhaps the conclusion will be that I should create a separate project with only minimal changes in the TestContainer code. We may also want to create new discussions for the JDBC examples discussed below.
How much testing should "container initialiization" include?
For that matter, what does "container initialization" even mean?
As a concrete example let's say I am launching a database container. There's a clear consensus among the implemented modules that the module should perform a "test query" to ensure that:
the database is running (per log messages and active port)
the provided credentials are valid
the database is responding to queries
So far so good....
But to a developer that's only the first step. For us the "initialization" must include, at a minimum, setting up the database schemas. The JdbcDatabaseContainer already supports this, partially, with JdbcDatabaseContainer#withInitScript(String...). (See sidenote below.) But let's stick with just the existing functionality and assume the container has run some initialization scripts.
So far so good....
But we're not done. We ran a test query above - if we're smart we'll run some additional queries to ensure that we have the expected database schema. We'll want to ensure that static tables, e.g., a list of countries or states, is properly initialized.
Should this be considered part of the container initialization? As a developer I would say "yes" - I want to be able to use my container immediately. Any @BeforeClass methods should be specific to the code being tested, not finishing the container's initialization. At first glance I can and should hide this beyond my own extension to the existing containers but it's possible to imagine situations where I want to perform these tests prior to the start() method returning.
(To be fair many of these situations involve the JdbcDatabaseContainer.)
Sidenote - withInitScript()
Enterprise developers are more likely to use database schema tools like Liquibase instead of a set of initialization scripts. Some require a Connection or DataSource. At this time we can override waitUntilContainerStarted() and make the required calls at that time but that has the usual issues with people forgetting to call super(), the possibility of a change in that method's implementation breaking their code, etc.
It would be much better for this to be handled as a peer to withInitScripts(). I think the best approach may be to add two new methods to JdbcDatabaseContainer, and possibly other containers.
Some drivers. e.g., PostgreSQL, also provide a basic data source provider so those modules could include a default implementation of the first method.
The withInitDataSource() method should be called before the withInitScripts() method since that fits the pattern of using a database schema manager in every container but using different initialization scripts that set up just enough for the tests in each test class.
I mentioned some JdbcDatabaseContainer modules providing a getConnection() method. I've noticed a lot of tests don't properly close everything. jOOQ has a really clever solution to this - you can't get a naked JDBC Connection. Instead everything must be run in a run() method, and jOOQ is responsible for closing the connection.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
This question is a broad followup to the response to an enhancement issue. Perhaps the conclusion will be that I should create a separate project with only minimal changes in the TestContainer code. We may also want to create new discussions for the JDBC examples discussed below.
How much testing should "container initialiization" include?
For that matter, what does "container initialization" even mean?
As a concrete example let's say I am launching a database container. There's a clear consensus among the implemented modules that the module should perform a "test query" to ensure that:
So far so good....
But to a developer that's only the first step. For us the "initialization" must include, at a minimum, setting up the database schemas. The
JdbcDatabaseContainer
already supports this, partially, withJdbcDatabaseContainer#withInitScript(String...)
. (See sidenote below.) But let's stick with just the existing functionality and assume the container has run some initialization scripts.So far so good....
But we're not done. We ran a test query above - if we're smart we'll run some additional queries to ensure that we have the expected database schema. We'll want to ensure that static tables, e.g., a list of countries or states, is properly initialized.
Should this be considered part of the container initialization? As a developer I would say "yes" - I want to be able to use my container immediately. Any
@BeforeClass
methods should be specific to the code being tested, not finishing the container's initialization. At first glance I can and should hide this beyond my own extension to the existing containers but it's possible to imagine situations where I want to perform these tests prior to thestart()
method returning.(To be fair many of these situations involve the
JdbcDatabaseContainer
.)Sidenote - withInitScript()
Enterprise developers are more likely to use database schema tools like Liquibase instead of a set of initialization scripts. Some require a
Connection
orDataSource
. At this time we can overridewaitUntilContainerStarted()
and make the required calls at that time but that has the usual issues with people forgetting to callsuper()
, the possibility of a change in that method's implementation breaking their code, etc.It would be much better for this to be handled as a peer to
withInitScripts()
. I think the best approach may be to add two new methods toJdbcDatabaseContainer
, and possibly other containers.Some drivers. e.g., PostgreSQL, also provide a basic data source provider so those modules could include a default implementation of the first method.
The
withInitDataSource()
method should be called before thewithInitScripts()
method since that fits the pattern of using a database schema manager in every container but using different initialization scripts that set up just enough for the tests in each test class.Sidenote - run(Consumer action) throws SQLException (from jOOQ)
I mentioned some
JdbcDatabaseContainer
modules providing agetConnection()
method. I've noticed a lot of tests don't properly close everything. jOOQ has a really clever solution to this - you can't get a naked JDBC Connection. Instead everything must be run in arun()
method, and jOOQ is responsible for closing the connection.Beta Was this translation helpful? Give feedback.
All reactions