まえがき
以前、iOS Test Night #4という勉強会にて、テストを書かない言い訳をした結果wwwwwww // Speaker Deckという発表①をしました。
この発表①はもっと過去のiOS Test Nightで行った発表⓪を枕にした発表です。ややこしいな。
発表⓪にて、テストファイルと実装ファイルって
みたいに距離があると気軽に行き来するには辛すぎるよねと話したんですが、そしたら
テストを書かない言い訳をさせてくれ // Speaker Deckと言われたので、それができるように https://github.com/takasek/XCJumpToTests/blob/master/xcode_toggleImplAndTests.scpt というAppleScriptスクリプトを作りました、というのが発表①の内容でした。Java+Eclipse時代はプロダクトコードとテストコードをトグル的に行き来できるプラグイン入れてたけどXcode+Swiftはそういうのないの???
2017/03/17 10:15
xcode_toggleImplAndTests.scpt の使い方
Xcodeには Custom Behavior
という機能があり、任意のスクリプトをワンタップで実行できます。
適当な場所にスクリプトを置いて、設定からTrigger Hot Keyを設定します。
Hoge.swift
で実行したら HogeTests.swift あるいは HogeSpec.swift
に、
HogeTests.swift あるいは HogeSpec.swift
で実行したら Hoge.swift
にジャンプします。
ありがたいことに、今も活用していただけてると報告を受けることがあります。
けど問題もありまして、
xcode_toggleImplAndTests.scpt の問題点
AppleScript読みづらいし書きづらい。
本当ならメンテしやすいように、SwiftかObj-Cで書きたいものです。
というかXcode Source Editor Extensionで実現できれば最高なんだけどなー…
と思ってたところで、それを可能にするワークアラウンドを思いつきました。
その詳細については数日前の別記事 続・Xcode Source Editor Extensionの世界 〜XPCとScripting Bridge〜 - Qiita で解説しました。
xcode_toggleImplAndTests.scpt をXcode Source Editor Extension化してみた
これが成果物です。
https://github.com/takasek/XCJumpToTests
使い方
- プロジェクトをcloneして、Xcodeで開きます
- プロビジョニングプロファイルを書き替えてArchiveします
- 出来上がった
.app
を実行すると、コンピュータにXcode Source Editor Extensionがインストールされます - 設定画面からホットキーを設定します
スクリプトバージョンに比べて、ビルドする手間が増えましたが、スクリプトの置き場所に悩む必要はなくなり、Xcodeと統合された安心感と格段のメンテナンス性が手に入りました。
制限
プロジェクトをArchiveする必要があるということは、有料のApple Developer Program登録をしている必要があるということです。
有料登録していない開発者であれば、AppleScript版が役に立つことでしょう。
XcodeとのScripting Bridge によるテストの可能性
「テスト自動化」の話かって言われると少し苦しい記事内容になってしまった気がするので、ついでに、最後にそれっぽい話でお茶を濁しましょう。
Xcode Scripting Bridgeには次のようなインタフェースがあります。
- (XcodeSchemeActionResult *) testWithCommandLineArguments:(id)withCommandLineArguments withEnvironmentVariables:(id)withEnvironmentVariables;
ちなみに XcodeSchemeActionResult
ってのはこんな奴。
// An object describing the result of performing a scheme action command.
@interface XcodeSchemeActionResult : SBObject <XcodeGenericMethods>
- (SBElementArray<XcodeBuildError *> *) buildErrors;
- (SBElementArray<XcodeBuildWarning *> *) buildWarnings;
- (SBElementArray<XcodeAnalyzerIssue *> *) analyzerIssues;
- (SBElementArray<XcodeTestFailure *> *) testFailures;
- (NSString *) id; // The unique identifier for the scheme.
@property (readonly) BOOL completed; // Whether this scheme action has completed (sucessfully or otherwise) or not.
@property XcodeSchemeActionResultStatus status; // Indicates the status of the scheme action.
@property (copy) NSString *errorMessage; // If the result's status is "error occurred", this will be the error message; otherwise, this will be "missing value".
@property (copy) NSString *buildLog; // If this scheme action performed a build, this will be the text of the build log.
@end
これを使えば、Apple ScriptやXcode Source Editor Extensionからテストを実行し、終了を監視することも可能かもしれません。
……そこ、誰得とか言わない。
完全に余談ですが
今回のプロジェクトを準備していたところ、Twitterにてこんな反応をいただきました。
@takasek さんの.swiftとtest.swiftを行き来できるスクリプトを使ってViewControllerとViewModelを行き来できるようしたい気持ちがすごい https://t.co/Uoh7WBVqpP
— mego (@mego_) 2017年12月5日
私もFlux版を作って使ってます👍
— ネバダ最速の鈴木 (@toshi0383) 2017年12月5日
アシスタントエディタ側でも効かせたいですよねー。
確かに、ジャンプ元・ジャンプ先を求めるロジックだけ切り出してエディットできるようにすれば、もっと柔軟で使い道が広がるなーと思いつつ、今回そこまでやると完全にアドベントカレンダーの趣旨から抜けてしまうのでやりませんでした。
近いうちに、そこまで実現したXcode Source Editor Extensionをリリースしたいなと思いました。