Я практиковался и читал о тестовой разработке.
До сих пор у меня все хорошо, потому что многое из этого просто, но у меня есть вопросы по поводу того, что тестировать.
о некоторых классах, таких как один ниже.
public function testPersonEnrollmentDateIsSet()
{
//For the sake of simplicity I've abstracted the PDO/Connection mocking
$PDO = $this->getPDOMock();
$PDOStatement = $this->getPDOStatementMock();
$PDO->method('prepare')->willReturn($PDOStatement);
$PDOStatement->method('fetch')->willReturn('2000-01-01');
$AccountMapper = $this->MapperFactory->build(
'AccountMapper',
array($PDO)
);
$Person = $this->EntityFactory->build('Person');
$Account = $this->EntityFactory->build('Account');
$Person->setAccount($Account);
$AccountMapper->getAccountEnrollmentDate($Person);
$this->assertEquals(
'2001-01-01',
$Person->getAccountEnrollmentDate()
);
}
Я немного не уверен, стоит ли мне вообще это проверять по двум причинам.
В приведенном выше примере я проверяю, правильно ли отображается значение. Просто логика одна, издевается над соединением, поэтому нет базы данных. Это потрясающе, потому что я могу запустить тест исключительно бизнес-логики без каких-либо других разработчиков, чтобы установить или настроить зависимость от базы данных.
Тем не менее, отдельная конфигурация может быть запущена по требованию для проверки самих запросов SQL, что в целом является другим типом проверки. При этом также консолидация тестов SQL для запуска отдельно от модульных тестов.
Тест будет точно таким же, как указано выше, за исключением PDO
соединение не будет смоделировано и будет реальным соединением с базой данных.
Я разрываюсь, потому что, хотя это тестирование для разных вещей, это по сути дублированный код.
Если я избавляюсь от модульного теста, я всегда ввожу необходимую зависимость от базы данных. По мере роста кодовой базы тесты со временем будут становиться все медленнее, никаких готовых тестов; дополнительные усилия других разработчиков по настройке конфигурации.
Если я избавлюсь от теста базы данных, я не смогу гарантировать, что SQL вернет ожидаемую информацию.
Мои вопросы:
Это законная причина, чтобы сохранить оба теста?
Стоит ли это того, или это может стать кошмаром технического обслуживания?
Судя по вашим комментариям, вы хотите проверить, что делает PDO. (Являются prepare
, execute
и т.д … меня правильно зовут и делают то, что я от них ожидаю?)
Это не то, что вы хотите сделать здесь с модульным тестированием. Вы не хотите тестировать PDO или любую другую библиотеку, и вы не должны тестировать логику или поведение PDO. Будьте уверены, что эти вещи были сделаны людьми, ответственными за PDO.
То, что вы хотите проверить, — это правильное выполнение ВАШЕГО кода и, следовательно, логика ВАШЕГО кода. Вы хотите проверить getAccountExpirationDate
и так результаты, которые вы ожидаете от него. Не те результаты, которые вы ожидаете от вызовов PDO.
Поэтому, и если я правильно понимаю ваш код, вам нужно только проверить, что срок годности $Person
вы даете как параметр был установлен с ожидаемым значением из $result
-> Если вы не правильно использовали PDO, то тест все равно не пройден!
Правильный тест может быть:
UserMapper
объект и открыть транзакцию БД$result
Person
объект с правильным taxId
а также clientID
разыскивать $result
из вашего запросаUserMapper->getAccountExpirationDate($Person)
$Person->expirationDate
равно, что вы поселились, как ожидалось от $result
Вы также можете проверить формат даты и т. Д. Все, что связано с логикой, которую вы внедрили.
Если вы собираетесь тестировать такие вещи во многих тестах, используйте setUp
а также tearDown
инициализировать и откатывать вашу БД после каждого теста.
Это законная причина, чтобы сохранить оба теста?
Я думаю, никто из ваших простых примеров никогда не сможет определить, какой тест вам нужно пройти. Если вам нравится, вы можете оставить оба. Я говорю это, потому что ответ во многом зависит от неизвестных факторов ваших проектов, включая будущие требования & модификаций.
Лично я не думаю, что вам нужны оба, по крайней мере, для одной и той же функции. Если ваша функция логически легче сломать, чем чувствительная к данным, не стесняйтесь отбрасывать те, которые поддерживаются базой данных. Вы научитесь использовать правильный тип тестов с течением времени.
Да, это.
Это действительная проблема если ваша база данных становится достаточно сложной. Вы используете DBUnit, поэтому я предполагаю, что у вас есть образец базы данных с образцом информации. Со временем производственная база данных может получить несколько модификаций структуры (добавление полей, удаление полей, даже переработку взаимосвязи данных …). Эти вещи добавят вам усилий по поддержке вашей тестовой базы данных. Тем не менее, было бы также полезно, если бы вы поняли, что некоторые изменения в базе данных не правы.
Что не так с требованием зависимости от базы данных?
Во-первых, я не вижу, как дополнительные усилия других разработчиков по настройке конфигурации играют здесь. Вы настроили только один раз, не так ли? На мой взгляд, это второстепенный фактор.
Во-вторых, тесты будут медленными со временем. Конечно. Вы можете рассчитывать на базу данных в памяти, как H2 или же HSQLDB чтобы снизить этот риск, но это, безусловно, займет больше времени. Тем не менее, вам действительно нужно беспокоиться? Большинство этих проверенных данных тестов интеграционный тест. Они должны быть ответственностью Сервер непрерывной интеграции, кто запускает изнурительный тест время от времени, чтобы предотвратить ошибку регрессии. Для разработчиков, я думаю, что мы должны запускать только небольшой набор легких тестов во время разработки.
В конце я хотел бы напомнить вам правило № 1 для использования модульного теста: Проверьте, что может сломаться. Не пишите тесты ради теста. У вас никогда не будет 100% покрытия. Однако, поскольку 20% кода используется в 80% случаев, хорошей идеей может быть сосредоточение усилий на тестировании на основном потоке бизнеса.