KarateによるAPIのシナリオテスト自動化 #08 Running Karate

# はじめに
[前回（#07 Test-Double）](https://qiita.com/takanorig/items/5f63806219ae30a8f09a) は、Karate によるテストダブルの実現方法について確認しました。

これまで、主に Karate の Feature ファイルを元にした利用方法をまとめて来ましたが、一度、Karate の実行方法についてまとめたいと思います。
というのも、自分自身、「あれ、こういうのどのように実行するんだっけ？」と調べ直すことが多かったので、整理してまとめておこうと思った次第です（汗）
そのため、本記事は、リファレンス目的で活用できるようにしたいと思います。

# 基本

ディレクトリ構成や初期設定は、以下を参考にしてください。

- https://github.com/intuit/karate#getting-started

## テストシナリオの実行

### 全ての Feature を実行する場合
基本となるテストシナリオの実行方法です。

```:Maven
mvn clean test
```

```:Gradle
gradle clean test
```

### Feature を指定して実行する場合
特定のシナリオだけ実行したい場合は、以下のように実行できます。

#### 特定のディレクトリにあるもの（Runner単位）で実行する場合

```:Maven
mvn clean test -Dtest=XxxRunner
```

```:Gradle
gradle clean test -Dtest=XxxRunner
```

#### Featureファイル単体で実行する場合

```:Maven
mvn clean test -Dkarate.options="classpath:example/01/xxxx.feature"
```

```:Gradle
gradle clean test -Dkarate.options="classpath:example/01/xxxx.feature"
```

さらに、StandaloneJAR(karate.jar)を利用することもできます。

```:karate.jar
java -jar karate.jar xxxx.feature
```


## テストシナリオの除外

### 特定の Feature／Scenario を除外する場合
特定の feature ファイルやシナリオを除外する場合は、Karateのtagの機能を利用して実現できます。

- https://github.com/intuit/karate#tags

まず、前提として、以下のようなディレクトリ構成があるとします（Karateの標準的なディレクトリ構成です）。

```
src
└── test
    └── java
        ├── examples
        │   ├── KarateExamplesTest.java
        │   ├── tutorial
        │       ├── TutorialRunner.java
        │       └── tutorial.feature
        └── karate-config.js
```

```java:KarateExamplesTest
@KarateOptions(tags = "~@ignore")
@RunWith(Karate.class)
public class KarateExamplesTest {
}
```
ここで、```@KarateOptions(tags = "~@ignore")``` アノテーションを指定しておきます。
このアノテーションを指定しておくと、```@ignore``` が指定されたシナリオが除外されます。

```java:TutorialRunner
@RunWith(Karate.class)
public class TutorialRunner {
}
```

```cucumber:tutorial.feature
@ignore
Feature: Tutorial Testing

Background:
* url 'https//localhost:8089'

Scenario: get all
    ・・・
```
上記の場合、```Feature``` 自体に ```@ignore``` を指定しているので、この Feature ファイル全体のシナリオが、実行時に除外されます。

### Feature の中で、一部の Scenario を除外する場合

以下のような Feature ファイルがあるとします。

```cucumber:ignore-example.feature
Feature: Ignore Example Testing

@ignore
Scenario: シナリオ1
    ・・・

Scenario: シナリオ2
    ・・・

Scenario: シナリオ3
    ・・・
```

上記のような場合に、```@ignore``` を指定した Scenario だけを除外して実行する場合は、以下のようにします。

```:Maven
mvn clean test -Dtest=XxxRunner -Dkarate.options="--tags ~@ignore"
```


## 並列実行
テストシナリオを並列で実行させることも可能です。
```Runner.parallel``` で、5並列で実行することになります。

```java
public class TestParallelRunner {
    
    @Test
    public void testParallel() {
        String outputPath = "target/surefire-reports";
        Results results = Runner.parallel(getClass(), 5, outputPath);
        assertTrue(results.getErrorMessages(), results.getFailCount() == 0);
    }
}
```

<font color="Red">
<b>※注意※</b>
並列実行の場合は、Runnerに ```@RunWith(Karate.class)``` アノテーションは指定してはいけません。
</font>


# 環境変数／プロファイル
```karate-config.js``` を利用すると、全体で共通の環境変数やプロファイルを利用することができるようになります。

```js:karate-config.js
function() {    
  var env = karate.env; // get system property 'karate.env'
  karate.log('karate.env system property was:', env);
  if (!env) {
    env = 'dev';
  }
  var config = {
    env: env,
    myBaseUrl: 'http://localhost:8089',
    myVarName: karate.properties['MY_VAR_NAME']
  }
  if (env == 'dev') {
    // customize
    // e.g. config.foo = 'bar';
  } else if (env == 'e2e') {
    // customize
  }
  return config;
}
```

## 環境変数の利用
```karate-config.js``` 中で環境変数を利用したい場合は、 ```karate.properties['PARAM_NAME']``` というかたちで、対象の変数を取得することができます。
また、 ```karate-config.js``` 中の ```config``` で指定した変数は、各featureファイルの中で利用することができます。

```
Background:
* url myBaseUrl
```

## プロファイルの利用
以下のように、実行時にオプションを指定することで、プロファイルを切り替えることができます。
環境によって、テスト全体の設定を変えたい場合などに利用すると便利です。

```:Maven
mvn clean test -DargLine="-Dkarate.env=e2e"
```

```:Gradle
gradle clean test -Dkarate.env=e2e
```