Модульное тестирование базовых данных - аварийное завершение с кодом 134 - PullRequest
3 голосов
/ 14 июля 2010

Я настраиваю модульное тестирование для своего приложения с основными данными. Я сталкиваюсь со странной проблемой в довольно простом тесте. Я получаю ошибку:

/Developer/Tools/RunPlatformUnitTests.include:451:0 Test rig '/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.0.sdk/Developer/usr/bin/otest' exited abnormally with code 134 (it may have crashed).

Заголовок для моих модульных тестов:

#import <SenTestingKit/SenTestingKit.h>
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#import "Unit.h"

@interface UnitLogicTests : SenTestCase {
    NSManagedObjectContext *managedObjectContext;
    NSPersistentStoreCoordinator *persistentStoreCoordinator;
    NSManagedObjectModel *managedObjectModel;
    NSPersistentStore *persistentStore;
}
@end

Реализация:

#import "UnitLogicTests.h"

@implementation UnitLogicTests

#pragma mark Setup and Teardown
- (void)setUp {
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles: nil] retain];
    NSLog(@"model: %@", managedObjectModel);
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel];
    persistentStore = [persistentStoreCoordinator addPersistentStoreWithType:NSInMemoryStoreType
                                                               configuration:nil
                                                                         URL:nil
                                                                     options:nil 
                                                                       error:NULL];
    managedObjectContext = [[NSManagedObjectContext alloc] init];
    [managedObjectContext setPersistentStoreCoordinator:persistentStoreCoordinator];
}

- (void)tearDown
{
    [managedObjectContext release];
    managedObjectContext = nil;
    NSError *error = nil;
    STAssertTrue([persistentStoreCoordinator removePersistentStore:persistentStore error:&error], 
                 @"couldn't remove persistent store: %@", error);
    persistentStore = nil;
    [persistentStoreCoordinator release];
    persistentStoreCoordinator = nil;
    [managedObjectModel release];
    managedObjectModel = nil;
}

#pragma mark -
#pragma mark Test Cases
- (void)testThatEnvironmentWorks
{
    STAssertNotNil(persistentStore, @"no persistent store");
}


- (void)testNewUnitDefaults {
    Unit *newUnit = [NSEntityDescription insertNewObjectForEntityForName:@"Unit" 
                                                  inManagedObjectContext:managedObjectContext];
    STAssertEquals(newUnit.floorNumber, 1, @"Default value for new Unit's floor number should be 1");

}

@end

Если я опускаю тест - (void)testNewUnitDefaults, то сборка завершается без ошибок, поэтому что-то в этом последнем тесте бросает его в цикл. Я новичок в этом, поэтому любая помощь будет принята с благодарностью!

Спасибо.

Ответы [ 3 ]

13 голосов
/ 11 ноября 2010

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

Вы можете попробовать получить пакет

[NSBundle bundleForClass:[self class]]

вот мой код, чтобы заставить работать модуль базовых данных

NSBundle * bundle = [NSBundle bundleForClass:[self class]];
managedObjectModel_ = [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:bundle]];

ПРИМЕЧАНИЕ. Просьба также убедиться, что файл .xcdatamodel включен в цель для юнит-теста

2 голосов
/ 14 июля 2010

поместите блок @try .... catch вокруг вашего теста.

Я думаю, что загрузка модели с

[NSManagedObjectModel mergedModelFromBundles: nil]

не работает, как ожидалось

Используя ваш код для инициализации основного стека данных, я получил исключение

+entityForName: could not locate an entity named 'Unit' in this model.

Изменение инициализации модели на следующий код работает нормально:

    // set according to the identifier in your modeltest Info.plist

    NSString* path = [[NSBundle bundleWithIdentifier:@"com.yourcompany.ModelTest"] 
                                     pathForResource:@"CoreDataUnitTest_DataModel" 
                                              ofType:@"mom"];
    NSURL* modelURL = [NSURL URLWithString:path];
    managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

Модульные тесты с OCUnit иногда немного сложны, так как раскрывается очень мало информации об ошибках.

0 голосов
/ 22 июля 2014

После нескольких часов, проведенных в июле 2014 года, этот пост был одним из нескольких, которые частично привели меня к рабочему решению.Нам каким-то образом удалось сломать удивительно хрупкий (и загадочный) механизм, который связывает пакет, в котором находится ваш исходный код, с пакетом, который выполняет модульное тестирование.Кроме того, у вас может быть неправильно названная xcdatamodel.См. Комментарии для объяснений:

-(NSManagedObjectContext *) getManagedObjectContext
{
   NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] init];
   //Replace MyClass with class that is from your data model
   //really any of your classes should work
   NSBundle * bundle = [NSBundle bundleForClass:[MyClass class]];

   //You can uses this line to figure you what your bundle is actually named
   //In my case the because my PRODUCT_NAME had spaces in it they was replaced with '-' 
   //(dashes) and I couldn't divine it from the info.plist and the Build Settings.
   NSString * ident =[bundle bundleIdentifier];


   //This will show you where your app is actually out building temporary files
   //The exact location appears to change every version or to of Xcode so
   //this is useful for figuring out what your model is named
   NSString * bundlePath =[bundle bundlePath];


   //Here replace Name_of_model_without_the_dot_xcdatamodel with the name of your 
   //xcdatamodel file without an extension
   //Some tutorials will have you use AppName.xcdatamodel others will simply name it
   //DataModel.xcdatamodel.
   //In any event if bothe path and path1 return null then check the 
   //bundlePath by going to Finder and pressing Command-Shift-G and pasting 
   //bundlePath into the pop-up. Look around for a mom or momd file thats the name you want!
   NSString* path = [bundle
              pathForResource:@"Name_of_model_without_the_dot_xcdatamodel"
              ofType:@"momd"];

   //If the above 'path' and 'path1' is not then you want to use this line instead
   NSString* path1 = [bundle
                  pathForResource:@"Name_of_model_without the_dot_xcdatamodel"
                  ofType:@"mom"];

   //the above path lines are simply so you can trace if you have a mom or a momd file
   //replace here appropriately 
   NSURL *modelURL = [bundle URLForResource:@"Name_of_model_without the_dot_xcdatamodel" 
       withExtension:@"momd"];

   //the rest is boiler plate:
   NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

   NSPersistentStoreCoordinator *psc =
      [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];

   [psc addPersistentStoreWithType:NSInMemoryStoreType 
      configuration:nil URL:nil options:nil error:nil];

   [moc setPersistentStoreCoordinator:psc];
   return moc;
}

Вот как вы можете использовать вышеуказанный контекст:

-(void)testMyStuff
{

   NSManagedObjectContext* context=[self getManagedObjectContext];
   MyClass *myobj=[NSEntityDescription insertNewObjectForEntityForName:@"MyClass"   
   inManagedObjectContext:context];
}

В заключение, вам также может понадобиться добавить свои исходные файлы и xcmodel в разделеИсточники компиляции »этапов сборки.К сожалению, это меняется практически с каждой версией Xcode.Для Xcode 5:

enter image description here

...