はじめに
はじめまして、2023年3月キャリア入社、HealthCare Inovation Group(HIG)所属の寒河江です。
春の入門ブログ連載の17日目です。
本記事はSwiftでの自動テストについての入門記事です。SwiftはXcodeを用いてiOSアプリが作成でき、自作して手元の端末で動きが見やすいため初心者がモチベーション維持したまま開発できる良い題材かなと思います。「作って動いて楽しいなぁ」→「テストしてみよう!」→ 「楽にできる方法ないかな?」 と思った方に見ていただければです。
簡単なメモアプリを作成し、それに対して部分的にテストコードを書いてみたので早速紹介していきます。
作ったメモアプリ
https://github.com/SagaeKugo/CRUD
XCTestのセットアップ
今回はプロジェクト作成後にテストを追加します。
Xcodeを開いてFile→New→Targetを選択し
対象となるテストを追加します。今回はUT/UIテストどちらも実施するためどちらも追加します。
テスト用のフォルダが作成され、TARGETにテストが追加されました。
UT対象
例のため、極端に簡素化した関数を作成してテストします
import Foundation |
UTの実施(1)〜デフォルトで入っている関数の扱い〜
先ほどUnit Testing Bungleを選択して追加したCRUDTestsにテストコードを記載していきます。
import XCTest |
デフォルトで4つのテスト関数が記載されていますが、これらはざっと以下の意味で、今回は変更する必要はないので無視します。
setUpWithError()
- →各テストを実行する前に毎回呼ばれます。
- tearDownWithError()`
- →各テスト実行後に毎回呼ばれます。
testExample()
- →テストコードのサンプルです。<test + テスト対象のメソッド名>
testPerformanceExample()
- →パフォーマンステストのサンプルです。<testPerformance + テスト対象のメソッド名>
そのため、XCTestCaseをまとめてテストを回すと、
setUpWithError()
testExample()
tearDownWithError()
setUpWithError()
testCulcAdd()
tearDownWithError()
…という流れでテストが動きます。
UTの実施(2)〜関数の追加、テスト実行〜
@testable import CRUD
と記載することでCRUDアプリ内のpublic,internalシンボルのテストが可能になります。
Sampleアプリを作成した場合は@testable import Sample
になりますね。
続いてテスト関数を作成します。
内容は特筆すべき部分はないと思うので省略(参考サイトは末尾に記載)しますが、テスト関数を作成する際は必ず先頭にtest
と入れる必要があります。
先頭にtestと記載することでテストメソッドとして認識され、テストできる関数には左側に菱形マークがつきます。
それぞれの関数単位で菱形ボタンを押してテスト実行することも可能ですし、CRUDTestsクラスの菱形ボタンを押すことでクラス内のテストをまとめて実施することも可能です。
成功すると緑のチェックがつき、失敗した場合は赤くバツが出てくれます。
失敗した時のログはこちらから確認できます。
UIテストの実施(1)
UI Testing Bungleを選択して追加したCRUDUITestsにテストコードを記載していきます。
デフォルトでCRUDUITests.swift
とCRUDUITestsLaunchTests.swift
の2ファイル作成されていますが、今回はCRUDUITests.swiftにテストを記載します。デフォルトで書かれているテスト関数はUTで紹介しているものと同じ役割なので省略します。
UIテストの実施(2)
今回テストしたのは下記の1関数のみです。
func testAddDelete() { |
testAddボタンを押下することでメモを10件登録し、testDeleteボタンを押下することでメモを全件削除しています。
ユーザーが操作せずに見た目が変わることだけを確認したいためメモ内容はチェック対象外としています。メモ内容をテストする場合は別途アサーションを追加しましょう。
let app = XCUIApplication() |
まずはテスト対象のアプリXCUIApplication()
のインスタンスを作成します。
XCTContext.runActivity(named: "Launch app") { _ in |
今回の規模であれば不要ですが、XCTContext.runActivity(named: "~~")
を使って長いテストメソッドを名前付きの小さなサブステップに分割できます。app.launch()
はnamedに記載されている通り、アプリの起動を行っています。
app.buttons["testAdd"].firstMatch.tap() |
テスト対象のアプリ内のtestAdd
、testDelete
というラベルのついたボタンを検索し、最初に見つかったものをタップしています。複数同じ名前のボタンがある場合は、accessibilityIdentifier
を設定することで分類できます。(参考サイトにリンク記載)
UIテスト動画
マウス操作しなくてもシミュレータ画面左上のtestAdd,testDeleteボタンが押下されています。
さいごに
長い記事になってしまいましたが、読んでくださった方ありがとうございます。
「はじめに」にも書きましたがiOSアプリは普段使う分実機テストもしやすく自分の欲しいものを作ることもできるので、初心者がモチベーションを維持しながら技術を身につけるにはいい題材だと思います。(私も初心者なので書いて遊んでます)
今回紹介できませんでしたが、CoreDataというのを使ってサーバーを立てなくてもアプリ上で扱うデータのCRUD処理が簡単にできたりと面倒ごとが少ないのも利点です。せっかく技術を身につけるなら動かして楽しんでスキルアップしていきましょう!!
次は斎藤賢太さんのJSパッケージ管理ツールpnpmの概要と内部構造を眺める です。
参考サイト
- XCTestで使えるAssert一覧
XCTestのAssert一覧 - accessibilityIdentifierの説明
XCUIElementの使い方をざっくりまとめてみた