Как выполнить постоянство модульного теста?

Как новичок в практике разработки, основанной на тестировании, я часто попадаю в затруднительное положение относительно того, как выполнить модульное тестирование устойчивости к базе данных.

Я знаю, что технически это будет интеграционный тест (а не модульный тест), но я хочу найти лучшие стратегии для следующего:

  1. Тестовые запросы.
  2. Тестовые вставки. Как я узнаю, что вставка пошла не так, если она вышла из строя? Я могу проверить это, вставив, а затем запросив, но как я могу узнать, что запрос был неправильным?
  3. Тестирование обновлений и удалений - так же, как тестовые вставки

Каковы лучшие практики для этого?


Что касается тестирования SQL: я знаю, что это можно сделать, но если я использую O / R Mapper, например NHibernate, он добавляет некоторые бородавки именования в псевдонимах, используемых для выходных запросов, и, поскольку это несколько непредсказуемо, я не уверен Я могу проверить это.

Должен ли я просто отказаться от всего и просто доверять NHibernate? Я не уверен, что это разумно.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
48
0
7 242
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

Вы выполняете модульное тестирование, имитируя соединение с базой данных. Таким образом, вы можете создавать сценарии, в которых определенные запросы в потоке вызова метода завершаются успешно или терпят неудачу. Я обычно строю свои фиктивные ожидания таким образом, что фактический текст запроса игнорируется, потому что я действительно хочу проверить отказоустойчивость метода и то, как он себя обрабатывает - специфика SQL не имеет отношения к этой цели.

Очевидно, это означает, что ваш тест на самом деле не будет проверять, что метод работает, потому что SQL может быть неправильным. Вот здесь и вступают в силу интеграционные тесты. Я ожидаю, что кто-то другой даст более подробный ответ, так как я только начинаю разбираться с ними сам.

Я бы также поиздевался над базой данных и убедился, что запросы соответствуют вашим ожиданиям. Есть риск, что тест проверит неправильный sql, но это будет обнаружено в интеграционных тестах.

Проблема, с которой я столкнулся при постоянном модульном тестировании, особенно без ORM и, таким образом, имитируя вашу базу данных (соединение), заключается в том, что вы действительно не знаете, успешны ли ваши запросы. Возможно, ваши запросы специально разработаны для конкретной версии базы данных и успешно выполняются только с этой версией. Вы никогда этого не узнаете, если будете издеваться над своей базой данных. Так что, на мой взгляд, постоянство модульного тестирования имеет ограниченное применение. Вы всегда должны добавлять тесты, запускаемые для целевой базы данных.

Я согласен, хотя я никогда не был сторонником TDD, я определенно вижу много преимуществ TDD, но чтобы игнорировать реальность и не проверять по-настоящему свои записи, входящие и исходящие из вашей базы данных, вы понятия не имеете, что на самом деле будет делать ваше приложение. в дикой природе. Так много раз, прежде чем мне приписывали "ошибку", что мой код не работал, я запускал свои модульные тесты и обнаруживал, что другой разработчик топтал весь мой sproc (злые злые sprocs) и никогда не заботился о запуске мои модульные тесты, чтобы увидеть, как они взорвали всю систему.

Chris Marisic 19.11.2009 17:50

Что касается NHibernate, я бы определенно рекомендовал просто издеваться над NHibernate API для модульных тестов - доверяйте библиотеке, чтобы она поступала правильно. Если вы хотите убедиться, что данные действительно поступают в БД, выполните интеграционный тест.

Технически юнит-тесты устойчивости не являются юнит-тестами. Это интеграционные тесты.

С C#, использующим mbUnit, вы просто используете атрибуты SqlRestoreInfo и RollBack:

    [TestFixture]
    [SqlRestoreInfo(<connectionsting>, <name>,<backupLocation>]
    public class Tests
    {
      
        [SetUp]
        public void Setup()
        {
        
        }

        [Test]
        [RollBack]
        public void TEST()
        {
           //test insert. 
        }
    }

То же самое можно сделать и в NUnit, за исключением того, что названия атрибутов немного отличаются.

Что касается проверки, если ваш запрос успешен, вам обычно нужно выполнить второй запрос, чтобы увидеть, была ли база данных изменена так, как вы ожидали.

Ответ принят как подходящий

Загляните в блок БД. Это библиотека Java, но должен быть эквивалент C#. Это позволяет вам подготовить базу данных с набором данных, чтобы вы знали, что находится в базе данных, а затем вы можете взаимодействовать с DB Unit, чтобы увидеть, что находится в базе данных. Он может работать со многими системами баз данных, поэтому вы можете использовать свою фактическую настройку базы данных или использовать что-то еще, например HSQL в Java (реализация базы данных Java с опцией в памяти).

Если вы хотите проверить, что ваш код правильно использует базу данных (что вам, скорее всего, следует делать), то это способ изолировать каждый тест и убедиться, что база данных подготовила ожидаемые данные.

Я написал здесь сообщение о модульное тестирование уровня данных, которое касается именно этой проблемы. Приносим извинения за (постыдный) плагин, но статья слишком длинная, чтобы размещать ее здесь.

Надеюсь, это поможет вам - за последние 6 месяцев он очень хорошо сработал для меня в трех активных проектах.

С уважением,

Роб Джи

Как и Майк Стоун сказал, DbUnit отлично подходит для приведения базы данных в известное состояние перед запуском ваших тестов. Когда ваши тесты будут завершены, DbUnit может вернуть базу данных в состояние, в котором она была до запуска тестов.

DbUnit (Java)

DbUnit.NET

Обычно я создаю репозиторий, использую его, чтобы сохранить свою сущность и получить новую. Затем я утверждаю, что извлеченное равно сохраненному.

Для проектов на основе JDBC можно использовать мой фреймворк Acolyte: http://acolyte.eu.org. Он позволяет смоделировать доступ к данным, которые вы хотите протестировать, используя абстракцию JDBC, без необходимости управлять конкретной тестовой БД.

Другие вопросы по теме