Slide 1

Slide 1 text

Circuits.GPIOは いかにテストされているか 2022/07/23 NervesJP #27

Slide 2

Slide 2 text

What’s Circuits.GPIO? ● Linux のGPIO(General-purpose input/output), 汎用入出力ピンを 操作するElixirのライブラリ ● NervesでLチカをやったことがあれば使ったことがあるはず ○ だけど、Nerves 専用のライブラリというわけではなく、 LinuxのGPIOを持ったマシンであれば、ピュア Elixirプロジェクトからも使用することができます。 iex> alias Circuits.GPIO iex> {:ok, pin} = GPIO.open(1, :output) iex> :ok = GPIO.write(pin, 1)

Slide 3

Slide 3 text

Circuits.GPIOの構成 ● lib/gpio.ex ○ ユーザ向けAPI用モジュール ● lib/gpio_nif.ex ○ nif用モジュール ● src/* ○ gpio操作の低レイヤ実装 ● test/cicuits_gpio_test.exs ○ テスト用モジュール、 mix test で実行される ○ ユーザ向けAPI用モジュールのテストを行う ちょっとだけ中身をのぞこう(時間あるかな?

Slide 4

Slide 4 text

Circuits.GPIOをテストするには? ● Linuxマシン固有のテストは 実機でなければできない なので、 - 実機でなければテストできない部分 - 実機でなくてもテストできる部分 に分けてやれば、 後者はどんな環境でもテストを回すことができる どのように分け、後者のテストをしているか興味あり!!

Slide 5

Slide 5 text

ユーザのAPIコールからGPIO操作までの流れ Circuit.GPIO Circuit.GPIO.Nif gpio_nif.c gpio_nif.h hal_sysfs.c /sys/class/gpio/* を操作 iex> alias Circuits.GPIO # /sys/class/gpio/1/direction を “out” iex> {:ok, pin} = GPIO.open(1, :output) # /sys/class/gpio/1/value を “1” iex> :ok = GPIO.write(pin, 1)

Slide 6

Slide 6 text

/sys/class/gpio/* なしでテストするために Circuit.GPIO Circuit.GPIO.Nif gpio_nif.c gpio_nif.h hal_sysfs.c hal_stab.c テスト用実装

Slide 7

Slide 7 text

ポイント Circuit.GPIO Circuit.GPIO.Nif gpio_nif.c gpio_nif.h hal_sysfs.c hal_stab.c テスト用実装 インタフェースを定 義 sysfs非依存の ロジックを実装 sysfsをシミュレートするので はなく、テストに必要な応答 のみをする薄い実装にする テスト範囲は ユーザ向けAPIの関数から、 インタフェース関数の呼び出しま で 操作実装の切り替えは Makefileで

Slide 8

Slide 8 text

このパターンは?見覚えが、、 ● そう、Moxでやることと同じ ○ Mox: Elixir のテストサポートライブラリ https://github.com/dashbitco/mox NervesJP.Behabiour NervesJP.Impl NervesJP.Mock ビヘイビアで各関数の入出力、 インタフェースを定義する OSのファイル操作や外部のWeb APIなど 応答をコントロールできない関数を まとめたモジュール 応答をコントロール可能なMockに切り替え、 このインタフェースを呼び出す ロジックのテストを可能にする

Slide 9

Slide 9 text

まとめ ● Circuits.GPIOがどのようにテストされているかを紹介しました ● POINT: インタフェースを定義して、 その内部実装を切り替える方法はテストに限らず有効!なことを理解しました ○ Cならヘッダファイルがインタフェースとして使える ○ ElixirならBehaviourがインタフェースとして使える Have nice Nerves days!!! Thank you!!