-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
154 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright (c) 2015 Richard North | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
# Test Containers | ||
|
||
Test Containers is a Java library aimed at making it easier to test components or systems that interact with databases and other containerized things. Compared with other approches, Test Containers is intended to achieve a better balance between compatibility, speed, and overhead of external management. | ||
|
||
Test Containers uses Docker to provide lightweight, throwaway instances of real databases and web servers for use in your tests. | ||
|
||
You can use TC to obtain a containerized database in one of two ways: | ||
|
||
### JUnit @Rule/@ClassRule | ||
|
||
This mode starts a container before your tests and tears it down afterwards. This technique is aimed at JUnit tests of isolated components that just need a database temporarily (e.g. DAO tests). Nginx web server containers are also supported currently. | ||
|
||
### Specially modified JDBC URL | ||
|
||
After making a very simple modification to your system's JDBC URL string, Test Containers will provide a disposable stand-in database that can be used without requiring modification to your application code. This is intended to be used for development or integrated testing, when you want consistent, repeatable behaviour without the overhead of managing an external database. | ||
|
||
## Support | ||
|
||
Test Containers currently supports: | ||
|
||
* MySQL | ||
* PostgreSQL | ||
* nginx | ||
|
||
Other container types can be added later. Note that at present, only Docker Official containers from the Docker Hub registry can be used - this needs to be fixed. | ||
|
||
## Comparison with other approaches | ||
|
||
### Database running on development/test machine | ||
|
||
* **Pro:** Perhaps the easiest option to initially 'get working' | ||
* **Con:** Every developer and test environment has to be configured the same way - but frequently isn't, leading to configuration drift and unexpected bugs. | ||
* **Con:** Managing a consistent database state is hard and often ignored, leading to flaky tests and different behaviour across environments or developer machines. | ||
|
||
### Database running in a VM (e.g. using Vagrant) | ||
|
||
* **Pro:** If managed using configuration management tools, this is a strong way to ensure consistent configuration | ||
* **Con:** Restoration of the DB to a clean state isn't well catered for, and again often ignored due to slowness and complexity. | ||
* **Con:** Control of VM state has to be managed externally from the Java test process, creating more moving parts. | ||
|
||
### Using an embedded database (e.g. H2) | ||
|
||
* **Pro:** very fast creation and teardown of databases | ||
* **Pro:** completely controlled within the Java test process, meaning no external moving parts | ||
* **Con:** not fully compatible with the target production database, leading to risk and bugs found late in development. | ||
|
||
### Using Docker directly (e.g. via Fig/Docker compose) | ||
|
||
* **Pro:** full compatibility with target database | ||
* **Con:** external orchestration of containers required; a Java test process cannot obtain new containers on demand for isolated testing. | ||
|
||
## Usage | ||
|
||
### Prerequisites | ||
|
||
Docker or boot2docker (for OS X) must be installed on the machine you are running tests on. | ||
|
||
### JUnit rule | ||
|
||
Add a @Rule or @ClassRule to your test class, e.g.: | ||
|
||
public class SimpleMySQLTest { | ||
@Rule | ||
public MySQLContainerRule mysql = new MySQLContainerRule(); | ||
|
||
Now, in your test code (or a suitable setup method), you can obtain details necessary to connect to this database: | ||
|
||
* `mysql.getJdbcUrl()` provides a JDBC URL your code can connect to | ||
* `mysql.getUsername()` provides the username your code should pass to the driver | ||
* `mysql.getPassword()` provides the password your code should pass to the driver | ||
|
||
Note that if you use @Rule, you will be given an isolated container for each test method. If you use @ClassRule, you will get on isolated container for all the methods in the test class. | ||
|
||
### JDBC URL | ||
|
||
As long as you have TestContainers on your classpath, you can modify regular JDBC connection URLs. | ||
|
||
**Original URL**: `jdbc:mysql://somehostname:someport/databasename` | ||
|
||
Insert `tc:` after `jdbc:` as follows. Note that the hostname, port and database name will be ignored; you can leave these as-is or set them to any value. | ||
|
||
#### Using Test Containers: | ||
|
||
`jdbc:tc:mysql://somehostname:someport/databasename` | ||
|
||
*(Note: this will use the latest version of MySQL)* | ||
|
||
#### Using Test Containers with a fixed version: | ||
|
||
`jdbc:tc:mysql:5.6.23://somehostname:someport/databasename` | ||
|
||
#### Using PostgreSQL: | ||
|
||
`jdbc:tc:postgresql://hostname/databasename` | ||
|
||
#### Using an init script | ||
|
||
Test Containers can run an initscript after the database container is started, but before your code is given a connection to it. The script must be on the classpath, and is referenced as follows: | ||
|
||
`jdbc:tc:mysql://hostname/databasename?TC_INITSCRIPT=somepath/init_mysql.sql` | ||
|
||
This is useful if you have a fixed script for setting up database schema, etc. | ||
|
||
#### Using an init function | ||
|
||
Instead of running a fixed script for DB setup, it may be useful to call a Java function that you define. This is intended to allow you to trigger database schema migration tools. To do this, add TC_INITFUNCTION to the URL as follows, passing a full path to the class name and method: | ||
|
||
`jdbc:tc:mysql://hostname/databasename?TC_INITFUNCTION=org.rnorth.testcontainers.jdbc.JDBCDriverTest::sampleInitFunction` | ||
|
||
The init function must be a public static method which takes a `java.sql.Connection` as its only parameter, e.g. | ||
|
||
public class JDBCDriverTest { | ||
public static void sampleInitFunction(Connection connection) throws SQLException { | ||
// e.g. run schema setup or Flyway/liquibase/etc DB migrations here... | ||
} | ||
... | ||
|
||
## License | ||
|
||
See [LICENSE](LICENSE). | ||
|
||
## Attributions | ||
|
||
This project includes a modified class (ScriptUtils) taken from the Spring JDBC project, adapted under the terms of the Apache license. Copyright for that class remains with the original authors. | ||
|
||
## Copyright | ||
|
||
Copyright (c) 2015 Richard North |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters