🧠

XCTestGen: ChatGPTを使ったXCTest自動生成ツール

2023/03/13に公開

はじめに

タイトルの通り、今流行りのChatGPTを使ってSwiftのXCTestの自動生成ツールを作りました。どのように開発したのか、使い方などをざっくり解説します。
スターくれたら嬉しいです。

https://github.com/NakaokaRei/XCTestGen

CLIツールの作成

Swift Packagesを使い、CLIツールを作成しました。作業ディレクトリ下で以下のコマンドを実行するとテンプレートが作成されます。詳しい方法はSwift Packagesを使ったCLIの開発はいろんな方が解説しているのでそちらを参照ください。

https://qiita.com/uhooi/items/4a4d9694e8a362b6885f

$ swift package init --type executable

XCTestの自動生成

XCTestの自動生成にはタイトルの通りChatGPTを使用しています。ChatGPTに以下のように命令することで、XCTestを書いてもらいます。

日本語に翻訳すると以下のSwiftコードのユニットテスト(XCTest)を書いてください。出力したものをそのままソースコードとして保存したいので、説明文は不要です。という命令をしています。

Please write a unit test (XCTest) of the following Swift code. No explanatory text is required as we would like to save your output as source code as is.

// Sample.swift
class Sample {
    func sample(input: String) -> String {
    // 任意の処理
    }
}

SwiftでOpenAIのAPIを利用するには以下のライブラリを使用しました。
https://github.com/adamrushy/OpenAISwift

上記の命令をChatGPTに投げてレスポンスを指定されたフォルダ内に保存します。詳細を知りたい方はリポジトリのコードをご覧ください。

func generateXCTest() async throws {
        let order = "Please write a unit test (XCTest) of the following Swift code. No explanatory text is required as we would like to save your output as source code as is."
        let code: String

        do {
            code = try FileManager.readTextFile(atPath: input)
        } catch {
            throw XCTestGenError.readCodeError
        }

        let prompt = order + "\n\n" + code

        let openAI = OpenAISwift(authToken: key)
        let result = try await openAI.sendCompletion(with: prompt, maxTokens: maxTokens)

        guard let testCode = result.choices.first?.text else {
            throw XCTestGenError.chatgptResultError
        }

        do {
            try FileManager.saveTextFile(text: testCode, atPath: outputTestsPath())
        } catch {
            throw XCTestGenError.saveFileError
        }
    }

使い方

インストール

以下のコマンドを実行します。

$ git clone git@github.com:NakaokaRei/XCTestGen.git
$ cd XCTestGen
$ swift build -c release
$ cp .build/release/XCTestGen /usr/local/bin/XCTestGen

実行

以下のコマンドを実行します。第一引数から順に「OpenAIのAPI Key」、「テストを自動生成したいSwiftファイルのPath」、「出力先のディレクトリ」です。

$ XCTestGen $OPENAI_KEY "input file path" "output dir path"

以下のようなコードを与えた場合は

class Sample {
    func sample1(x: Int) -> Int {
        return x + 1
    }

    func sample2(x: String) -> String {
        return x + "sample"
    }
}

以下のコードが自動生成されます。

import XCTest

class SampleTests: XCTestCase {

    func test_sample1() {
        // given
        let expectedResult = 11
        let sampleInput = 10
        let sut = Sample()

        // when
        let result = sut.sample1(x: sampleInput)

        // then
        XCTAssertEqual(result, expectedResult)
    }

    func test_sample2() {
        // given
        let expectedResult = "testsample"
        let sampleInput = "test"
        let sut = Sample()

        // when
        let result = sut.sample2(x: sampleInput)

        // then
        XCTAssertEqual(result, expectedResult)
    }
}

最後に

今の課題としてChatGPTから生成されたテストコードが文法的に正しいかなどのチェックが行えてないのでSwiftLintなどを使って最低限のチェックは行なったほうがいいかなと思っています。
今後はSwift Package Mangerのプラグイン機能を追加し、Xcodeプロジェクトへの導入を簡単にできるようにしていく予定です。

株式会社ZOZO

Discussion