Почему использование UITableViewCell из модульного теста вызывает ловушку Trace / BPT? - PullRequest
2 голосов
/ 06 сентября 2010

У меня есть следующий минимальный тестовый пример в минимальном проекте, созданном после GHUnit README:

#import <GHUnitIOS/GHUnitIOS.h>
#import <UIKit/UIKit.h>

@interface MyTest : GHTestCase { }
@end

@implementation MyTest

- (BOOL)shouldRunOnMainThread {
  return YES;
}

- (void)testFoo {
  UITableViewCell *cell =
      [[UITableViewCell alloc] initWithStyle:UITableViewStylePlain
                             reuseIdentifier:@"foo"];

  NSLog(@"cell: %@", cell);
  NSLog(@"cell.textLabel: %@", cell.textLabel);
}

@end

Работает нормально, когда я использую Build and Run в симуляторе в Xcode. Тем не менее, когда я выполните в терминале следующую команду:

GHUNIT_CLI=1 xcodebuild -target Tests -configuration Debug -sdk iphonesimulator4.0 build

Я получаю этот вывод:

Running: /Users/<user>/Desktop/tmp/TestApp/build/Debug-iphonesimulator/Tests.app/Tests -RegisterForSystemEvents
Tests(39346) malloc: protecting edges
Tests(39346) malloc: recording malloc stacks to disk using standard recorder
Tests(39346) malloc: enabling scribbling to detect mods to free blocks
Tests(39346) malloc: process 39249 no longer exists, stack logs deleted from /tmp/stack-logs.39249.Tests.ac1JfL.index
Tests(39346) malloc: stack logs being written into /tmp/stack-logs.39346.Tests.t8LG4p.index
Test Suite 'Tests' started.
MyTest/testFoo 2010-09-06 23:24:25.006 Tests[39346:903] cell: <UITableViewCell: 0x5a6d190; frame = (0 0; 320 44); layer = <CALayer: 0x5a6d390>>
RunTests.sh: line 28: 39346 Trace/BPT trap          $RUN_CMD
Command /bin/sh failed with exit code 133
Command /bin/sh failed with exit code 133
** BUILD FAILED **

Эта вещь "Trace / BPT Trap" происходит и с OCUnit, и я надеялся, что GHUnit решил бы это, но это не в командной строке. Кто-нибудь есть идеи, что это о? Кажется, это связано с использованием UIKit из контекста, которым вы не являетесь предполагается, но я не понимаю, что именно ограничение.

Ответы [ 2 ]

4 голосов
/ 08 ноября 2010

Существует ряд классов UIKit, которые просто не работают вне контекста работающего UIApplication.Например, создание всего, что пытается использовать UIFont (например, UILabel), будет беспорядочно взорваться (то есть ошибка сегментации или подобное) за пределами работающего UIApplication.UIActivityIndicatorView аналогично завершится с ошибкой.

На самом деле невозможно последовательно протестировать код, который зависит от UIKit вне симулятора или устройства.К счастью, вы можете запустить код, скомпилированный для симулятора, без фактического запуска процесса симулятора.Я полагаю, что настройка GTM для тестов iOS делает это;Я знаю, что Cedar делает это для спецификаций iOS.Я не достаточно знаком с GHUnit, чтобы сказать, может ли он это делать.

Если вы хотите запускать такие спецификации из командной строки, вам необходимо соответствующим образом установить некоторые переменные среды.Вам нужно установить DYLD_ROOT_PATH в каталог для iOS SDK, с которым вы связываете, IPHONE_SIMULATOR_ROOT в тот же каталог SDK, а CFFIXED_USER_HOME во что-то непустое (я использую случайный временный каталог).После того, как они установлены, вы можете выполнить двоичный файл, который вы создали для SDK симулятора, вызвав его напрямую и добавив -RegisterForSystemEvents в командной строке.

Например, вы можете проверить Cedar Rakefile (я больше всего знаком с этим, потому что написал его; другие не менее достоверные примеры могут существовать в GTM или GHUnit).Посмотрите на нижнюю часть файла в задаче: uispecs для командной строки, которую он запускает.

0 голосов
/ 07 сентября 2010

У меня были подобные сбои при тестировании UIViews и UIViewControllers в GHUnit, при запуске из командной строки, потому что нет интерфейса для отображения видов.

Вы должны быть в состоянии проверить логику в некоторых из этих классов, если вы не вызываете методы, которые заставляют их рисовать себя на экране. Вы можете инициировать представление, если оно не добавлено в основную иерархию представлений. Избегать drawRect в UIView и loadView в UIViewController помогло мне.

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

...