Automate an iOS Tic Tac Toe app with Appium 2 (XCUITest) Part 1: Player vs Player
How to use Appium 2 to automate playing Tic Tac Toe
In this article, I’ll show you how to automate Nathan Fallet and Group MINASTE’s Tic Tac Toe iOS app with Appium 2.
Table of Contents:
· Setup
∘ Install Appium 2 and the XCUITest Driver
∘ Build the Tic Tac Toe app
· Get Started
∘ How to Play Tic Tac Toe
· Play Tic Tac Toe with Appium
∘ Execution Video
∘ Test Design
∘ Refactoring
· Complete Test Scripts
· Zhimin’s notes
Setup
Install Appium 2 and the XCUITest Driver
Follow the steps in my other article to install the Appium 2 server, the XCUITest Driver and your desired Appium Client library (I prefer Ruby).
A basic summary of the setup (for macOS) is as follows:
# Install Node.js
brew install node@18
# Install Appium 2
npm install -g appium@next
# Install XCUITest Driver
appium driver install xcuitest
# Run this in a separate window to start up the Appium server
appium
# Install Ruby's Appium client library
gem install --no-document appium_lib
Note that there are some security permissions that may need to be granted. See the article for detailed step-by-step instructions as well as a simple script to verify the setup.
Build the Tic Tac Toe app
In this exercise, I will run a Tic Tac Toe app on the iOS simulator, using the open-source tic tac toe app I found on Github by Group MINASTE. By the way, this app is also available on the App Store under the name Tic TAI Toe
.
Clone or download the project (from Github) then build it in Xcode. Once the project has been built, we want to get it in .app.zip
.
Navigate to ~/Library/Developer/Xcode/DerivedData/
to find your app name, just check the starting part. For example, “MorpionTPE-dhzxccjhkowtjtfegrbiqgmnxewt
”. Under that folder, go to Build/Products/{another folder named after your build target}
to find the app file. Right-click and “Compress” to zip it, then rename it to MorpionTPE.app.zip
.
Now that we have the app file and Appium set up, we can start playing the game with Appium!
Get Started
Create your test project, it can be done in your favourite editor and run on the command line. I used TestWise, a testing IDE as it’s very helpful to set up the initial Appium options.
In TestWise, you can select an Appium project and specify the app path:
TestWise will create a project skeleton with the Appium capability options to start up the TicTacToe app.
# test_helper.rb
def app_file_path
'/Users/courtney/sample-apps/MorpionTPE.app.zip'
end
def appium_xcuitest_opts
opts = {
caps: {
platformName: 'ios',
automationName: 'xcuitest',
platformVersion: '16.2', # change to match your Xcode
deviceName: 'iPhone 14', # change here if necessary
app: app_file_path
},
appium_lib: {
server_url: "http://127.0.0.1:4723",
wait: 0.1,
},
}
end
def appium_opts
return appium_xcuitest_opts()
end
Then, at the start of every test script file, it starts the driver with the above settings:
before(:all) do
@driver = Appium::Driver.new(appium_opts).start_driver
end
Now that our test’s skeleton is ready, we can start driving the Tic Tac Toe app.
Right-click the sample test case (`new_spec.rb`)
and select Run "..."
, you will see the app launching in an iOS simulator.
Zhimin’s notes: Appium test scripts, just like Selenium WebDriver, has no dependencies on tools such as TestWise. You are free to use any. Mobile (appium) set up is considerablly more comflex than Web (selenium), Courtney find that TestWise’s such easy set up is good for beginners.
How to Play Tic Tac Toe
Given a 3x3 board, two players take turns selecting a cell. First to 3-in-a-row wins. The app let’s you pick between three game modes:
In this exercise, I’ll select Player vs Player (PVP) mode, i.e. we can control the outcome (via scripts). Let’s play a very simple game so that Player 1 (X) wins.
The game plan:
# Begin game
Player 1: (1, 1)
Player 2: (3, 1)
Player 1: (1, 2)
Player 2: (3, 2)
Player 1: (1, 3) # Game ends, P1 wins
Play Tic Tac Toe with Appium
First, I will show a video of executing the completed Appium test.
Execution Video
Test Execution in TestWise
The video link on Youtube:
Test Design
The board is made up of 9 cells (3x3). To play, we need to find and tap a specific cell.
Each cell does not have a unique identifier. However, all cells have the type XCUIElementTypeImage
(getting this info via the Appium Inspector). I used driver.find_elements
on the type to get all 9 cells. Then indexing to get a specific cell.
board = driver.find_elements(:class_name, "XCUIElementTypeImage")
# Board layout
# 0 1 2
# 3 4 5
# 6 7 8
board[0].click # taps the top-left cell
Using this, it’s simple to write a test case.
it "Play Tic Tac Toe - Player x Player - X Wins" do
driver.find_element(:name, "Player VS Player").click
board = driver.find_elements(:class_name, "XCUIElementTypeImage")
# 0 1 2
# 3 4 5
# 6 7 8
board[0].click
board[6].click
board[1].click
board[7].click
board[2].click
game_status_text = driver.find_element(:class_name, "XCUIElementTypeStaticText")["value"]
expect(game_status_text).to eq("Game has ended! Winner: Player X")
end
Using indexing is not very intuitive though, we can do better.
Refactoring
To make the script more readable, let’s use coordinates. While we are at it, we can refactor based on Maintainable Automated Test Design and use the Page Object Models design here as well.
First, I select "driver.find_element(:name, “Player VS Player”).click"
, then invoke the ‘Extract to Page’ refactoring in TestWise.
Keep reading with a 7-day free trial
Subscribe to AgileWay’s Test Automation & Continuous Testing Blog to keep reading this post and get 7 days of free access to the full post archives.