{"id":11657,"date":"2019-12-10T00:53:36","date_gmt":"2019-12-10T05:53:36","guid":{"rendered":"https:\/\/qxf2.com\/blog\/?p=11657"},"modified":"2020-01-02T06:16:56","modified_gmt":"2020-01-02T11:16:56","slug":"build-and-test-ios-app-with-qxf2-framework-and-appium","status":"publish","type":"post","link":"https:\/\/qxf2.com\/blog\/build-and-test-ios-app-with-qxf2-framework-and-appium\/","title":{"rendered":"Build and Test iOS app with Qxf2 Framework and Appium."},"content":{"rendered":"<h3>Why this post?<\/h3>\n<p>In this post, we are going to look into, how to test an iOS app with <a href=\"https:\/\/github.com\/qxf2\/qxf2-page-object-model\">Python-based testing framework<\/a> using appium. This is a step by step procedure, right from building an app, writing a test for iOS app in Python using Qxf2 test automation framework and then actual testing of app with Appium on Mac OS using an iOS Simulator.<\/p>\n<hr \/>\n<h3>Tools we need for iOS testing<\/h3>\n<p><strong>Step 1.<\/strong> Install node.js and npm<br \/>\nWe need node.js for running Appium Server.<\/p>\n<pre lang=\"Python\">brew install node<\/pre>\n<p><strong>Step 2.<\/strong> Install Appium<br \/>\nAppium can be installed through command line or through the link given below:<\/p>\n<pre lang=\"Python\">npm install -g appium<\/pre>\n<p>Install <a href=\"https:\/\/github.com\/appium\/appium-desktop\/releases\/tag\/v1.15.1\">Appium Desktop<\/a>.<\/p>\n<p><strong>Step 3.<\/strong> Install Python and Python client Library for Appium<\/p>\n<pre lang=\"Python\">pip install Appium-Python-Client<\/pre>\n<p><strong>Step 4.<\/strong> XCode<br \/>\nXcode is the development and debug environment for Mac. It provides required tools, files for dev\/automation for Mac and iOS apps. You can get XCode from the App Store.<\/p>\n<p><strong>Step 5.<\/strong> Install XCode command-line tools<br \/>\nrun the following command:<\/p>\n<pre lang=\"Python\">xcode-select --install<\/pre>\n<p><strong>Step 6.<\/strong> Create Apple ID<br \/>\nTo develop, test or run applications on Mac, you need a free Apple ID. You can create the same, using this <a href=\"https:\/\/support.apple.com\/en-us\/HT204316\">link<\/a>. You can add this Apple ID to Xcode as below:<br \/>\nGoto Xcode &#8211; preferences &#8211; account, Add Apple ID<\/p>\n<p><strong>Step 7.<\/strong> Carthage<br \/>\nIn order to launch WebDriverAgent, your macOS will need to have Carthage installed.<\/p>\n<pre lang=\"Python\">brew install Carthage<\/pre>\n<p>In case you need more information on the installation of tools for iOS testing you can refer to one of our previous <a href=\"https:\/\/qxf2.com\/blog\/get-set-test-an-ios-app-using-appium-and-python\/\">Blogs<\/a>. Also, in case you want to refer to videos for installation, this <a href=\"https:\/\/www.youtube.com\/watch?v=-_6C_-CMqSk\" data-rel=\"lightbox-video-0\">link<\/a> will be useful.<\/p>\n<hr \/>\n<h3>Creating an App with Xcode<\/h3>\n<p>We will create a simple app in Swift with Xcode which has two input fields for email and phone number and has a Submit button. To start open Xcode and follow the steps below:<\/p>\n<p>1. Select a new project from the File menu.<br \/>\n2. From iOS Click on &#8220;Single View app&#8221;, Click &#8220;Next&#8221;.<br \/>\n3. Enter the &#8220;Product Name&#8221; as the name of the app you want to create<br \/>\n4. Enter the &#8220;Team&#8221; and &#8220;Organization Name&#8221;.<br \/>\n5. With all the above details &#8220;Bundle Identifier&#8221; will be generated. We need a &#8220;Bundle Identifier&#8221;, for running the test, keep that handy.<br \/>\n6. Enter the language with which we want to create the app, in our case it is Swift.<br \/>\n7. Select the &#8220;User Interface&#8221; as Storyboard.<br \/>\n8. If you want to include Unit tests and UI tests, you can tick those options and Click on Next.<br \/>\n9. Then select the workspace where we want this app to be created.<br \/>\n10. One will be then redirected to workspace for an app, we need to create.<br \/>\n11. One can find many files\/folders getting created.<br \/>\n12. To create an app, in &#8220;ViewController.swift&#8221; file we have to write code to define what action needs to be taken after entering the details in the app. In our app, once the user enters the details like mail and phone number and clicks on &#8220;Submit&#8221; a flash message should display as &#8220;Thanks for entering the details&#8221;.<\/p>\n<pre lang=\"Swift\">import UIKit\r\n\r\nclass ViewController: UIViewController {\r\n\r\n    override func viewDidLoad() {\r\n        super.viewDidLoad()\r\n        \/\/ Do any additional setup after loading the view, typically from a nib.\r\n    }\r\n\r\n    @IBAction func submit(_ sender: UIButton) {\r\n        let alert = UIAlertController.init(title: \"ThankYou\", message: \"Thank you for submitting details\", preferredStyle: UIAlertController.Style.alert)\r\n        alert.addAction(UIAlertAction(title: \"OK\", style: UIAlertAction.Style.default, handler: nil))\r\n        self.present(alert, animated: true, completion: nil)\r\n    }\r\n\r\n\r\n}\r\n<\/pre>\n<p>13. Then comes the design of the app layout. So for this, there is a &#8220;storyboard&#8221; file called &#8220;Main.storyboard&#8221;. Click on the same, users can draw here the basic layout of their app. There is an option Library. It has several options to pull for an app to be built. On the right-hand side of the screen, there is an option &#8220;+&#8221;. Click on the same. Click on the required Object and pull it to Storyboard. In this case, we need &#8220;Text Field&#8221;, &#8220;Label&#8221; and &#8220;Button&#8221;.<br \/>\n<a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-03-at-2.44.04-PM-1.png\" data-rel=\"lightbox-image-0\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-large wp-image-11876\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-03-at-2.44.04-PM-1-1024x640.png\" alt=\"\" width=\"1024\" height=\"640\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-03-at-2.44.04-PM-1-1024x640.png 1024w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-03-at-2.44.04-PM-1-300x188.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-03-at-2.44.04-PM-1-768x480.png 768w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-03-at-2.44.04-PM-1.png 1439w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/p>\n<p>14. Linking of an app, UI with viewcontroller.swift. In this app after entering details like email and phone number and clicking on Submit button a flash message on the screen should be displayed. So we need to link the viewcontroller.swift to main.storyboard, &#8220;Submit&#8221; button.<br \/>\n<a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-03-at-2.57.59-PM-1.png\" data-rel=\"lightbox-image-1\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-large wp-image-11877\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-03-at-2.57.59-PM-1-1024x636.png\" alt=\"\" width=\"1024\" height=\"636\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-03-at-2.57.59-PM-1-1024x636.png 1024w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-03-at-2.57.59-PM-1-300x186.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-03-at-2.57.59-PM-1-768x477.png 768w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-03-at-2.57.59-PM-1.png 1434w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/p>\n<p>15. Now it is time to build an app. From the tab, &#8220;Product&#8221;, there is an option, &#8220;Build&#8221;. On clicking this option, the build process gets initiated. If no issues are seen, &#8220;Build succeeded&#8221; is flashed on the screen. Then on the left pane, under the &#8220;Products&#8221; folder, the user can find .app file.<\/p>\n<hr \/>\n<h3>Writing Code to test an app with Qxf2 Framework<\/h3>\n<p>For testing the app we built, let&#8217;s have a look at how to write a test for this app.<\/p>\n<p>The Mobile test case is as below:<\/p>\n<pre lang=\"Python\">import os, sys, time\r\nsys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))\r\nfrom page_objects.PageFactory import PageFactory\r\nfrom utils.Option_Parser import Option_Parser\r\nimport conf.mobile_ios_conf as conf\r\nimport conf.testrail_caseid_conf as testrail_file\r\n\r\ndef test_mobile_iOS(mobile_os_name, mobile_os_version, device_name, app_package, app_activity, remote_flag, device_flag, testrail_flag, tesults_flag, test_run_id,app_name,app_path,ud_id,org_id,signing_id,no_reset_flag):\r\n#def test_mobile_iOS(mobile_os_name, mobile_os_version, device_name, app_package, app_activity, remote_flag, device_flag, testrail_flag, tesults_flag, test_run_id, app_name,app_path, ud_id, org_id, signing_id, no_reset_flag):\r\n    \"Run the test.\"\r\n    #try:\r\n    # Initalize flags for tests summary.\r\n    expected_pass = 0\r\n    actual_pass = -1\r\n\r\n    #1. Create a test object.\r\n    test_obj = PageFactory.get_page_object(\"avinash demo main page\")\r\n    \r\n    #Get the path of the .apk file\r\n    app_path = input('\\nEnter the path of .app file:')\r\n    \r\n    #2. Setup and register a driver\r\n    start_time = int(time.time())\r\n    #test_obj.register_driver(mobile_os_name,mobile_os_version,device_name,app_package,app_activity,remote_flag,device_flag,app_name,app_path,ud_id,org_id,signing_id,no_reset_flag)\r\n    test_obj.register_driver(mobile_os_name,mobile_os_version,device_name,app_package,app_activity,remote_flag,device_flag,app_name,app_path,ud_id,org_id,signing_id,no_reset_flag)\r\n    #3. Get the test details from the conf file\r\n    name = conf.name\r\n    phone = conf.phone_no\r\n    \r\n    #4. Set the name in the demo app.\r\n    result_flag = test_obj.set_name_input(name)\r\n    test_obj.log_result(result_flag,\r\n                positive=\"Successfully set name.\",\r\n                negative=\"Failed to set name.\") \r\n\r\n    #5. Set the phone no in the demo app.\r\n    result_flag = test_obj.set_phone_input(phone)\r\n    test_obj.log_result(result_flag,\r\n                positive=\"Successfully set phone no.\",\r\n                negative=\"Failed to set phone no.\")    \r\n    \r\n    #6. Click on submit button.\r\n    result_flag = test_obj.click_submit()\r\n    test_obj.log_result(result_flag,\r\n                positive=\"Successfully clicked on Submit Button.\",\r\n                negative=\"Failed to click on Submit Button\")       \r\n\r\n    #7. Print out the results.\r\n    test_obj.write_test_summary()\r\n\r\n    #8. Teardown and Assertion.\r\n    test_obj.wait(3)\r\n    expected_pass = test_obj.result_counter\r\n    actual_pass = test_obj.pass_counter\r\n    test_obj.teardown()\r\n\r\n    #except Exception as e:\r\n    print (\"Exception when trying to run test:%s\" % __file__)\r\n    print (\"Python says:%s\" % str(e))\r\n\r\n    assert expected_pass == actual_pass,\"Test failed: %s\"%__file__\r\n\r\n\r\n# ---START OF SCRIPT\r\n\r\nif __name__ == '__main__':\r\n    print (\"Start of %s\" % __file__)\r\n    # Creating an instance of the class.\r\n    options_obj = Option_Parser()\r\n    options = options_obj.get_options()\r\n    \r\n    # Run  the test only if the options provided are valid.\r\n    if options_obj.check_options(options):\r\n        test_mobile_iOS(mobile_os_name = options.mobile_os_name,\r\n                          mobile_os_version = options.mobile_os_version,\r\n                          device_name = options.device_name,\r\n                          app_package = options.app_package,\r\n                          app_activity = options.app_activity,\r\n                          remote_flag = options.remote_flag,\r\n                          device_flag = options.device_flag,\r\n                          testrail_flag = options.testrail_flag,\r\n                          test_run_id = options.test_run_id,\r\n                          app_name = options.app_name,\r\n                          ud_id = options.aud_id,\r\n                          org_id = options.org_id,\r\n                          signing_id = options.signing_id,\r\n                          no_reset_flag = options.no_reset_flag)\r\n    else:\r\n        print ('ERROR: Received incorrect comand line input arguments')\r\n        print (options_obj.print_usage())\r\n<\/pre>\n<h3>How to setup test with .app<\/h3>\n<p>1. Copy the path location of your .app file.<br \/>\n2. Run the appium server.<br \/>\n3. From Xcode Simulator, select the device which is available (in our case it was &#8220;iPhone 8&#8221;).<br \/>\n4. On the terminal, when we run command &#8220;xcrun simctl list&#8221;, we get the devices available with their udid.<br \/>\n5. Run the test case as below with capabilities as shown below on Simulator:<\/p>\n<pre lang=\"Python\">a) D: App name\r\nb) J: Bundle identifier\r\nc) G: Operating System\r\nd) H: OS Version\r\ne) I: Simulator Device\r\nf) ud_id: Unique identifier for Apple Devices\r\ng) N: .app location<\/pre>\n<p>6. Qxf2 Framework has some fixtures defined, to take information related to capabilities as below:<\/p>\n<pre lang=\"Python\">@pytest.fixture\r\ndef ud_id(request):\r\n    \"pytest fixture for iOS udid\"\r\n    return request.config.getoption(\"--ud_id\")\r\n\r\n\r\n@pytest.fixture\r\ndef org_id(request):\r\n    \"pytest fixture for iOS team id\"\r\n    return request.config.getoption(\"--org_id\")\r\n\r\n\r\n@pytest.fixture\r\ndef signing_id(request):\r\n    \"pytest fixture for iOS signing id\"\r\n    return request.config.getoption(\"--signing_id\")\r\n\r\n\r\n@pytest.fixture\r\ndef no_reset_flag(request):\r\n    \"pytest fixture for no_reset_flag\"\r\n    return request.config.getoption(\"--no_reset_flag\")<\/pre>\n<p>Command to run the tests with the required fixtures is shown below:<\/p>\n<pre lang=\"Python\">pytest test_mobile_ios.py -D=\"nilaya_app_demo.app\" -J=\"SoftwareEngineer.com.nilaya-app-demo\" -G=\"iOS\" -H=\"13.0\" -I=\"iPhone 8\" --ud_id=\"251C968C-BC97-4B18-B967-B22DC7CE759A\" -N \"\/Users\/apple\/Desktop\" -s -v<\/pre>\n<p><a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/11\/Screenshot-2019-11-26-at-12.06.39-PM.png\" data-rel=\"lightbox-image-2\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-large wp-image-11749\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/11\/Screenshot-2019-11-26-at-12.06.39-PM-1024x303.png\" alt=\"\" width=\"1024\" height=\"303\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/11\/Screenshot-2019-11-26-at-12.06.39-PM-1024x303.png 1024w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/11\/Screenshot-2019-11-26-at-12.06.39-PM-300x89.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/11\/Screenshot-2019-11-26-at-12.06.39-PM-768x227.png 768w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/11\/Screenshot-2019-11-26-at-12.06.39-PM.png 1425w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><br \/>\n<a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-03-at-2.34.19-PM.png\" data-rel=\"lightbox-image-3\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-large wp-image-11868\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-03-at-2.34.19-PM-1024x608.png\" alt=\"\" width=\"1024\" height=\"608\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-03-at-2.34.19-PM-1024x608.png 1024w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-03-at-2.34.19-PM-300x178.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-03-at-2.34.19-PM-768x456.png 768w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2019\/12\/Screenshot-2019-12-03-at-2.34.19-PM.png 1254w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/p>\n<hr \/>\n<p>Hope you liked this post and is helpful for you to get going on iOS app testing. Happy testing!!!!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Why this post? In this post, we are going to look into, how to test an iOS app with Python-based testing framework using appium. This is a step by step procedure, right from building an app, writing a test for iOS app in Python using Qxf2 test automation framework and then actual testing of app with Appium on Mac OS [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[50,38,104,47,18,61],"tags":[],"class_list":["post-11657","post","type-post","status-publish","format-standard","hentry","category-appium","category-automation","category-ios","category-mobile","category-python","category-testing"],"_links":{"self":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/11657","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/comments?post=11657"}],"version-history":[{"count":62,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/11657\/revisions"}],"predecessor-version":[{"id":12027,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/11657\/revisions\/12027"}],"wp:attachment":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/media?parent=11657"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/categories?post=11657"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/tags?post=11657"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}