Help us understand the problem. What is going on with this article?

[Blender] GitHubとTravisCIを用いてBlenderアドオンのテストを自動化する

More than 5 years have passed since last update.

Blenderのアドオン開発に限らずにソフトウェアの開発全体に対して言えることですが、ソースコードを更新するたびにきちんと動作することを毎回確認するのは面倒ですよね。

本記事では、GitHubとTravis CIを用いてBlenderアドオンのテストを自動化する方法を紹介します。

前準備

本記事ではテスト自動化のために、CI(継続的インテグレーション)サービスの Travis CI とホスティングサービスの GitHub を利用します。
GitHubとTravis CIの使い方をここで説明すると長くなりますので省略します。
GitHubやTravis CIについてはウェブ上にたくさんの記事がありますので、各自参考にして以下のことができるようになるまで準備を進めてください。

  1. GitHub
    • アカウント作成
    • リポジトリ作成
    • 作成したリポジトリへのpush
  2. Travis CI
    • GitHubアカウントでログイン
    • GitHubで作成したリポジトリをテスト対象に設定

GitHubとTravis CIについては、例えば以下のサイトが参考になるでしょう。

ファイル構成

BlenderのアドオンをTravis CIでテストするためのファイル構成を以下に示します。

/    # リポジトリのルートディレクトリ
├ .travis.yml     # Travis CI用設定ファイル
├ test_addon.py   # テストするアドオン
├ run_tests.py    # 個別のテストを呼び出すスクリプト
├ test_1.py       # test_addon.pyのテストスクリプト
└ test_1.blend    # test_1.py用の.blendファイル

アドオンの作成

テスト対象とするアドオンを作成します。ファイル名を test_addon.py としてください。
テスト対象のオペレーションクラスを1つ用意した単純なアドオンになっています。
なおアドオンの作り方については、以下の記事を参考にしてください。

test_addon.py
import bpy

bl_info = {
    "name": "テストするアドオン",
    "author": "Nutti",
    "version": (1, 0),
    "blender": (2, 75, 0),
    "location": "UV Mapping > テストするアドオン",
    "description": "テスト対象のアドオン",
    "warning": "",
    "support": "TESTING",
    "wiki_url": "",
    "tracker_url": "",
    "category": "UV"
}


class TestOps(bpy.types.Operator):

    bl_idname = "uv.test_ops"
    bl_label = "テスト"
    bl_description = "テストするオペレーション"
    bl_options = {'REGISTER', 'UNDO'}

    def execute(self, context):
        return {'FINISHED'}


def register():
    bpy.utils.register_module(__name__)


def unregister():
    bpy.utils.unregister_module(__name__)


if __name__ == "__main__":
    register()

Travis CI用設定ファイル(.travis.yml)の作成

続いて、Travis CI用の設定ファイルを .travis.yml として保存します。
.travis.yml の解説はコメントに記載しています。
基本的にはコメントの記載内容で理解できると思いますが、 .travis.yml の書き方に困った場合は以下の記事が参考になるでしょう。

.travis.yml
# プログラミング言語の指定
# BlenderのアドオンはPythonで記述するためpythonを指定
language: python

# 使用するPythonのバージョン
# ★BlenderのPythonコンソールから利用されているPythonのバージョンを特定可能
python:
  - "3.4"

# install前に実行する処理
before_install:
  # 可能な限り最新のBlenderをインストール
  # パッケージマネージャー経由でインストールすることで、Blenderに依存しているパッケージを自動的にインストール(手動で依存するパッケージをインストールするのは手間がかかるため)
  - sudo apt-get update -qq
  - sudo apt-get install blender

# テスト実行の前準備
install:
  # 作業領域の作成し、移動
  - mkdir tmp && cd tmp
  # ★最新版のBlenderをダウンロード
  - wget http://mirror.cs.umn.edu/blender.org/release/Blender2.76/blender-2.76-linux-glibc211-x86_64.tar.bz2
  # ★ダウンロードしたBlenderを解凍
  - tar jxf blender-2.76-linux-glibc211-x86_64.tar.bz2
  - mv blender-2.76-linux-glibc211-x86_64 blender
  - rm blender-2.76-linux-glibc211-x86_64.tar.bz2
  - cd ..
  # ★アドオンをインストール(Blenderのバージョンに合わせて、ディレクトリを指定)
  - sudo ln -s ${PWD}/test_addon.py ${PWD}/tmp/blender/2.76/scripts/addons/test_addon.py

# テスト実行
script: python ${PWD}/run_tests.py ${PWD}/tmp/blender/blender

テストスクリプトの作成

.travis.ymlscript に書かれたコマンドが実行されてテストが開始されます。

実行されるテストスクリプト run_tests.py を作成します。
これは、個別のテストを呼び出す大元のテストスクリプトになります。
テストスクリプトは、Blenderのアドオンの開発言語であるPythonで書きます。

UI表示をなくすため、Blenderをコマンドラインで実行するところがポイントです。
Blenderをコマンドラインから実行するときに指定できるオプションは、以下のサイトから確認することができます。

http://wiki.blender.org/index.php/Doc:JA/2.6/Manual/Render/Command_Line

run_tests.py
import sys
import subprocess

if len(sys.argv) != 2:
    exit(-1)

blender_path = sys.argv[1]     # Blender本体のパス

addon_name = 'test_addon'      # テストするアドオン
blend_file = 'test_1.blend'    # テスト用に作成した.blendファイル
src_file = 'test_1.py'         # 個別のテスト用スクリプト

# 個別のテスト用スクリプト(test_1.py)を実行
# 実行されるコマンド: blender --addons test_addon --factory-startup -noaudio -b test_1.blend --python test_1.py
# オプション: 
#   --addons: test_addonを有効化
#   --factory-startup: startup.blendファイルを読み込まない
#   -noaudio: サウンドの無効化
#   -b: UIなしBlender起動
#   blend_file: 読み込む.blendファイル
#   --python: src_fileに指定したPythonスクリプトを実行
subprocess.call([blender_path, '--addons', addon_name, '--factory-startup', '-noaudio', '-b', blend_file, '--python', src_file])

続いて run_tests.py から呼ばれる、個別のテスト用スクリプト test_1.py を作成します。
テストの方法はいろいろありますが、Pythonのテストフレームワークであるunittestモジュールを利用するのが手っ取り早いでしょう。

http://docs.python.jp/2/library/unittest.html

test_1.py
import unittest    # Pythonのテストフレームワーク
import bpy

# テストセット
class TestAddon(unittest.TestCase):
    # アドオンが正常に有効化されたことを確認
    def test_addon_enabled(self):
        self.assertIsNotNone(by.ops.uv.test_ops)

    # アドオンを実行して正常終了したことを確認
    def test_execute(self):
        result = boy.ops.uv.test_ops()
        self.assertSetEqual(result, {'FINISHED'})


# テストセットの作成
suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestAddon)
# テスト実行
unittest.TextTestRunner().run(suite)

最後に、Blender起動時の状態で.blendファイルを test_1.blend として保存しましょう。
test_1.blend は、テスト実行時に利用する.blendファイルです。

実際にテストする場合は、実行したいテストに合わせて.blendファイルを作成する必要があります。
今回は簡単のため、Blender起動時の状態を保存しました。

テストの実行

テスト対象にしたリポジトリへ push することで自動的にテストが実行されます。

run_test.sh
$ git push

addon_test_1.png

テスト結果の確認

Travis CIのサイトからテストの実行結果を確認してみましょう。
テストがうまくいっていれば以下のような画面になっていると思います。

addon_test_2.png

テスト実行時の内容の詳細もWeb上から確認することができ .travis.yml に記載した処理が実行されていることがわかります。
今回は test_addon_enabledtest_execute の2つのテストを実行しているため Ran 2 tests in 0.001s と表示されています。
その後にテストが通ったことを示す OK が出力されているため、テストが無事に通ったことがわかります。

addon_test_3.png

テストはリポジトリにpushする度に行われるため、アドオンを更新した時に問題ないかどうかを手作業で確認する必要がなくなります。
テストの手間と手作業による確認ミスを防ぐことができ、アドオン開発者は開発に集中することができますので、自動化できる部分はどんどん自動化してしまいましょう。

参考資料

nutti
同人ゲーム開発、Blenderアドオン開発、DTM
https://colorful-pico.net
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away