日頃の行い

個人的な日頃の行いをつらつら書いてます\\\\ ٩( 'ω' )و ////

ScalaのTestツールScalaTestを使ってみた。

みなさん、こんばんは。
昨日書いたこちらの記事同様Scala書くのが最近とても楽しいので、Scala関連の記事を書こうと思います。

ScalaでTestを書こうと思って、とりあえず出てきたScalaTestというものを試してみました。
SEO高そうですね

使ってみた感想としては、とりあえず全部これでいいんじゃね感です。

|∧∧
|・ω・`) 今回検証に使ったレポジトリも置いておきますね
|o旦o
|―u'
""""""""""""""""'""""""


tarata/scalatest-getting-started · GitHub


とりあえず環境を用意しましょう。

  • Scala 2.11.4
  • sbt 0.13.7

を利用します。
build.sbtに

libraryDependencies += "org.scalatest" % "scalatest_2.11" % "2.2.1" % "test"

と書いてテストツールの準備は終了です。

早いですね。こんな感じです。

https://github.com/tarata/scalatest-getting-started/blob/master/build.sbt

これでsbt testと打てばとりあえずインストールが走り、テストが実行されます。
今はなにもないので、no tests executedとかそれらしきことを言われるでしょう。

次に、以下のことを試してみました。

1. xUnit形式でassertionを行う
2. Property based testingをやってみる

1. テストの形式を選ぶ

ScalaTestではxUnitの形式やBDDっぽくSpecで書く形式などいくつか用意されているようです。
今回はxUnitっぽくやってみました。
xUnit形式の場合、FunSuiteというクラスを継承してTestクラスを作成します。
書いたコードが以下のURLです。

scalatest-getting-started/Calculator.scala at master · tarata/scalatest-getting-started · GitHub

感想としては

  • xUnitっぽく書けました。(当然
  • assert使える(当然
  • ShouldMatchersというtraitを使うと自然言語っぽく書けて( ・∀・)イイ!!

という感じです。
ShouldMatchersは使い勝手そこそこよかったので、使えるかと。
色んな書き方があるようです。
もうちょっと色々試してみようかなぁと思います。

参考:http://www.scalatest.org/user_guide/using_matchers
その他のテスト形式はこちらのブログが綺麗にまとまっていたように感じました。


2. Property based testingをやってみる

そもそもProperty based testingってなんだよ。
って思ったのでぐぐってみて、下記のページを参考にしました。

Abstractivate: Property-based testing: what is it?

タイトルがそのまんま気になってる内容ですねw

Property-based tests make statements about the output of your code based on the input, and these statements are verified for many different possible inputs.

A property-based testing framework runs the same test over and over with generated input

google 翻訳したら以下のようになりました。

プロパティベースのテストは、入力に基づいて、コードの出力についてのステートメントを作成し、これらの記述は、多くの異なる可能な入力に対して検証される。

プロパティベースのテストフレームワークでは、生成された入力に何度も同じテストを実行します

可能な入力を大量に与えて、同一のテストを何度も行うということでしょうか。
HaskellのQuickCheckというものにおける考え方(?)のようです。
そちらの方も後で調べてみようかなと思います。

今回ScalaTestのページに載っていた2種類を試してみました。

Table-driven property checks

前者のTable-driven property checksはDataProvider的な印象を受けました。
自前で用意した入力に対して、テストを行うためです。

書いたテスト
scalatest-getting-started/CalculatorWithTableDrivenPropertyBased.scala at master · tarata/scalatest-getting-started · GitHub

Table関数を利用して、引数として与えたいデータをタプル形式で作り、forAll関数に渡せば良いみたいです。

使った感想

  • データプロバイダーぽい
  • データプロバイダーに慣れてるせいか使いやすかった

Generator-driven property checks

こちらは自前のデータではなく、適当なデータを作成してそのデータセットを入力として、テストを行うということができるようです。

書いたテスト
scalatest-getting-started/CalculatorWithGeneratorDrivenPropertyBased.scala at master · tarata/scalatest-getting-started · GitHub

これを利用する場合、build.sbtに

libraryDependencies += "org.scalacheck" %% "scalacheck" % "1.12.2" % "test"

を追記する必要があります。
もともとScalaCheckの機能のようですね。
HaskellのQuickCheckに対するものがScalaのScalaCheckなのでしょうか。

使った感想

  • 任意と言いつつ、完全なランダムではなさそう。
  • ⇒Test名に入力を含めた際にDuplicateTestNameExceptionが発生したため。
  • ⇒Int型を指定した際には0 , 1, -1, Int型の最大値・最小値とその他ちょっと大きめな値(どういう理由で選ばれたかわからない値)が指定されていたような印象
  • どのタイミングで使うのが良いのだろう。
  • ⇒テストは自分が気になる境界値に対して行うものだと思っているため、任意の入力をするというこのテスト用のデータセットをどのタイミングで使うかがわからない。

という感じでした。

まとめ

  • ScalaでテストするならとりあえずScalaTestを利用するのがよさそう
  • xUnitぽくもBDDぽくも書ける
  • データプロバイダー的なこともできる

やっぱ、sbtでテストできるのは楽ですね。