Модульное тестирование приватных переменных в Swift - PullRequest
3 голосов
/ 09 мая 2019

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

Класс вычисляет позицию пользователя с помощью BLE и CoreLocation - это не так важно.У меня есть протокол, который при обнаружении нового местоположения я вызываю, и все классы, которые соответствуют этому протоколу, получат идентификатор комнаты и имя комнаты.Итак, что это означает, что буквально все поля в моем классе являются частными, потому что да, нет никаких причин, по которым любой внешний класс должен иметь к ним правильный доступ?Но это также означает, что я могу буквально ничего не тестировать в этом классе, хотя есть довольно много функций, которые я хотел бы протестировать.Я имею в виду, что я мог бы просто сделать переменные внутренними, а не частными, но просто неправильно делать это только для модульного тестирования.Я слышал о внедрении зависимостей, но мне кажется, что это очень много усилий.

Например, у меня есть эта функция:


private var beacons: [AppBeacon] = []
private var serverBeacons:[Beacon] = []

private func addBeacons(serverBeacons: [Beacon]){
        for beacon in serverBeacons {
            let beacon = AppBeacon(id: beacon.id, uuid: beacon.uuid, building: beacon.building, name: beacon.name)
            beacons.append(beacon)
       }
   }

я не могу проверить, был ли массив маяковна самом деле пополнил, как я хотел или нет, например.Общедоступные функции моего класса - это, в основном, функция startLocating, результатом которой являются идентификатор комнаты и ее имя, и я знаю, что при тестировании черного ящика имитируется модульное тестирование (верно?), Мне не следует беспокоиться о промежуточных шагах, но, честно говорятак много функциональности я должен просто сказать, не имеет значения?И предположим, что я заполнил маяки некоторыми значениями rssi по своему выбору, фактический алгоритм определения местоположения выполняется на сервере node.js, так что я, честно говоря, не знаю, что тестировать на стороне клиента?

Это классический MVC, и я никак не могу изменить его архитектуру до того срока, который у меня есть, так что я не знаю, как лучше отсюда пойти?Просто не проверяйте функциональность?Сделать поля внутренними, а не частными?Мы проводим тестирование самого алгоритма на стороне сервера, поэтому тестирование того, является ли идентификатор комнаты ожидаемым идентификатором комнаты, уже протестировано.

В другом посте я прочитал следующее:

«Модульное тестирование по определению - это тестирование черного ящика, что означает, что вы не заботитесь о внутренних элементах тестируемого вами модуля. В основном, вам интересно посмотреть, какой вывод получен на основе входных данных, которые вы даете ему в модульном тесте.по выводам мы можем утверждать о нескольких вещах:

  • результат метода
  • состояние объекта после воздействия на него,
  • взаимодействиес зависимостями у объекта есть

Во всех случаях нас интересует только общедоступный интерфейс, поскольку именно он связывается с остальным миром. Личные вещи не нужныиметь модульные тесты просто потому, что любой частный элемент косвенно используется общедоступным. Хитрость заключается в том, чтобы написать достаточно тестов, которые осуществляют общедоступные элементы, чтобы частный элементОни полностью покрыты.

Кроме того, важно помнить, что модульное тестирование должно проверять спецификации модуля, а не его реализацию.Проверка деталей реализации добавляет тесную связь между кодом модульного тестирования и тестируемым кодом, что имеет большой недостаток: если детали проверенной реализации изменяются, то, вероятно, потребуется также изменить модульный тест, и это уменьшает выгоду,модульный тест для этого куска кода. "

И из-за этого я, по сути, понимаю, что я просто не должен тестировать этот модуль?

Ответы [ 2 ]

0 голосов
/ 10 мая 2019

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

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

0 голосов
/ 09 мая 2019

Во-первых, приведенное вами определение «юнит-теста» довольно необычно: все известные мне литературные определения рассматривают юнит-тестирование метода «стеклянный ящик / белый ящик». Точнее говоря, модульное тестирование как таковое на самом деле не является ни «черным ящиком», ни «белым ящиком» - это метод, используемый для разработки тестовых случаев, который имеет значение. Но нет никаких оснований не применять методики тестирования белого ящика для модульного тестирования. На самом деле, некоторые методы разработки тестов «белого ящика» имеют смысл только при применении для модульного тестирования. Например, когда вы исследуете модульное тестирование, вы столкнетесь с множеством дискуссий о различных критериях покрытия кода, таких как покрытие операторов, покрытие переходов, покрытие условий, MC / DC - для всего этого важно знать реализацию детали кода и учитывайте эти детали реализации при разработке тестового примера.

Но, даже принимая это во внимание, он не сильно изменится для вашего конкретного случая: переменные в вашем коде все еще являются частными :-) Однако вы подходите к проблеме тестирования слишком ограниченно: вы пытаетесь протестировать функция addBeacons сама по себе, в полной изоляции даже от других функций в этом компоненте.

Чтобы проверить addBeacons, ваши тесты должны содержать не только вызов addBeacons, но также вызов некоторой другой функции, результат которой покажет вам, был ли вызов addBeacons успешным. Например, если у вас также есть функция для поиска маяка по имени или положению, вы сначала должны вызвать addBeacon и, чтобы проверить, успешно ли это выполнено, вызвать одну из этих функций, чтобы увидеть, будет ли найден добавленный вами маяк. Эти два вызова будут частью одного и того же теста.

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