Search code examples
swiftxcodexctestxcuitestdata-driven-tests

Issue while parsing JSON file in my XCUITest


JSON file : "credentials"

[
    
{
        
"name" : Tom Harry
        
"email" : [email protected]
        
"password" : tomharry123
    
},
    
    {
        "name" : Sam Billings
        "email" : [email protected]
        "password" : sambillings789
    }
]

Utility file :

import Foundation
import XCTest

class Utils {
    
    static func loadData(filename : String) -> [Any] {
        let filePath = Bundle(for: self).path(forResource: filename, ofType: "json") ?? "default"
        let url = URL(fileURLWithPath: filePath)
        do {
            let data = try Data(contentsOf: url)
            let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
            let array =  json as! [Any]
            if array.isEmpty {
                XCTFail("Source file \(filename) is empty.")
            }
            return array
            }
            catch {
                    XCTFail("File \(filename) not found.")
                    return []
                }
    }
}

TestFile:

import XCTest

class UITests: XCTestCase {
    var app : XCUIApplication!

    override func setUpWithError() throws {
        launchApp()
        continueAfterFailure = false
    }

    func launchApp() {
        app = XCUIApplication()
        app.launch()
        print("APPLICATION IS LAUNCHED")
    }
    
    func signUp(fullName : String, email : String, password : String) {
        let fullNameTextField = app.textFields.matching(identifier: "full name").element
        let emailTextField = app.textFields.matching(identifier: "email").element
        let passwordTextField = app.textFields.matching(identifier: "password").element
        if fullNameTextField.exists {
            fullNameTextField.tap()
            fullNameTextField.typeText(fullName)
        }
        if emailTextField.exists {
            emailTextField.tap()
            emailTextField.typeText(email)
        }
        
        if passwordTextField.exists {
            passwordTextField.tap()
            passwordTextField.typeText(password)
        }
        
        
        
    }
  
    func register() {
        let registerButton = app.buttons.matching(identifier: "register").element
        XCTAssert(registerButton.waitForExistence(timeout: 5), "REGISTER BUTTON IS NOT PRESENT")
        if registerButton.exists {
            print("REGISTER BUTTON IS PRESENT")
            registerButton.tap()
            print("REGISTER BUTTON IS TAPPED")
        }
    }
    
    func testSignUp(){
        let dataSource = Utils.loadData(filename: "credentials")
        for iteration in dataSource {
            guard let user = iteration as? [String : Any] else {return}
            let fullname = user["name"] as! String
            let email = user["email"] as! String
            let password = user["password"] as! String
            signUp(fullName: fullname, email: email, password: password)
        }
    
    }
    
    func testflowtest() {
        register()
        testSignUp()
    }
        
}

After running the testFlowTest function in Test file, "credentials file is not found" error is showing.

I want to fill the Sign up text fields with name, email, password from the JSON file.

This is the image showing the error after using XCTFail("Error: \(error)")

enter image description here


Solution

  • Your JSON isn't properly formatted. Keys and values need to have quotes, and key/value pairs need to be separated by commas:

    [
        {
            "name" : "Tom Harry",
            "email" : "[email protected]",        
            "password" : "tomharry123"    
        },
        
        {
            "name" : "Sam Billings",
            "email" : "[email protected]",
            "password" : "sambillings789"
        }
    ]
    

    Here's code that is paste-able into a Playground that shows that this is parsable (and will fail with your same error if you replace it with your original JSON):

    let data = """
    [
        {
            "name" : "Tom Harry",
            "email" : "[email protected]",
            "password" : "tomharry123"
        },
        
        {
            "name" : "Sam Billings",
            "email" : "[email protected]",
            "password" : "sambillings789"
        }
    ]
    """.data(using: .utf8)!
    
    do {
        let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers)
        print(json)
    } catch {
        print(error)
    }