Pruebas
Test Using a Default Realm
The easiest way to use and test Realm-backed applications is to use the default realm. To avoid overriding application data or leaking state between tests, set the default realm to a new file for each test.
// A base class which each of your Realm-using tests should inherit from rather // than directly from XCTestCase class TestCaseBase: XCTestCase { override func setUp() { super.setUp() // Use an in-memory Realm identified by the name of the current test. // This ensures that each test can't accidentally access or modify the data // from other tests or the application itself, and because they're in-memory, // there's nothing that needs to be cleaned up. Realm.Configuration.defaultConfiguration.inMemoryIdentifier = self.name } }
Inyectar instancias Realm
Otra forma de probar código relacionado con Realm es que todos los métodos que se quieran probar acepten una instancia de realm como argumento. Esto permite pasar diferentes realms al ejecutar la aplicación y al probarla.
Por ejemplo, supongamos que su aplicación tiene un método para GET Un perfil de usuario de una API JSON. Quiere comprobar que el perfil local se creó correctamente:
// Application Code func updateUserFromServer() { let url = URL(string: "http://myapi.example.com/user") URLSession.shared.dataTask(with: url!) { data, _, _ in let realm = try! Realm() createOrUpdateUser(in: realm, with: data!) } } public func createOrUpdateUser(in realm: Realm, with data: Data) { let object = try! JSONSerialization.jsonObject(with: data) as? [String: String] try! realm.write { realm.create(User.self, value: object, update: .modified) } } // Test Code let realmPath = URL(fileURLWithPath: "...") func testThatUserIsUpdatedFromServer() { let config = Realm.Configuration(fileURL: realmPath) let testRealm = try! Realm(configuration: config) let jsonData = "{\"email\": \"help@realm.io\"}".data(using: .utf8)! // In our test, we're passing in the testRealm. This is where we'd // pass in our "real" realm in the application code above. createOrUpdateUser(in: testRealm, with: jsonData) XCTAssertEqual(testRealm.objects(User.self).first!.email, "help@realm.io", "User was not properly updated from server.") }
Simplify Testing with Class Projections
New in version 10.21.0.
If you want to work with a subset of an object's properties for testing, you can create a class projection. A class projection is a model abstraction where you can pass through, rename, or exclude realm object properties. While this feature simplifies view model implementation, it also simplifies testing with Realm.
Ejemplo
This example uses the object models and the class projection from the Define and Use Class Projections page.
En este ejemplo, creamos un objeto de dominio utilizando el modelo de objetos completo. Luego, recuperamos el objeto como una proyección de clase, trabajando solo con un subconjunto de sus propiedades.
With this class projection, we don't need to access or account for properties that we don't need to test.
func testWithProjection() { let realm = try! Realm() // Create a Realm object, populate it with values let jasonBourne = Person(value: ["firstName": "Jason", "lastName": "Bourne", "address": [ "city": "Zurich", "country": "Switzerland"]]) try! realm.write { realm.add(jasonBourne) } // Retrieve all class projections of the given type `PersonProjection` // and filter for the first class projection where the `firstName` property // value is "Jason" let person = realm.objects(PersonProjection.self).first(where: { $0.firstName == "Jason" })! // Verify that we have the correct PersonProjection XCTAssert(person.firstName == "Jason") // See that `homeCity` exists as a projection property // Although it is not on the object model XCTAssert(person.homeCity == "Zurich") // Change a value on the class projection try! realm.write { person.firstName = "David" } // Verify that the projected property's value has changed XCTAssert(person.firstName == "David") }
Test Targets
Don't link the Realm framework directly to your test target. This can cause your tests to fail with an exception message "Object type 'YourObject' is not managed by the Realm." Unlinking Realm from your test target should resolve this issue.
Compile your model class files in your application or framework targets; don't add them to your unit test targets. Otherwise, those classes are duplicated when testing, which can lead to difficult-to-debug issues.
Exponga todo el código necesario para las pruebas a sus objetivos de pruebas unitarias. Utilice el modificador de acceso public o @testable.
Dado que usas Realm como un framework dinámico, debes asegurarte de que el objetivo de tu prueba unitaria pueda encontrarlo. Agrega la ruta principal a RealmSwift.framework a las "Rutas de búsqueda del framework" de tu prueba unitaria.
Depuración
Debug Using Realm Studio
Realm Studio enables you to open and edit local realms. It supports Mac, Windows and Linux.
LLDB
Debugging apps using Realm's Swift API must be done through the LLDB console.
Aunque el script LLDB permite inspeccionar el contenido de las variables de tu dominio en la interfaz de usuario de Xcode, esto aún no funciona en Swift. Estas variables mostrarán datos incorrectos. En su lugar, usa el comando po de LLDB para inspeccionar el contenido de los datos almacenados en un dominio.
Solución de problemas
Resuelve Problemas de compilación
Algunos desarrolladores experimentan problemas de compilación después de instalar el Swift SDK de Realm a través de CocoaPods o Carthage. Causas comunes de estos problemas incluyen:
Installation issues:
Error en la instalación inicial.
Using an unsupported version of the dependency manager
Problemas con la herramienta de compilación:
Las herramientas de compilación tienen cachés desactualizados
Updating build tool versions
Making changes to your project setup, such as:
Adding a new target
Sharing dependencies across targets
A fix that often clears these issues is to delete derived data and clean the Xcode build folder.
Reset the Cocoapods Integration State
Run these commands in the terminal, in the root of your project:
pod cache clean Realm pod cache clean RealmSwift pod deintegrate || rm -rf Pods pod install --repo-update --verbose # Assumes the default DerivedData location: rm -rf ~/Library/Developer/Xcode/DerivedData
Restablecer el estado de dependencia administrado por Carthage
Run these commands in the terminal, in the root of your project:
rm -rf Carthage # Assumes default DerivedData location: rm -rf ~/Library/Developer/Xcode/DerivedData carthage update
Importante
Esto actualizará todas las dependencias gestionadas por Carthage, no solo aplicación Services.
Issues Opening Realm Before Loading the UI
You may open a realm and immediately see crashes with error messages related to properties being optional or required. Issues with your object model can cause these types of crashes. These errors occur after you open a realm, but before you get to the UI.
Realm has a "schema discovery" phase when a realm opens on the device. At this time, Realm examines the schema for any objects that it manages. You can specify that a given realm should manage only a subset of objects in your application.
Si ves errores relacionados con propiedades durante el descubrimiento de esquemas, probablemente se deban a problemas de esquema y no a problemas con los datos de un objeto específico. Por ejemplo, puedes ver errores de descubrimiento de esquemas si definir una relación uno a uno como obligatoria en lugar de opcional.
To debug these crashes, check the schema you've defined.
Se pueden identificar problemas de descubrimiento de esquemas porque ocurren antes de que se cargue la interfaz de usuario. Esto significa que ningún elemento de la interfaz de usuario intenta usar incorrectamente una propiedad y que no hay objetos en memoria que puedan contener datos incorrectos. Si se producen errores relacionados con las propiedades después de que se cargue la interfaz de usuario, probablemente no se deban a un esquema no válido. Es probable que estos errores se deban a datos incorrectos, mal escritos o faltantes.
No Properties are Defined for Model
The Realm Swift SDK uses the Swift language reflection feature to determine the properties in your model at runtime. If you get a crash similar to the following, confirm that your project has not disabled reflection metadata:
Terminating app due to uncaught exception 'RLMException', reason: 'No properties are defined for 'ObjectName'.
Si configura SWIFT_REFLECTION_METADATA_LEVEL = none, Realm no podrá detectar elementos secundarios de tipos, como propiedades y enumeraciones. Reflection está habilitado de forma predeterminada si su proyecto no define específicamente un nivel para esta configuración.
Mala asignación/No hay suficiente memoria disponible
In iOS or iPad devices with little available memory, or where you have a memory-intensive application that uses multiple realms or many notifications, you may encounter the following error:
libc++abi: terminating due to an uncaught exception of type std::bad_alloc: std::bad_alloc
Este error normalmente indica que un recurso no se puede asignar porque no hay suficiente memoria disponible.
If you are building for iOS 15+ or iPad 15+, you can add the Extended Virtual Addressing Entitlement to resolve this issue.
Add these keys to your Property List, and set the values to true:
<key>com.apple.developer.kernel.extended-virtual-addressing</key> <true/> <key>com.apple.developer.kernel.increased-memory-limit</key> <true/>
El objetivo del paquete Swift no se puede compilar dinámicamente
Cambiado en la versión 10.49.3.
La versión 680010.49.3 del SDK de Swift modificó los detalles de instalación del paquete con el Gestor de Paquetes Swift (SPM). Al actualizar desde una versión anterior del paquete a la versión 710010.49.3 o posterior, podría aparecer un error de compilación similar al siguiente:
Swift package target `Realm` is linked as a static library by `TargetName` and `Realm`, but cannot be built dynamically because there is a package product with the same name.
Para resolver este error, desvincula cualquiera de los paquetes Realm o RealmSwift de tu objetivo de compilación. Puedes hacer esto en Xcode siguiendo estos pasos:
En tu proyecto Targets, seleccione su objetivo de compilación.
Vaya a la pestaña Build Phases.
Expand the Link Binary With Libraries element.
Selecciona
RealmoRealmSwifty haz clic en el botón remover elementos (-) para eliminar el binario innecesario.Si emplea Swift o APIs de Swift y Objective-C, mantenga
RealmSwift.Si solo utilizas APIs de Objective-C, mantén
Realm.
Ahora tu objetivo debería construirse sin este error.
