2019年3月15日金曜日

NativeExtensions のテスト書く方法

概要

前回 NativeExtensions で Struct を使う方法を紹介しました
ライブラリを書けば当然テストしたくなります
NativeExtensions の場合少しクセがあるのでやり方の流れを紹介します

環境

  • CentOS 7.5.1804
  • Ruby 2.5.0p0

必要なファイル

spec ファイル関連のファイルが必要になります
bundle gem でプロジェクトを作成する際に -t オプションがあればテストに必要なファイルを一通り作成してくれます

.rspec
spec/firstext_spec.rb
spec/spec_helper.rb

rake-compiler のインストール

これを使ったほうが簡単 (というか公式のやり方) なのでこれを使います

  • vim firstext.gemspec
spec.add_development_dependency "rake-compiler"
  • bundle install --path vendor

Rakefile の編集

compile タスクを使えるようにします

  • vim Rakefile
require "bundler/gem_tasks"
require "rspec/core/rake_task"
require "rake/extensiontask"

Rake::ExtensionTask.new "firstext" do |ext|
  ext.lib_dir = "lib"
end

RSpec::Core::RakeTask.new(:spec)

task :default => :spec

ポイントは ext.lib_dir = "lib" の部分です
このパスに Makefile から作成される so ファイルを配置します
このパスに配置することで require 'firstext' できるようになります
ただ、このパスにはすでに lib/firstext.rb があります
どうやらこのファイルが優先されるようで、これがあるとせっかく C で実装したコードが参照されません
なので削除しておきます

  • rm lib/firstext.rb

rb ファイルを残したい場合は rake compile 時に吐き出されるファイル名を変更する方法もあります
が、その場合は require するのも吐き出されるファイル名になるのでご注意ください

lib/firstext/version.rb

module になっている部分を class に変更します
ここが module のままだと module が優先されて NativeExtensions 側のクラスが参照できなくなります

  • vim lib/firstext/version.rb
class FirstExt
  VERSION = "0.1.0"
end

spec/spec_helper.rb

特に何もしません

spec/firstext_spec.rb

ではテストを書きましょう
前回 NativeExtensions で実装した関数を呼び出しているだけです

  • vim spec/firstext_spec.rb
RSpec.describe FirstExt do
  it "has a version number" do
    expect(FirstExt::VERSION).not_to be nil
  end

  it "create a instance" do
    cli = FirstExt.new
    cli.set
    cli.show
  end
end

動作確認

  • bundle exec rake spec

でテストが動くはずです
うまく NativeExtensions で作成したクラスが参照できない場合は rake copile で so ファイルを再配置してみてください
もしくは so ファイル自体が指定のパスにあるか確認してください

また ext/firstext 配下に firstext.ofirstext.so などの成果物がある場合は削除しましょう
rake compile がエラーを吐きうまく動かないケースがあるようです

最後に

NativeExtensions で RSpec を使ってテストを書く方法を紹介しました
成果物の so ファイルを rb ファイルの代わりに配置するのがポイントです

NativeExtensions を変更した場合は再度 rake compile して成果物をデプロイする必要があります
あとは普通に spec テストを書いていけば OK です

参考サイト

0 件のコメント:

コメントを投稿