使用 SQLite3 进行单元测试

Posted

技术标签:

【中文标题】使用 SQLite3 进行单元测试【英文标题】:Unit Testing with SQLite3 【发布时间】:2018-05-06 11:51:40 【问题描述】:

我正在编写单元测试并将 SQLite3 与他的内存模式一起使用。

我这样做是因为我需要为每个测试提供一个新的数据库,这样我就可以并行运行测试而不会相互影响。

但是,当然,我进行的测试越多,这就越慢。

我可以用 sqlite3 做任何优化吗,另一个更好的工作流程(例如一个好的模拟库)或另一个解决方案来解决这个问题?我需要运行原始查询。

目前我使用 knexjs,但这与几乎所有数据访问库有关。

【问题讨论】:

为什么要针对真实数据库运行测试?假设您以模拟形式从数据库中获取某些数据,并基于此对您的业务逻辑进行单元测试,这还不够吗?在我看来,您尝试做的更像是集成测试。 是的,对于查询,这是真的。但是插入和更新呢?模拟数据库引用等。 对于单元测试,我相信我的持久层实际上能够存储数据,并且我只会覆盖边缘情况——例如通过单元测试进行适当的异常处理。我并不是说针对适当的测试数据库运行查询是不好的,但是这些测试的设计速度较慢,您所能做的就是加快它们的运行速度。一定程度。 确实如此。我想我正在切换到某种模拟库。谢谢! @k0pernikus @dknaack 对数据库查询进行单元测试通常非常浪费时间,因此进行集成测试听起来是个好主意。如果 inmemory sqlite 变得太慢,您要进行多少次测试?这样你应该能够每秒进行数百次测试......可能不是你的测试中慢速部分的 sqlite。 【参考方案1】:

您无需对数据库运行原始查询。

在单元测试的范围内,您可以假设您的持久层正常工作,即它能够更新插入和删除。

在编写单元测试时,模拟掉你的数据库连接。关于单元测试,对数据库执行查询并不重要,但您的业务逻辑在获取某些输入时以特定方式运行。 (这也可能意味着让您的模拟数据库连接引发异常,以确保您的应用程序以故障安全的方式运行。)

无论环境如何(本地、暂存甚至生产环境),让集成测试实际对测试数据库运行查询都是有价值的。

然而,根据定义,这些设置更慢且更难,并且只能在一定程度上并行化。 (如果你过于依赖他们,your test setup resembles an ice cone and not a pyramid。)

它们仍然适用于业务关键型功能(例如购物车点击)。但是,如果您的重点是编写单元测试,请确保您对应用程序而不是持久层进行单元测试。

【讨论】:

以上是关于使用 SQLite3 进行单元测试的主要内容,如果未能解决你的问题,请参考以下文章

Iphone 单元测试:使用 SQL

Android怎样进行单元测试

使用MOCK对象进行单元测试

无法开始业力测试 - 无法解析模块 [sqlite3] 等

使用本机单元测试项目在 Visual Studio 2017 中对 C 代码进行单元测试

Java应用XVIII在 Java 中使用JUnit5进行单元测试和自动化测试