Making an Xcode Template for ViewUnitTest

Xcode Templates

The View Inspector framework makes testing SwiftUI Views fast... very fast to execute! Not to write. But that is the optimization we are after in TDD. Test that execute in microseconds are worth their weight in platinum (or platypus venom). So taking a few minutes to write is OK... but we can speed that up with a good template. Xcode has a way to customize file templates. Let's learn how...

First some exploration of the existing Xcode file template directory structure. Note inside this domain, things that seem like files... well, sometimes turn out to be directories. So navigate carefully in a terminal - consider using the Mac Finder.

In the Finder press Ctrl-G to goto the path: "/Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates"
don't mess with these - they are part of the standard Xcode product.

Here you will find two folders with structures and templates below them. A File Templates & Project Templates folder. We are going to find the classic iOS Unit Test template and copy it - then modify it for our View UnitTest. Navigate futher into the abiss ... File Templates/macOS/Source/Unit Test Cases Class.xctemplate (note that is a directory - not a file).

Create Your Customization Directories

Open another Finder window and navigate to your home directory's ~/Library/Developer/Xcode/Templates
in all likelyhood - you will have nothing in the folder. Create to folders: File Templates & Project Templates (pay attention to names - they must be correctly spelled).

Then inside of File Templates create a new folder Custom Templates this will coorelate to a grouping in the New File dialogues of Xcode.

Next we want to use the Unit Test Cases Class.xctemplate (directory) as our example - so copy that directory into your home directory's
~/Library/Developer/Xcode/Templates/File Templates/Custom Templates/ folder. Then rename the folder - I'm suggesting View Unit Test Cases Class.xctemplate for the new name.

Next open the folder and find the TemplateInfo.plist file - you want to edit this - I use a simple text editor (vi) but Xcode has a special plist file editor also. Change the Description & Summary strings to something more approprate for a View UnitTest.

There are three important changes you need to make - so that we do not confuse Xcode - they are:

  1. the directory name for the xctemplate (View Unit Test Cases Class.xctemplate)

  2. the Description string (A class implementiong a unit test utilizing ViewInspector)

  3. the Summary string (A class implementing a unit test utilizing ViewInspector)

Next - if you desire - change the icons Xcode will use for the template (4 png files).

Now for the template changes... open the directory XCTestCaseSwift and edit the ___FILEBASENAME___.swift file. This file becomes your unit-test file and uses some special triple-underscore-keywords that will be replaced. In general you may write any code you wish to be part of your template and also use the special keywords (I don't yet know them - or where Apple keeps that secret.) Here's what I'm using for a ViewInspector Unit Test.

___FILEBASENAME___.swift

//___FILEHEADER___


import XCTest

import ViewInspector // 1. First requirement for ViewInspector

@testable import ___TARGETNAME___


extension ___FILEBASENAME___: Inspectable {} // 2. Second requirement for ViewInspector


class ___FILEBASENAMEASIDENTIFIER___: ___VARIABLE_testSubclass___ {


// a View Inspector UnitTest of a SwiftUI View

// cleanup required:

// check for proper @testable import TARGETNAME

// check for proper extension VIEW_FILE: Inspectable {}

// check for proper let VUT = VIEW_FILE()

// substitute a good string to find and print the view hierarchy

//

func testExample() throws { // 3. Third requirement for ViewInspector e.g. throws


let VUT = ___FILEBASENAME___() // remove "Test" from name // VUT = View Under Test

let textView = try VUT.inspect().find(text: "Some_Unique_Text") // 4. Fourth requirement for ViewInspector e.g. VUT.inspect()

print("ViewInspector found Some_Unique_Test in view path: \(textView.pathToRoot)" )


// see: https://github.com/nalexn/ViewInspector/blob/master/guide.md the View Inspector Guide.

}


}





WARNING - a work in process (Jan 2021):: need a way to get the implementation class name from the test file name. EX: GameViewTest.swift => test the implementation GameView.swift and the ViewInspector Test code needs to extension GameView: Inspectable ()
But I don't know how to chop off the "Test" string!


See Also:

A very out of date example - but it got me started looking around.
https://thoughtbot.com/blog/creating-custom-xcode-templates

Xcode - Build Settings Reference inside the Xcode Help documents will give a hint at the keywords wrapped in three underscores to be used in templates.

A list of keywords used in templates:

https://help.apple.com/xcode/mac/11.4/index.html?localePath=en.lproj#/dev7fe737ce0

Xcode Marcin Rabieko wrote this article on templates:

https://itcraftapps.com/blog/xcode-templates-tutorial/