Все еще пишут тесты с TDD, когда в желаемом коде практически нет логики? Зачем? - PullRequest
3 голосов
/ 10 февраля 2011

TDD должен иметь 100% покрытие кода.Означает ли это, что предполагается писать тесты для методов получения и установки свойств, а также другие методы, которые не содержат реальной логики, такие как работа с функциями внешнего API?

Пример 1:

Ниже приведен один пример метода (который также является примером в этом другом SO вопросе , который касается того, как лучше всего его протестировать, если мысобираемся проверить это).Этот метод мало что делает.Это фасад System.ServiceProcess.ServiceController функциональности остановки службы.В настоящее время этот код не был написан с использованием TDD, но если бы это было так, нужно ли это проверять?Здесь очень мало логики.Сам по себе тест не был бы таким полезным.

К вашему сведению: Если вы хотите ответить о том, как лучше всего его протестировать (схема IoC и Adapter Pattern против Detouring), пожалуйста,см. этот другой вопрос SO .

Public Function StopService(ByVal serviceName As String, ByVal timeoutMilliseconds As Double) As Boolean Implements IWindowsServicesService.StopService

    Try
        Dim service As New ServiceController(serviceName)
        Dim timeout As TimeSpan = TimeSpan.FromMilliseconds(timeoutMilliseconds)

        service.[Stop]()

        If timeoutMilliseconds <= 0 Then
            service.WaitForStatus(ServiceControllerStatus.Stopped)
        Else
            service.WaitForStatus(ServiceControllerStatus.Stopped, timeout)
        End If

        Return service.Status = ServiceControllerStatus.Stopped

    Catch ex As Win32Exception
        Return False
    Catch ex As TimeoutException
        Return False
    End Try

End Function

Пример 2:

В случае, если утверждается, что код все еще имеет некоторую логику, и поэтомуон должен быть проверен при выполнении TDD, а как насчет следующего кода, который имеет no logic:

Public Function GetProcess(ByVal serviceName As String) As Process
    Dim managementObject As New ManagementObject(String.Format("Win32_service.Name='{0}'", serviceName))
    Dim processID As Integer = CType(managementObject.GetPropertyValue("ProcessID"), Integer)
    Dim process As Process = process.GetProcessById(processID)
    Return process
End Function

Ответы [ 3 ]

11 голосов
/ 10 февраля 2011

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

Большинство из нас не тестируют простые геттеры и сеттеры специально как частьпроцесс TDD.Но мы не создаем то поле, в котором нужны методы получения и установки, пока нам это не понадобится, где «потребность» определяется как провальный тест.Таким образом, метод получения и установки будет проверен как само собой разумеющееся, поскольку они создаются по мере необходимости методами, которые мы тестируем.

В обоих ваших примерах достаточно логики, чтобы быть достойными тестирования;Я бы проверил их обоих.

5 голосов
/ 10 февраля 2011

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

Представьте себе ситуацию, когда у вас есть простое свойство / функция "нулевой логики", как во втором примере.Предположим, вы реализовали свою собственную версию GetProcessById, которая функционирует немного иначе, но взаимозаменяема с объектом Process.Вы решаете не писать тест для этой функции и говорите: «Ах, я просто делегирую ее в хорошо протестированную библиотеку, я не могу ее испортить».Там твоя первая ошибка.«Я не могу все испортить» - единственная наихудшая ложь, которую программисты когда-либо регулярно говорят себе.

Предположим, через шесть месяцев вы поймете, что вам нужно расширить Process дополнительными вещами.Вы делегируете все правильные методы и переопределяете GetProcessById.Теперь вы официально должны проверить этот метод "нулевой логики".И это беда.Полиморфизм и многие другие особенности языков программирования (даже те, которые не являются строго объектно-ориентированными) приводят к коду, который не выполняет точно того, что вы себе представляете.

Итак, чтоПри этом, если вы придерживаетесь строгой методологии TDD, и вы стремитесь к 100% охвату тестами, вам нужно протестировать «нулевые логические» методы, как и эти два.

ЕдинственноеИсключение, которое я могу себе представить, относится только к .NET, и это автоматически реализуемые свойства, в которых нет смысла проверять правильность работы Getter и Setter, потому что даже если бы они этого не делали, вы ничего не могли бы с этим поделать.Протестируйте объект, обернутый в свойстве, а не само свойство.

Ребята из TDD, достаточно ли это суммируется?

1 голос
/ 10 февраля 2011

Полное раскрытие: Я не использую формальный TDD и у меня никогда не было

В ваших примерах кода инкапсулирован сторонний сложный API для достижения цели.Откуда появятся ошибки?

Большинство ошибок будет вызвано неожиданным, возможно недокументированным поведением из API.Это может быть очень трудно , чтобы заставить эти вещи действовать правильно в любой ситуации (версия для Windows / региональные настройки / настройка сети и т. Д.) Вы можете стать всемирно известным блоггером простодокументирование ошибок и недоразумений, которые люди делали с Win32 API.

  • Наиболее важные тесты - это тесты против реального API .Для создания процессов или сервисов вам понадобится некоторый код установки и демонтажа.
  • Mocking / IoC не очень ценны.Вы просто доказываете, что делаете определенные вызовы API в определенном порядке.Вы должны доказать, что ваш код достигает того, чего вы хотите, во всех ситуациях, с которыми он сталкивается в реальном мире.
  • Я действительно думаю, что вы не можете делать тестовую разработку против макетов здесь.Представьте, что вы обнаружили ошибку в стороннем API ( это случается ).Вам нужно будет обойти ошибку.Возможно, вам даже потребуется полностью изменить свой подход, например, PInvoke для Win32 API или какой-либо COM-объект.В этой ситуации проверенные тесты были бы просто пустой тратой времени.
    1. Сначала вам нужно будет написать обходной путь, который на самом деле работает против реального API.
    2. Тогда вам нужно отредактировать проверенные тесты в соответствии с обходным решением.
    3. Вы не могли сначала отредактировать макетированные тесты, потому что вы должны попробовать обходной путь, чтобы узнать, действительно ли он работает.

My world - это программное обеспечение для настольных компьютеров вертикального рынка.У нас есть библиотека таких процедур, как ваша, и у нас есть реалистичные тесты для них.Иногда мы находим ошибку в определенной версии Windows / региональных настройках / что угодно.Затем мы расширяем тесты, чтобы воспроизвести ошибку и проверить исправление, а также убедиться, что повторно запустили их в нашем наборе тестовых сред. Примечание для читателя: если ваш код должен работать только на одном сервере , возможно, ваш мир отличается , и вам не нужно будет это делать.

...