Pruebas
Prueba usando un reino predeterminado
La forma más sencilla de usar y probar aplicaciones respaldadas por Realm es usar el dominio predeterminado. Para evitar sobrescribir los datos de la aplicación o filtrar el estado entre pruebas, configure el dominio predeterminado con un nuevo archivo para cada prueba.
// 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 } }
Inyección de instancias de 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.") }
Simplifique las pruebas con proyecciones de clases
Nuevo en la versión 10.21.0.
Si desea trabajar con un subconjunto de las propiedades de un objeto para realizar pruebas, puede crear una proyección de clase. Una proyección de clase es una abstracción del modelo que permite transferir, renombrar o excluir propiedades de objetos de realm. Si bien esta función simplifica la implementación del modelo de vista, también simplifica las pruebas con Realm.
Ejemplo
Este ejemplo utiliza los modelos de objetos y la proyección de clase de la página Definir y usar proyecciones de clase.
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.
Con esta proyección de clase, no necesitamos acceder ni contabilizar propiedades que no necesitamos probar.
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") }
Objetivos de prueba
No vincule el framework Realm directamente con su objetivo de prueba. Esto puede provocar que sus pruebas fallen con el mensaje de excepción "El tipo de objeto 'YourObject' no está administrado por Realm". Desvincular Realm de su objetivo de prueba debería resolver este problema.
Compila los archivos de clase de tu modelo en los objetivos de tu aplicación o framework; no los añadas a los objetivos de las pruebas unitarias. De lo contrario, esas clases se duplican durante las pruebas, lo que puede generar problemas difíciles de depurar.
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
Depuración con Realm Studio
Realm Studio te permite abrir y editar dominios locales. Es compatible con Mac, Windows y Linux.
LLDB
La depuración de aplicaciones que utilizan la API Swift de Realm debe realizarse a través de la consola LLDB.
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
Resolver problemas de compilación
Algunos desarrolladores experimentan problemas de compilación tras instalar el SDK de Realm Swift mediante CocoaPods o Carthage. Las causas comunes de estos problemas incluyen:
Problemas de instalación:
Error en la instalación inicial.
Uso de una versión no compatible del administrador de dependencias
Problemas con la herramienta de compilación:
Las herramientas de compilación tienen cachés obsoletos
Actualización de las versiones de la herramienta de compilación
Realizar cambios en la configuración de su proyecto, como por ejemplo:
Agregar un nuevo objetivo
Compartir dependencias entre objetivos
Una solución que a menudo soluciona estos problemas es eliminar los datos derivados y limpiar la carpeta de compilación de Xcode.
Restablecer el estado de integración de Cocoapods
Ejecute estos comandos en la terminal, en la raíz de su proyecto:
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
Ejecute estos comandos en la terminal, en la raíz de su proyecto:
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.
Problemas al abrir Realm antes de cargar la interfaz de usuario
Es posible que al abrir un reino se produzcan fallos inmediatos con mensajes de error relacionados con propiedades opcionales u obligatorias. Problemas con el modelo de objetos pueden causar este tipo de fallos. Estos errores ocurren después de abrir un reino, pero antes de acceder a la interfaz de usuario.
Realm tiene una fase de "descubrimiento de esquemas" cuando se abre un dominio en el dispositivo. En este momento, Realm examina el esquema de los objetos que administra. Puede especificar que un dominio determinado administre solo un subconjunto de objetos en su aplicación.
Si observa errores relacionados con las propiedades durante la detección de esquemas, es probable que se deban a problemas del esquema y no a problemas con los datos de un objeto específico. Por ejemplo, podría observar errores de detección de esquemas si define una relación de uno a uno como obligatoria en lugar de opcional.
Para depurar estos fallos, verifique el esquema que ha definido.
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 hay propiedades definidas para el modelo
El SDK de Realm Swift utiliza la función de reflexión del lenguaje Swift para determinar las propiedades de su modelo en tiempo de ejecución. Si experimenta un fallo similar al siguiente, confirme que su proyecto no haya deshabilitado los metadatos de reflexión:
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
En dispositivos iOS o iPad con poca memoria disponible, o donde tienes una aplicación que consume mucha memoria y utiliza varios reinos o muchas notificaciones, es posible que encuentres el siguiente error:
libc++abi: terminating due to an uncaught exception of type std::bad_alloc: std::bad_alloc
Este error generalmente indica que no se puede asignar un recurso porque no hay suficiente memoria disponible.
Si está compilando para iOS 15+ o iPad 15+, puede agregar el derecho de direccionamiento virtual extendido para resolver este problema.
Agregue estas claves a su lista de propiedades y establezca los valores en true:
<key>com.apple.developer.kernel.extended-virtual-addressing</key> <true/> <key>com.apple.developer.kernel.increased-memory-limit</key> <true/>
El paquete Swift Target no se puede construir 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 solucionar este error, desvincule el paquete Realm o RealmSwift de su destino de compilación. Puede hacerlo en Xcode siguiendo estos pasos:
En tu proyecto Targets, seleccione su objetivo de compilación.
Vaya a la pestaña Build Phases.
Expandir el elemento Link Binary With Libraries.
Seleccione
RealmoRealmSwifty haga clic en el botón Eliminar elementos (-) para eliminar el binario innecesario.Si utiliza Swift o las API de Swift y Objective-C, mantenga
RealmSwift.Si utiliza únicamente API de Objective-C, conserve
Realm.
Ahora tu objetivo debería construirse sin este error.
