Вступление
Модульное тестирование требует изоляции отдельных компонентов от их зависимостей. Зависимости заменяются на макеты , которые имитируют определенные варианты использования. Таким образом, мы можем проверить поведение компонента в тесте в различных сценариях внешнего контекста.
Веб-компоненты могут быть протестированы модульно с использованием сервисов бизнес-логики. Сервисы могут быть проверены на наличие ложных хранилищ данных. Но уровень доступа к данным не является хорошим кандидатом для модульного тестирования , потому что операторы базы данных должны быть проверены на соответствие действующей системе баз данных.
Варианты тестирования базы данных интеграции
В идеале, наши тесты должны работать с производственной базой данных. Но использование выделенного сервера базы данных неосуществимо, поскольку у нас, скорее всего, есть несколько разработчиков для запуска таких интеграционных тестов. Чтобы изолировать параллельные тестовые прогоны, каждому разработчику потребуется отдельный каталог базы данных. Добавление инструмента непрерывной интеграции усугубляет ситуацию, поскольку параллельно должно выполняться больше тестов.
Урок 1. Нам нужна разветвленная база данных, связанная с набором тестов
При запуске набора тестов база данных должна быть запущена и сделана доступной только для этого конкретного экземпляра набора тестов. В основном у нас есть следующие варианты:
- Встроенная база данных в памяти
- Временный порожденный процесс базы данных
Ошибка тестирования базы данных в памяти
Java предлагает на выбор несколько вариантов реляционной базы данных в памяти:
Встраивание базы данных в память происходит быстро, и каждая JVM может запускать свою собственную изолированную базу данных. Но мы больше не тестируем действительный производственный механизм базы данных, потому что наши интеграционные тесты будут проверять поведение приложения для непроизводственной системы баз данных.
Использование инструмента ORM может создать ложное впечатление, что все базы данных равны, особенно когда весь сгенерированный код SQL совместим с SQL-92 .
Что хорошо для поддержки базы данных инструмента ORM, может лишить вас возможности использовать специфичные для базы данных функции запросов ( оконные функции , общие табличные выражения , PIVOT ).
Таким образом, база данных тестирования интеграции в памяти может не поддерживать такие сложные запросы. Это может привести к снижению охвата кода или к тому, что разработчики будут вынуждены использовать только общие, но ограниченные возможности SQL-запросов.
Даже если ваше ядро производственной базы данных предоставляет вариант в памяти , могут существовать рабочие различия между действительной и облегченной версиями базы данных.
Урок 2. Базы данных в памяти могут создать ложное впечатление о том, что ваш код также будет работать в рабочей базе данных
Создание производственной временной базы данных
Тестирование на реальной производственной базе данных гораздо более ценно, и именно поэтому я вырос, чтобы оценить эту альтернативу.
При использовании MongoDB мы можем выбрать встроенный плагин Монго . Этот проект с открытым исходным кодом создает процесс внешней базы данных, который может быть связан с текущим жизненным циклом набора тестов.
Если вы используете Maven, вы можете воспользоваться модулем embedmongo-maven-plugin :
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
< plugin > < groupId >com.github.joelittlejohn.embedmongo</ groupId > < artifactId >embedmongo-maven-plugin</ artifactId > < version >${embedmongo.plugin.version}</ version > < executions > < execution > < id >start</ id > < goals > < goal >start</ goal > </ goals > < configuration > < port >${embedmongo.port}</ port > < version >${mongo.test.version}</ version > < databaseDirectory >${project.build.directory}/mongotest</ databaseDirectory > < bindIp >127.0.0.1</ bindIp > </ configuration > </ execution > < execution > < id >stop</ id > < goals > < goal >stop</ goal > </ goals > </ execution > </ executions > </ plugin > |
При запуске плагина выполняются следующие действия:
- Пакет MongoDB загружается:
12345
[INFO] --- embedmongo-maven-plugin:0.1.12:start (start) @ mongodb-facts ---
Download Version{2.6.1}:Windows:B64 START
Download Version{2.6.1}:Windows:B64 DownloadSize: 135999092
Download Version{2.6.1}:Windows:B64 0% 1% 2% 3% 4% 5% 6% 7% 8% 9% 10% 11% 12% 13% 14% 15% 16% 17% 18% 19% 20% 21% 22% 23% 24% 25% 26% 27% 28% 29% 30% 31% 32% 33% 34% 35% 36% 37% 38% 39% 40% 41% 42% 43% 44% 45% 46% 47% 48% 49% 50% 51% 52% 53% 54% 55% 56% 57% 58% 59% 60% 61% 62% 63% 64% 65% 66% 67% 68% 69% 70% 71% 72% 73% 74% 75% 76% 77% 78% 79% 80% 81% 82% 83% 84% 85% 86% 87% 88% 89% 90% 91% 92% 93% 94% 95% 96% 97% 98% 99% 100% Download Version{2.6.1}:Windows:B64 downloaded with 3320kb
/s
Download Version{2.6.1}:Windows:B64 DONE
- После запуска нового набора тестов пакет MongoDB распаковывается в уникальном месте во временной папке ОС.
12
Extract C:\Users\vlad\.embedmongo\win32\mongodb-win32-x86_64-2008plus-2.6.1.zip START
Extract C:\Users\vlad\.embedmongo\win32\mongodb-win32-x86_64-2008plus-2.6.1.zip DONE
- Встроенный экземпляр MongoDB запущен.
01020304050607080910111213141516171819
[mongod output]note: noprealloc may hurt performance
in
many applications
[mongod output] 2014-10-09T23:25:16.889+0300 [DataFileSync] warning: --syncdelay 0 is not recommended and can have strange performance
[mongod output] 2014-10-09T23:25:16.891+0300 [initandlisten] MongoDB starting : pid=2384 port=51567 dbpath=D:\wrk\vladmihalcea\vladmihalcea.wordpress.com\mongodb-facts\target\mongotest 64-bit host=VLAD
[mongod output] 2014-10-09T23:25:16.891+0300 [initandlisten] targetMinOS: Windows 7
/Windows
Server 2008 R2
[mongod output] 2014-10-09T23:25:16.891+0300 [initandlisten] db version v2.6.1
[mongod output] 2014-10-09T23:25:16.891+0300 [initandlisten] git version: 4b95b086d2374bdcfcdf2249272fb552c9c726e8
[mongod output] 2014-10-09T23:25:16.891+0300 [initandlisten] build info: windows sys.getwindowsversion(major=6, minor=1, build=7601, platform=2, service_pack=
'Service Pack 1'
) BOOST_LIB_VERSION=1_49
[mongod output] 2014-10-09T23:25:16.891+0300 [initandlisten] allocator: system
[mongod output] 2014-10-09T23:25:16.891+0300 [initandlisten] options: { net: { bindIp:
"127.0.0.1"
, http: { enabled:
false
}, port: 51567 }, security: { authorization:
"disabled"
}, storage: { dbPath:
"D:\wrk\vladmihalcea\vladmihalcea.wordpress.com\mongodb-facts\target\mongotest"
, journal: { enabled:
false
}, preallocDataFiles:
false
, smallFiles:
true
, syncPeriodSecs: 0.0 } }
[mongod output] 2014-10-09T23:25:17.179+0300 [FileAllocator] allocating new datafile D:\wrk\vladmihalcea\vladmihalcea.wordpress.com\mongodb-facts\target\mongotest\
local
.ns, filling with zeroes...
[mongod output] 2014-10-09T23:25:17.179+0300 [FileAllocator] creating directory D:\wrk\vladmihalcea\vladmihalcea.wordpress.com\mongodb-facts\target\mongotest\_tmp
[mongod output] 2014-10-09T23:25:17.240+0300 [FileAllocator]
done
allocating datafile D:\wrk\vladmihalcea\vladmihalcea.wordpress.com\mongodb-facts\target\mongotest\
local
.ns, size: 16MB, took 0.059 secs
[mongod output] 2014-10-09T23:25:17.240+0300 [FileAllocator] allocating new datafile D:\wrk\vladmihalcea\vladmihalcea.wordpress.com\mongodb-facts\target\mongotest\
local
.0, filling with zeroes...
[mongod output] 2014-10-09T23:25:17.262+0300 [FileAllocator]
done
allocating datafile D:\wrk\vladmihalcea\vladmihalcea.wordpress.com\mongodb-facts\target\mongotest\
local
.0, size: 16MB, took 0.021 secs
[mongod output] 2014-10-09T23:25:17.262+0300 [initandlisten] build index on:
local
.startup_log properties: {
v
: 1, key: { _id: 1 }, name:
"_id_"
, ns:
"local.startup_log"
}
[mongod output] 2014-10-09T23:25:17.262+0300 [initandlisten] added index to empty collection
[mongod output] 2014-10-09T23:25:17.263+0300 [initandlisten] waiting
for
connections on port 51567
[mongod output] Oct 09, 2014 11:25:17 PM MongodExecutable start
INFO: de.flapdoodle.embed.mongo.config.MongodConfigBuilder$ImmutableMongodConfig@26b3719c
- Для срока службы текущего набора тестов вы можете увидеть процесс embedded-mongo:
12345678
C:\Users\vlad>
netstat
-ano | findstr 51567
TCP 127.0.0.1:51567 0.0.0.0:0 LISTENING 8500
C:\Users\vlad>TASKLIST
/FI
"PID eq 8500"
Image Name PID Session Name Session
# Mem Usage
========================= ======== ================ =========== ============
extract-0eecee01-117b-4d2 8500 RDP-Tcp
#0 1 44,532 K
- Когда тестовый набор завершен, монтирование встраивается
0102030405060708091011121314
[INFO] --- embedmongo-maven-plugin:0.1.12:stop (stop) @ mongodb-facts ---
2014-10-09T23:25:21.187+0300 [initandlisten] connection accepted from 127.0.0.1:64117
#11 (1 connection now open)
[mongod output] 2014-10-09T23:25:21.189+0300 [conn11] terminating,
shutdown
command
received
[mongod output] 2014-10-09T23:25:21.189+0300 [conn11] dbexit:
shutdown
called
[mongod output] 2014-10-09T23:25:21.189+0300 [conn11]
shutdown
: going to close listening sockets...
[mongod output] 2014-10-09T23:25:21.189+0300 [conn11] closing listening socket: 520
[mongod output] 2014-10-09T23:25:21.189+0300 [conn11]
shutdown
: going to flush diaglog...
[mongod output] 2014-10-09T23:25:21.189+0300 [conn11]
shutdown
: going to close sockets...
[mongod output] 2014-10-09T23:25:21.190+0300 [conn11]
shutdown
: waiting
for
fs preallocator...
[mongod output] 2014-10-09T23:25:21.190+0300 [conn11]
shutdown
: closing all files...
[mongod output] 2014-10-09T23:25:21.191+0300 [conn11] closeAllFiles() finished
[mongod output] 2014-10-09T23:25:21.191+0300 [conn11]
shutdown
: removing fs lock...
[mongod output] 2014-10-09T23:25:21.191+0300 [conn11] dbexit: really exiting now
[mongod output] Oct 09, 2014 11:25:21 PM de.flapdoodle.embed.process.runtime.ProcessControl stopOrDestroyProcess
Вывод
Плагин embed-mongo нигде не медленнее, чем любые системы баз данных отношений в памяти. Меня удивляет, почему нет такой опции для СУБД с открытым исходным кодом (например, PostgreSQL). Это отличная идея проекта с открытым исходным кодом, и, возможно, Flapdoodle OSS также предложит поддержку реляционных баз данных.
- Код доступен на GitHub .
Ссылка: | Интеграционное тестирование выполнено правильно с Embedded MongoDB от нашего партнера JCG Влада Михалча в блоге Влада Михалча . |