unitarias tipos tecnicas software pruebas niveles funcionalidad ejemplos diseño componentes cocoa unit-testing xcode nsbundle octest

cocoa - tipos - ¿Por qué el código dentro de las pruebas de unidad no puede encontrar recursos de paquete?



tecnicas de pruebas de software (4)

Con swift Swift 3 la sintaxis self.dynamicType ha quedado en desuso, use esto en su lugar

let testBundle = Bundle(for: type(of: self)) let fooTxtPath = testBundle.path(forResource: "foo", ofType: "txt")

o

let fooTxtURL = testBundle.url(forResource: "foo", withExtension: "txt")

Algún código que estoy probando unidad necesita cargar un archivo de recursos. Contiene la siguiente línea:

NSString *path = [[NSBundle mainBundle] pathForResource:@"foo" ofType:@"txt"];

En la aplicación funciona muy bien, pero cuando se ejecuta mediante el marco de prueba de la unidad pathForResource: devuelve nil, lo que significa que no pudo encontrar foo.txt .

Me he asegurado de que foo.txt esté incluido en la fase de compilación Copy Bundle Resources del objetivo de la prueba unitaria, así que ¿por qué no puede encontrar el archivo?


Confirme que el recurso se agrega al objetivo de prueba.


Cuando el arnés de prueba de la unidad ejecuta su código, el paquete de prueba de la unidad NO es el paquete principal.

Aunque está ejecutando pruebas, no su aplicación, su paquete de aplicaciones sigue siendo el paquete principal. (Presumiblemente, esto evita que el código que está probando busque el paquete incorrecto). Por lo tanto, si agrega un archivo de recursos al conjunto de pruebas de la unidad, no lo encontrará si busca en el paquete principal. Si reemplaza la línea anterior con:

NSBundle *bundle = [NSBundle bundleForClass:[self class]]; NSString *path = [bundle pathForResource:@"foo" ofType:@"txt"];

Luego, su código buscará en el paquete en el que se encuentra la clase de prueba de su unidad, y todo estará bien.


Una implementación Swift:

Swift 2

let testBundle = NSBundle(forClass: self.dynamicType) let fileURL = testBundle.URLForResource("imageName", withExtension: "png") XCTAssertNotNil(fileURL)

Swift 3, Swift 4

let testBundle = Bundle(for: type(of: self)) let filePath = testBundle.path(forResource: "imageName", ofType: "png") XCTAssertNotNil(filePath)

Bundle proporciona formas de descubrir las rutas principales y de prueba para su configuración:

@testable import Example class ExampleTests: XCTestCase { func testExample() { let bundleMain = Bundle.main let bundleDoingTest = Bundle(for: type(of: self )) let bundleBeingTested = Bundle(identifier: "com.example.Example")! print("bundleMain.bundlePath : /(bundleMain.bundlePath)") // …/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Xcode/Agents print("bundleDoingTest.bundlePath : /(bundleDoingTest.bundlePath)") // …/PATH/TO/Debug/ExampleTests.xctest print("bundleBeingTested.bundlePath : /(bundleBeingTested.bundlePath)") // …/PATH/TO/Debug/Example.app print("bundleMain = " + bundleMain.description) // Xcode Test Agent print("bundleDoingTest = " + bundleDoingTest.description) // Test Case Bundle print("bundleUnderTest = " + bundleBeingTested.description) // App Bundle

En Xcode 6 | 7 | 8 | 9, una ruta de paquete de prueba de unidad estará en Developer/Xcode/DerivedData algo así como ...

/Users/ UserName/ Library/ Developer/ Xcode/ DerivedData/ App-qwertyuiop.../ Build/ Products/ Debug-iphonesimulator/ AppTests.xctest/ foo.txt

... que está separado de la ruta del paquete regular Developer/CoreSimulator/Devices (sin unidad de prueba) :

/Users/ UserName/ Library/ Developer/ CoreSimulator/ Devices/ _UUID_/ data/ Containers/ Bundle/ Application/ _UUID_/ App.app/

También tenga en cuenta que el ejecutable de la prueba unitaria está, por defecto, vinculado con el código de la aplicación. Sin embargo, el código de prueba de la unidad solo debe tener Membresía objetivo solo en el paquete de prueba. El código de la aplicación solo debe tener Membresía objetivo en el paquete de la aplicación. En tiempo de ejecución, el paquete de destino de la prueba unitaria se inyecta en el paquete de aplicaciones para su ejecución .

Swift Package Manager (SPM) 4:

let testBundle = Bundle(for: type(of: self)) print("testBundle.bundlePath = /(testBundle.bundlePath) ")

Nota: De manera predeterminada, la swift test línea de comando creará un paquete de prueba MyProjectPackageTests.xctest . Y, el swift package generate-xcodeproj creará un paquete de prueba MyProjectTests.xctest . Estos diferentes paquetes de prueba tienen diferentes caminos . Además, los diferentes paquetes de prueba pueden tener algunas diferencias internas de estructura de directorios y contenido .

En cualquier caso, .bundlePath y .bundleURL devolverán la ruta del paquete de prueba que se está ejecutando actualmente en macOS. Sin embargo, Bundle no está implementado actualmente para Ubuntu Linux.

Además, la swift build línea de comando y la swift test no proporcionan actualmente un mecanismo para copiar recursos.

Sin embargo, con cierto esfuerzo, es posible configurar procesos para usar Swift Package Manger con recursos en macOS Xcode, línea de comandos macOS y entornos de línea de comandos de Ubuntu. Un ejemplo se puede encontrar aquí: 004.4''2 SW Dev Swift Package Manager (SPM) con recursos Qref

Consulte también: Usar recursos en pruebas unitarias con Swift Package Manager