Chi*_*Lan 88 postgresql unit-testing postgresql-performance
我想运行一个只在内存中运行的小型PostgreSQL数据库,用于我编写的每个单元测试.例如:
@Before
void setUp() {
String port = runPostgresOnRandomPort();
connectTo("postgres://localhost:"+port+"/in_memory_db");
// ...
}
Run Code Online (Sandbox Code Playgroud)
理想情况下,我将在版本控件中检查一个postgres可执行文件,单元测试将使用该版本控件.
有点像HSQL
,但对于postgres.我怎样才能做到这一点?
我可以获得这样的Postgres版本吗?如何指示不使用磁盘?
Cra*_*ger 69
(从使用内存中的PostgreSQL移动我的答案并将其推广):
我无法弄清楚如何运行内存Postgres数据库进行测试.可能吗?
不,这是不可能的.PostgreSQL在C中实现并编译为平台代码.与H2或Derby不同,你不能只是加载它jar
并将其作为一次性内存数据库启动.
与SQLite(也是用C语言编写并编译为平台代码)不同,PostgreSQL也无法在进程中加载.它需要多个进程(每个连接一个),因为它是一个多处理,而不是多线程架构.多处理要求意味着您必须将postmaster作为独立进程启动.
我建议简单地编写测试以期望特定的主机名/用户名/密码工作,并让测试工具CREATE DATABASE
成为一次性数据库,然后DROP DATABASE
在运行结束时.从属性文件,构建目标属性,环境变量等获取数据库连接详细信息.
使用您已经拥有的数据库的现有PostgreSQL实例是安全的,只要您提供给单元测试的用户不是超级用户,只有具有CREATEDB
权限的用户.在最坏的情况下,您将在其他数据库中创建性能问题.我更喜欢运行完全独立的PostgreSQL安装进行测试.
或者,如果你真的渴望,你可以有你的测试工具定位initdb
和postgres
二进制文件,运行initdb
创建数据库,修改pg_hba.conf
到trust
,运行postgres
启动它一个随机端口上,创建一个用户,创建一个数据库,并运行测试.您甚至可以在jar中捆绑多个体系结构的PostgreSQL二进制文件,并在运行测试之前将当前体系结构的二进制文件解压缩到临时目录.
我个人认为这是一个应该避免的重大痛苦; 只需配置一个测试数据库就更容易了.然而,随着include_dir
支持的出现,它变得更容易了postgresql.conf
; 现在你可以只追加一行,然后为所有其余部分写一个生成的配置文件.
有关如何安全地提高PostgreSQL性能以进行测试的更多信息,请参阅我之前就此主题撰写的详细解答:优化PostgreSQL以进行快速测试
有些人在PostgreSQL方言模式下使用H2数据库来运行测试.我认为这几乎和使用SQLite进行测试和使用PostgreSQL进行生产部署的Rails人一样糟糕.
H2支持一些PostgreSQL扩展并模拟PostgreSQL方言.然而,就是这样 - 仿真.你会发现H2接受查询的区域,但PostgreSQL没有,行为不同等等.在撰写本文时,你还会发现很多地方PostgreSQL支持做一些H2不能做的事情 - 就像窗口函数一样.
如果您了解此方法的局限性并且数据库访问很简单,那么H2可能没问题.但在这种情况下,你可能是抽象数据库的ORM的更好候选者,因为你还没有使用它有趣的功能 - 在这种情况下,你不必再关心数据库的兼容性了.
千万不能使用表空间来创建一个"内存"数据库.它不仅没有必要,因为它无论如何都不会显着提高性能,但它也是一种很好的方法来破坏对同一PostgreSQL安装中你可能关心的任何其他内容的访问.9.4文档现在包含以下警告:
警告
即使位于主PostgreSQL数据目录之外,表空间也是数据库集群的组成部分,不能被视为数据文件的自治集合.它们依赖于主数据目录中包含的元数据,因此无法附加到其他数据库集群或单独备份.同样,如果丢失表空间(文件删除,磁盘故障等),数据库群集可能会变得不可读或无法启动.将表空间放在像ramdisk这样的临时文件系统上会危及整个集群的可靠性.
因为我注意到有太多人这样做并遇到麻烦.
(如果你已经这样做了,你可以找到mkdir
丢失的表空间目录,让PostgreSQL再次启动,然后DROP
是丢失的数据库,表等.最好不要这样做.)
Erw*_*ter 66
或者您可以在ramfs/tempfs中创建TABLESPACE并在那里创建所有对象.
我最近指的是一篇关于在Linux上做到这一点的文章.
这可能会危及整个数据库集群的完整性.
阅读手册中添加的警告.
所以这只是消耗性数据的一种选择.
对于单元测试,它应该工作得很好.如果在同一台计算机上运行其他数据库,请确保使用单独的数据库集群(具有自己的端口)是安全的.
a_h*_*ame 41
Postgres无法做到这一点.它不提供像HSQLDB或MySQL那样的进程内/内存引擎.
如果要创建一个自包含的环境,可以将Postgres二进制文件放入SVN(但它不仅仅是一个可执行文件).
在使用此操作之前,您需要运行initdb来设置测试数据库.这可以通过批处理文件或使用Runtime.exec()来完成.但请注意,initdb不是那么快的东西.你肯定不想为每个测试运行它.你可能会在测试套件之前运行它.
但是,虽然可以这样做,但我建议您使用专门的Postgres安装,只需在运行测试之前重新创建测试数据库.
您可以使用模板数据库重新创建测试数据库,这使得创建它非常快(比每次测试运行initdb 快很多)
Rub*_*bms 25
现在可以通过OpenTable中的嵌入式PostgreSQL组件在JUnit测试中运行PostgreSQL的内存实例:https://github.com/opentable/otj-pg-embedded.
通过将依赖项添加到otj-pg嵌入式库(https://mvnrepository.com/artifact/com.opentable.components/otj-pg-embedded),您可以在@Before中启动和停止自己的PostgreSQL实例. @Afer挂钩:
EmbeddedPostgres pg = EmbeddedPostgres.start();
Run Code Online (Sandbox Code Playgroud)
他们甚至提供了一个JUnit规则来自动让JUnit为您启动和停止PostgreSQL数据库服务器:
@Rule
public SingleInstancePostgresRule pg = EmbeddedPostgresRules.singleInstance();
Run Code Online (Sandbox Code Playgroud)
And*_*ejs 11
您可以使用TestContainers启动PosgreSQL docker容器进行测试:http://testcontainers.viewdocs.io/testcontainers-java/usage/database_containers/
TestContainers提供了一个JUnit @ Rule/@ ClassRule:此模式在测试之前启动容器内的数据库,然后将其撕掉.
例:
public class SimplePostgreSQLTest {
@Rule
public PostgreSQLContainer postgres = new PostgreSQLContainer();
@Test
public void testSimple() throws SQLException {
HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setJdbcUrl(postgres.getJdbcUrl());
hikariConfig.setUsername(postgres.getUsername());
hikariConfig.setPassword(postgres.getPassword());
HikariDataSource ds = new HikariDataSource(hikariConfig);
Statement statement = ds.getConnection().createStatement();
statement.execute("SELECT 1");
ResultSet resultSet = statement.getResultSet();
resultSet.next();
int resultSetInt = resultSet.getInt(1);
assertEquals("A basic SELECT query succeeds", 1, resultSetInt);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 10
如果你可以使用docker,你可以将postgresql数据目录挂载到内存中进行测试
docker run --tmpfs=/data -e PGDATA=/data postgres
Run Code Online (Sandbox Code Playgroud)
现在有来自俄罗斯搜索公司 Yandex 的内存版本 PostgreSQL:https : //github.com/yandex-qatools/postgresql-embedded
它基于 Flapdoodle OSS 的嵌入过程。
使用示例(来自 github 页面):
// starting Postgres
final EmbeddedPostgres postgres = new EmbeddedPostgres(V9_6);
// predefined data directory
// final EmbeddedPostgres postgres = new EmbeddedPostgres(V9_6, "/path/to/predefined/data/directory");
final String url = postgres.start("localhost", 5432, "dbName", "userName", "password");
// connecting to a running Postgres and feeding up the database
final Connection conn = DriverManager.getConnection(url);
conn.createStatement().execute("CREATE TABLE films (code char(5));");
Run Code Online (Sandbox Code Playgroud)
我正在使用它一段时间。它运作良好。
更新:这个项目不再被积极维护
Please be adviced that the main maintainer of this project has successfuly
migrated to the use of Test Containers project. This is the best possible
alternative nowadays.
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
71674 次 |
最近记录: |