Bruno Alassia
Software Engineer 🐳 rosarino en Canada
@vrunoa
vrunoa
vruno@saucelabs.com
Appium is an open source test automation framework for use with native, hybrid and mobile web apps. It drives iOS, Android, Windows desktop apps and more using the WebDriver protocol.
Each platform is supported by one or more "drivers", which know how to automate that particular platform.
Appium gives you the possibility to automate and run tests over mobile web and native application on Android and iOS, desktop applications on Windows and MacOS, youi.tv, tizen and more.
You don't have to recompile your app or modify it in any way, due to use of standard automation APIs on all platforms.
You can easily start moving from Manual testing to Automated testing without code changes.
This allow you to automate external or system apps along with yours during a test case scenario.
Appium has built-in mobile web and hybrid app support. Within the same script you can easily change between native app automation and webview automation, all using the WebDriver model that's already the standard for web automation.
You can write tests with your favorite dev tools using any WebDriver-compatible language such as Java, Objective-C, JavaScript (Node), PHP, Python, Ruby, C#, Clojure, or Perl with the Selenium WebDriver API and language-specific client libraries.
Appium client
Appium server
Device
Manual testing
Automated testing
...
...
...
...
...
...
1. the client talks to Appium server to start a session on an device
2. Appium instanciate the driver that will manage the communication with the device
3. The driver prepares the device, make sure it can talk to the device and once it's ready tells the appium server
4. Appium server replies back to the client that the session is ready and that it can receive the commands
And then we go thru the same process for each command we have in our test
Let's take a quick look at a Selenium test
import unittest
import sys
from time import sleep
from selenium import webdriver
class WebTest(unittest.TestCase):
def setUp(self):
host = "http://localhost:4444/wd/hub"
capabilities = {}
capabilities["browserName"] = "chrome"
self.driver = webdriver.Remote(host, capabilities)
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
def test_login_succes_flow(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elUser.send_keys("standard_user")
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
elPass.send_keys("secret_sauce")
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
btt.click()
self.assertEquals(self.driver.current_url, "https://www.saucedemo.com/inventory.html")
sleep(2)
def main():
suite = unittest.TestLoader().loadTestsFromTestCase(WebTest)
ret = not unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful()
sys.exit(ret)
if __name__ == '__main__':
main()
import unittest
import sys
from time import sleep
from selenium import webdriver
class WebTest(unittest.TestCase):
def setUp(self):
host = "http://localhost:4444/wd/hub"
capabilities = {}
capabilities["browserName"] = "chrome"
capabilities["platformName"] = "Mac OS"
capabilities["platformVersion"] = "10.14.5"
self.driver = webdriver.Remote(host, capabilities)
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
def test_login_succes_flow(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elUser.send_keys("standard_user")
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
elPass.send_keys("secret_sauce")
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
btt.click()
self.assertEquals(self.driver.current_url, "https://www.saucedemo.com/inventory.html")
sleep(2)
def main():
suite = unittest.TestLoader().loadTestsFromTestCase(WebTest)
ret = not unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful()
sys.exit(ret)
if __name__ == '__main__':
main()
import unittest
import sys
from time import sleep
from selenium import webdriver
class WebTest(unittest.TestCase):
def setUp(self):
host = "http://localhost:4444/wd/hub"
capabilities = {}
capabilities["browserName"] = "chrome"
capabilities["platformName"] = "Mac OS"
capabilities["platformVersion"] = "10.14.5"
self.driver = webdriver.Remote(host, capabilities)
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
def test_login_succes_flow(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elUser.send_keys("standard_user")
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
elPass.send_keys("secret_sauce")
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
btt.click()
self.assertEquals(self.driver.current_url, "https://www.saucedemo.com/inventory.html")
sleep(2)
def main():
suite = unittest.TestLoader().loadTestsFromTestCase(WebTest)
ret = not unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful()
sys.exit(ret)
if __name__ == '__main__':
main()
import unittest
import sys
from time import sleep
from appium import webdriver
class WebTest(unittest.TestCase):
def setUp(self):
host = "http://localhost:4444/wd/hub"
capabilities = {}
capabilities["browserName"] = "chrome"
capabilities["platformName"] = "android"
capabilities["platformVersion"] = "7.1"
capabilities["deviceName"] = "Android Emulator"
self.driver = webdriver.Remote(host, capabilities)
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
def test_login_succes_flow(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elUser.send_keys("standard_user")
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
elPass.send_keys("secret_sauce")
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
btt.click()
self.assertEquals(self.driver.current_url, "https://www.saucedemo.com/inventory.html")
sleep(2)
def main():
suite = unittest.TestLoader().loadTestsFromTestCase(WebTest)
ret = not unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful()
sys.exit(ret)
if __name__ == '__main__':
main()
import unittest
import sys
from time import sleep
from appium import webdriver
class WebTest(unittest.TestCase):
def setUp(self):
host = "http://localhost:4444/wd/hub"
capabilities = {}
capabilities["browserName"] = "chrome"
capabilities["platformName"] = "android"
capabilities["platformVersion"] = "7.1"
capabilities["deviceName"] = "Android Emulator"
self.driver = webdriver.Remote(host, capabilities)
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
def test_login_succes_flow(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elUser.send_keys("standard_user")
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
elPass.send_keys("secret_sauce")
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
btt.click()
self.assertEquals(self.driver.current_url, "https://www.saucedemo.com/inventory.html")
sleep(2)
def main():
suite = unittest.TestLoader().loadTestsFromTestCase(WebTest)
ret = not unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful()
sys.exit(ret)
if __name__ == '__main__':
main()
import unittest
import sys
from time import sleep
from appium import webdriver
class WebTest(unittest.TestCase):
def setUp(self):
host = "http://localhost:4723/wd/hub"
capabilities = {}
capabilities["browserName"] = "chrome"
capabilities["platformName"] = "android"
capabilities["platformVersion"] = "7.1"
capabilities["deviceName"] = "Android GoogleApi Emulator"
capabilities["automationName'] = "uiautomator2"
self.driver = webdriver.Remote(host, capabilities)
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
def test_login_succes_flow(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elUser.send_keys("standard_user")
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
elPass.send_keys("secret_sauce")
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
btt.click()
self.assertEquals(self.driver.current_url, "https://www.saucedemo.com/inventory.html")
sleep(2)
def main():
suite = unittest.TestLoader().loadTestsFromTestCase(WebTest)
ret = not unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful()
sys.exit(ret)
if __name__ == '__main__':
main()
the client is what it's going to communicate with the Appium server and drive your test
import unittest
import sys
from time import sleep
from appium import webdriver
class WebTest(unittest.TestCase):
def setUp(self):
host = "http://localhost:4723/wd/hub"
capabilities = {}
capabilities["browserName"] = "chrome"
capabilities["platformName"] = "android"
capabilities["platformVersion"] = "7.1"
capabilities["deviceName"] = "Android GoogleApi Emulator"
capabilities["automationName'] = "uiautomator2"
self.driver = webdriver.Remote(host, capabilities)
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
def test_login_succes_flow(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elUser.send_keys("standard_user")
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
elPass.send_keys("secret_sauce")
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
btt.click()
self.assertEquals(self.driver.current_url, "https://www.saucedemo.com/inventory.html")
sleep(2)
def main():
suite = unittest.TestLoader().loadTestsFromTestCase(WebTest)
ret = not unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful()
sys.exit(ret)
if __name__ == '__main__':
main()
Capabilities are the way to tell Appium which kind of session we are interested in.
import unittest
import sys
from time import sleep
from appium import webdriver
class WebTest(unittest.TestCase):
def setUp(self):
host = "http://localhost:4723/wd/hub"
capabilities = {}
capabilities["browserName"] = "chrome"
capabilities["platformName"] = "android"
capabilities["platformVersion"] = "7.1"
capabilities["deviceName"] = "Android GoogleApi Emulator"
self.driver = webdriver.Remote(host, capabilities)
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
def test_login_succes_flow(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elUser.send_keys("standard_user")
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
elPass.send_keys("secret_sauce")
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
btt.click()
self.assertEquals(self.driver.current_url, "https://www.saucedemo.com/inventory.html")
sleep(2)
def main():
suite = unittest.TestLoader().loadTestsFromTestCase(WebTest)
ret = not unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful()
sys.exit(ret)
if __name__ == '__main__':
main()
As we have introduced before, Appium is a server so we need to set up the endpoint where we are going to be sending commands thru the client
import unittest
import sys
from time import sleep
from appium import webdriver
class WebTest(unittest.TestCase):
...
def test_login_elements_displayed(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
def test_login_succes_flow(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elUser.send_keys("standard_user")
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
elPass.send_keys("secret_sauce")
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
btt.click()
self.assertEquals(self.driver.current_url, "https://www.saucedemo.com/inventory.html")
sleep(2)
def main():
suite = unittest.TestLoader().loadTestsFromTestCase(WebTest)
ret = not unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful()
sys.exit(ret)
if __name__ == '__main__':
main()
On the tests we have the command calls to interact with our UI and assert that everything is working properly as expected
Appium gives you the possibility to automate and run tests over mobile web and native application on Android and iOS, desktop applications on Windows and MacOS, you.tv, tizen and more.
Let's write a web test for iOS
import unittest
import sys
from time import sleep
from appium import webdriver
class WebTest(unittest.TestCase):
def setUp(self):
host = "http://localhost:4723/wd/hub"
capabilities = {}
capabilities["browserName"] = "chrome"
capabilities["platformName"] = "android"
capabilities["platformVersion"] = "7.1"
capabilities["deviceName"] = "Android GoogleApi Emulator"
self.driver = webdriver.Remote(host, capabilities)
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
def test_login_succes_flow(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elUser.send_keys("standard_user")
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
elPass.send_keys("secret_sauce")
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
btt.click()
self.assertEquals(self.driver.current_url, "https://www.saucedemo.com/inventory.html")
sleep(2)
def main():
suite = unittest.TestLoader().loadTestsFromTestCase(WebTest)
ret = not unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful()
sys.exit(ret)
if __name__ == '__main__':
main()
Looking at our current Android test? What do we need to change to run a test on iOS?
import unittest
import sys
from time import sleep
from appium import webdriver
class WebTest(unittest.TestCase):
def setUp(self):
host = "http://localhost:4723/wd/hub"
capabilities = {}
capabilities["browserName"] = "chrome"
capabilities["platformName"] = "android"
capabilities["platformVersion"] = "7.1"
capabilities["deviceName"] = "Android Emulator"
self.driver = webdriver.Remote(host, capabilities)
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
def test_login_succes_flow(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elUser.send_keys("standard_user")
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
elPass.send_keys("secret_sauce")
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
btt.click()
self.assertEquals(self.driver.current_url, "https://www.saucedemo.com/inventory.html")
sleep(2)
def main():
suite = unittest.TestLoader().loadTestsFromTestCase(WebTest)
ret = not unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful()
sys.exit(ret)
if __name__ == '__main__':
main()
import unittest
import sys
from time import sleep
from appium import webdriver
class WebTest(unittest.TestCase):
def setUp(self):
host = "http://localhost:4723/wd/hub"
capabilities = {}
capabilities["browserName"] = "safari"
capabilities["platformName"] = "iOS"
capabilities["platformVersion"] = "12.2"
capabilities["deviceName"] = "iPhone X"
self.driver = webdriver.Remote(host, capabilities)
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
def test_login_succes_flow(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elUser.send_keys("standard_user")
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
elPass.send_keys("secret_sauce")
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
btt.click()
self.assertEquals(self.driver.current_url, "https://www.saucedemo.com/inventory.html")
sleep(2)
def main():
suite = unittest.TestLoader().loadTestsFromTestCase(WebTest)
ret = not unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful()
sys.exit(ret)
if __name__ == '__main__':
main()
Appium gives you the possibility to automate and run tests over mobile web and native application on Android and iOS, desktop applications on Windows and MacOS, you.tv, tizen and more.
Let's do that!
Looking at Appium documentation we can see there is an `app` capability to use when trying to start a test on a native application
import unittest
import sys
from time import sleep
from appium import webdriver
class WebTest(unittest.TestCase):
def setUp(self):
host = "http://localhost:4723/wd/hub"
capabilities = {}
capabilities["browserName"] = "chrome"
capabilities["platformName"] = "android"
capabilities["platformVersion"] = "7.1"
capabilities["deviceName"] = "Android Emulator"
self.driver = webdriver.Remote(host, capabilities)
import unittest
import sys
from time import sleep
from appium import webdriver
class WebTest(unittest.TestCase):
def setUp(self):
host = "http://localhost:4723/wd/hub"
capabilities = {}
capabilities["app"] = "/path/to/my/app"
capabilities["platformName"] = "android"
capabilities["platformVersion"] = "7.1"
capabilities["deviceName"] = "Android Emulator"
self.driver = webdriver.Remote(host, capabilities)
Web
Native
...
class WebTest(unittest.TestCase):
def setUp(self):
...
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
el = self.driver.find_element_by_accessibility_id('test-Username')
self.assertIsNotNone(el)
self.assertEquals(el.is_displayed(), True)
el = self.driver.find_element_by_accessibility_id('test-Password')
self.assertIsNotNone(el)
self.assertEquals(el.is_displayed(), True)
el = self.driver.find_element_by_accessibility_id('test-LOGIN')
self.assertIsNotNone(el)
self.assertEquals(el.is_displayed(), True)
def test_login_succes_flow(self):
el = self.driver.find_element_by_accessibility_id('test-Username')
el.send_keys("standard_user")
el = self.driver.find_element_by_accessibility_id('test-Password')
el.send_keys("secret_sauce")
el = self.driver.find_element_by_accessibility_id('test-LOGIN')
el.click()
sleep(2)
self.assertEquals(self.driver.current_activity, ".MainActivity")
...
...
class WebTest(unittest.TestCase):
def setUp(self):
...
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
def test_login_succes_flow(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elUser.send_keys("standard_user")
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
elPass.send_keys("secret_sauce")
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
btt.click()
self.assertEquals(self.driver.current_url, "https://www.saucedemo.com/inventory.html")
sleep(2)
...
Web
Native
"When writing native apps testing, follow best practices. This will speed up your tests execution time and make them easy to maintain"
Same concept of `app` capability applies to iOS
...
class WebTest(unittest.TestCase):
def setUp(self):
host = "http://localhost:4723/wd/hub"
capabilities = {}
capabilities["app"] = path.join(CWD, 'apps', 'Android.SauceLabs.Mobile.Sample.app.1.0.0.apk')
capabilities["platformName"] = "android"
capabilities["platformVersion"] = "7.1"
capabilities["deviceName"] = "Android GoogleApi Emulator"
capabilities["automationName"] = "uiautomator2"
self.driver = webdriver.Remote(host, capabilities)
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
el = self.driver.find_element_by_accessibility_id('test-Username')
self.assertIsNotNone(el)
self.assertEquals(el.is_displayed(), True)
el = self.driver.find_element_by_accessibility_id('test-Password')
self.assertIsNotNone(el)
self.assertEquals(el.is_displayed(), True)
el = self.driver.find_element_by_accessibility_id('test-LOGIN')
self.assertIsNotNone(el)
self.assertEquals(el.is_displayed(), True)
def test_login_succes_flow(self):
el = self.driver.find_element_by_accessibility_id('test-Username')
el.send_keys("standard_user")
el = self.driver.find_element_by_accessibility_id('test-Password')
el.send_keys("secret_sauce")
el = self.driver.find_element_by_accessibility_id('test-LOGIN')
el.click()
sleep(2)
self.assertEquals(self.driver.current_activity, ".MainActivity")
...
class WebTest(unittest.TestCase):
def setUp(self):
host = "http://localhost:4723/wd/hub"
capabilities = {}
capabilities["app"] = path.join(CWD, 'apps', 'iOS.Simulator.SauceLabs.Mobile.Sample.app.1.0.0.app.zip')
capabilities["platformName"] = "iOS"
capabilities["platformVersion"] = "12.2"
capabilities["deviceName"] = "iPhone X"
self.driver = webdriver.Remote(host, capabilities)
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
el = self.driver.find_element_by_accessibility_id('test-Username')
self.assertIsNotNone(el)
self.assertEquals(el.is_displayed(), True)
el = self.driver.find_element_by_accessibility_id('test-Password')
self.assertIsNotNone(el)
self.assertEquals(el.is_displayed(), True)
el = self.driver.find_element_by_accessibility_id('test-LOGIN')
self.assertIsNotNone(el)
self.assertEquals(el.is_displayed(), True)
def test_login_succes_flow(self):
el = self.driver.find_element_by_accessibility_id('test-Username')
el.send_keys("standard_user")
el = self.driver.find_element_by_accessibility_id('test-Password')
el.send_keys("secret_sauce")
el = self.driver.find_element_by_accessibility_id('test-LOGIN')
el.click()
sleep(2)
self.assertEquals(self.driver.current_activity, ".MainActivity")
So, I copy-pasted my Android native test and changed the capabilities to run on an iOS device.
ERROR: test_login_succes_flow (__main__.WebTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "tests/test_app_ios.py", line 44, in test_login_succes_flow
self.assertEquals(self.driver.current_activity, ".MainActivity")
File "/Users/brunoalassia/.virtualenvs/testing/lib/python2.7/site-packages/appium/webdriver/extensions/android/activities.py", line 63, in current_activity
return self.execute(Command.GET_CURRENT_ACTIVITY)['value']
File "/Users/brunoalassia/.virtualenvs/testing/lib/python2.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "/Users/brunoalassia/.virtualenvs/testing/lib/python2.7/site-packages/appium/webdriver/errorhandler.py", line 29, in check_response
raise wde
WebDriverException: Message: Method has not yet been implemented
Use the Appium documentation to verify the methods used in your test works for the platform to be tested
Selenium and Appium gives you the possibility to run your tests locally or in the cloud
Test across different platforms
We support the latest releases on Android Emulators and iOS Simulators
we support different combinations of Android emulators
iPhone and iPad simulators
Use our Real Device Cloud
we have more than 800 devices, 188 different device models you can select
Make use of concurrency to speed up your builds
Get fast feedback using Emulators & Simulators
Use our real device cloud to test performance
Make sure your new code is not introducing performance regressions
...
class WebTest(unittest.TestCase):
def setUp(self):
host = "http://localhost:4723/wd/hub"
capabilities = {}
capabilities["app"] = "sauce-storage:my-app.apk"
capabilities["platformName"] = "android"
capabilities["platformVersion"] = "7.1"
capabilities["deviceName"] = "Android GoogleApi Emulator"
capabilities["automationName"] = "uiautomator2"
capabilities["recordDeviceVitals"] = True
self.driver = webdriver.Remote(host, capabilities)
def tearDown(self):
self.driver.quit()
def test_list_loads(self):
...
once your test is finished you'll get a CSV with metrics on the
resources used in the device
Use this metics to keep track of your performance and compare new versions
we are continuous adding tools to help you debug issues
Occasionally mobile applications crash during a test and it is hard to identify the root cause of the problem. However, users can now access crash logs generated while testing an iOS application on Sauce iOS simulators.
easily tests behind a firewall or you own localhost in the cloud using SauceConnect
Tests in the cloud accesing my local laptop
we care about security
we use fresh clean VMs on each test you ran in our platform
we have a security team making sure we are compliant
That's why most famous banks in the world and media services choose us
we use AES256 encryption for our assets and sauce connect data transportation
we completely destroy VMs after each tests finishes
import unittest
import sys
from time import sleep
from appium import webdriver
class WebTest(unittest.TestCase):
def setUp(self):
host = "http://localhost:4723/wd/hub"
capabilities = {}
capabilities["browserName"] = "safari"
capabilities["platformName"] = "iOS"
capabilities["platformVersion"] = "12.2"
capabilities["deviceName"] = "iPhone X"
self.driver = webdriver.Remote(host, capabilities)
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
def test_login_succes_flow(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elUser.send_keys("standard_user")
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
elPass.send_keys("secret_sauce")
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
btt.click()
self.assertEquals(self.driver.current_url, "https://www.saucedemo.com/inventory.html")
sleep(2)
def main():
suite = unittest.TestLoader().loadTestsFromTestCase(WebTest)
ret = not unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful()
sys.exit(ret)
if __name__ == '__main__':
main()
How many lines of code would you think we need to change in our test to start using sauce cloud?
import unittest
import sys
from time import sleep
from appium import webdriver
class WebTest(unittest.TestCase):
def setUp(self):
host = "http://localhost:4723/wd/hub"
capabilities = {}
capabilities["browserName"] = "safari"
capabilities["platformName"] = "iOS"
capabilities["platformVersion"] = "12.2"
capabilities["deviceName"] = "iPhone X"
self.driver = webdriver.Remote(host, capabilities)
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
def test_login_succes_flow(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elUser.send_keys("standard_user")
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
elPass.send_keys("secret_sauce")
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
btt.click()
self.assertEquals(self.driver.current_url, "https://www.saucedemo.com/inventory.html")
sleep(2)
def main():
suite = unittest.TestLoader().loadTestsFromTestCase(WebTest)
ret = not unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful()
sys.exit(ret)
if __name__ == '__main__':
main()
The answer is 1
import unittest
import sys
from time import sleep
from appium import webdriver
class WebTest(unittest.TestCase):
def setUp(self):
host = "https://%s:%s@ondemand.saucelabs.com:443/wd/hub" % (os.environ['SAUCE_USERNAME'], os.environ['SAUCE_ACCESS_KEY'])
capabilities = {}
capabilities["browserName"] = "safari"
capabilities["platformName"] = "iOS"
capabilities["platformVersion"] = "12.2"
capabilities["deviceName"] = "iPhone X Simulator"
self.driver = webdriver.Remote(host, capabilities)
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
def test_login_succes_flow(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elUser.send_keys("standard_user")
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
elPass.send_keys("secret_sauce")
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
btt.click()
self.assertEquals(self.driver.current_url, "https://www.saucedemo.com/inventory.html")
sleep(2)
def main():
suite = unittest.TestLoader().loadTestsFromTestCase(WebTest)
ret = not unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful()
sys.exit(ret)
if __name__ == '__main__':
main()
...and a half
...
class WebTest(unittest.TestCase):
def setUp(self):
...
capabilities = {}
capabilities["browserName"] = "chrome"
capabilities["platformName"] = "android"
capabilities["platformVersion"] = "9"
capabilities["deviceName"] = "Google Pixel"
capabilities["appiumVersion"] = "1.13.0"
capabilities["projectName"] = "saucedemo"
capabilities["name"] = "Test SauceDemo login"
self.driver = webdriver.Remote(host, capabilities)
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
...
...
class WebTest(unittest.TestCase):
def setUp(self):
...
capabilities = {}
capabilities["browserName"] = "chrome"
capabilities["platformName"] = "android"
capabilities["platformVersion"] = "8.1"
capabilities["deviceName"] = "Android GoogleApi Emulator"
capabilities["name"] = "Test SauceDemo login"
self.driver = webdriver.Remote(host, capabilities)
def tearDown(self):
self.driver.quit()
def test_login_elements_displayed(self):
self.driver.get("https://www.saucedemo.com")
elUser = self.driver.find_element_by_id('user-name')
self.assertIsNotNone(elUser)
elPass = self.driver.find_element_by_id('password')
self.assertIsNotNone(elPass)
btt = self.driver.find_element_by_class_name('btn_action')
self.assertIsNotNone(btt)
...
Emulator
Real Device Cloud
Along with appium
|
||
---|---|---|
Android Emulators | ||
iOS Simulators |
||
Android Real Devices | ||
iOS Real Devices |
we're going to help you get onboard on automated testing
we're going to help you find flaky tests
we're going to help you write better tests
we're going to help you speed up your test times
with parallelization
across all our platforms
across all our testing solutions
using best practices and help you decide when and what to test
we're going to help build your pipelines
...and much much more
@vrunoa
vrunoa
vruno@saucelabs.com
By Bruno Alassia