APIテスト自動化ツールKarateをBDDツールとして使う
Karateとは
Karateは主にe2eテストを自動化するツール。cucumber的なfeatureファイルを書くとそれを実行できる。WebAPIのテストがその中心的ターゲット
graalvmのjsライブラリで実現しているっぽいので、featureファイルからJavaも呼べる。
個人的にBDDというのが結構いいと思っていて、ビジネスルールの仕様なんかをビジネスサイドと意識合わせする場合に使えると思っている。アンクルボブはFitnesseというツールを作っている。
Fitnesseは名著『実践アジャイルテスト』でも紹介されていたもの
実践アジャイルテスト テスターとアジャイルチームのための実践ガイド (IT Architects' Archiveソフトウェア開発の実践)
- 作者:Janet Gregory,Lisa Crispin
- 発売日: 2009/11/28
- メディア: 大型本
Fitnesseはアイデアはいいんだけど、wiki文書にテスト埋め込むとかまでしなくていいと思っていた。もっと簡便でメンテしやすい開発者フレンドリーなLiving Documentないかなあ、と。有名どころでは、Cucumberとかがあるんだけど、結局テストコードをドキュメントに合わせて2重に書くので、正直使いたくない。
Karateは簡潔なDSLでAPI呼び出しの実行からアサーションまでをfeatureファイルに記述できる。かなり文書性が高く、テストコード特有の煩雑なノイズがない。普通に開発者が使うテストツールとしても使えると思う。
一つ思ったのが、ビジネスルール単体の仕様についてkarateで同様にかければユーザーとのコミュニケーションに便利なのではないか、と。 加えてSpring のBeanもテストしたいと思ってやってみた。
featureファイルはこんな感じ。
Feature: ビジネスロジックのテスト Background: * def CalcTestsRunner = Java.type('feature.calc.CalcFeatureTestsRunner') * table example | 入力値1 | 入力値2 | 期待結果 | | 10 | 20 | 30 | | 50 | 100 | 150 | | -10 | 10 | 0 | Scenario: シンプルなシナリオ * def x = 10 * def result = CalcTestsRunner.testAdd(x,20) * assert result == 30 Scenario Outline: データ駆動シナリオ データ例 <入力値1> + <入力値2> の結果は<期待結果>になる * def result = CalcTestsRunner.testAdd(<入力値1>,<入力値2>) * assert result == <期待結果> Examples: | example |
テストコードはこんな感じ
package feature.calc; import com.example.demo.DemoApplication; import com.example.demo.calc.CalcService; import com.intuit.karate.junit5.Karate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest(classes = DemoApplication.class) public class CalcFeatureTestsRunner { static CalcService calcService; @Autowired public void setCalcService(CalcService calcService) { CalcFeatureTestsRunner.calcService = calcService; } @Karate.Test Karate testCalc() { return Karate.run("calc").relativeTo(getClass()); } public static int testAdd(int input1,int input2){ //仕様を実現するコードを書いていく。流動的で良い return calcService.add(input1,input2); } }
featureファイルにはプロダクションコードのクラスを直接書かない。リファクタリングするとき面倒になるから。 こんな感じで実行できる。
レポートはこんな感じ
githubにアップしました。