BackEnd

Go言語でGinkgoを利用してBDDしてみた

投稿日:2018年10月29日 更新日:

はじめに

こんにちはsuzukiです。Go言語の連載9回目です。
今回はライブラリのGinkgoを利用してBDDについて説明いたします。

BDDとは

BDD(BehaviorDrivenDevelopment)とはビヘイビア駆動開発と呼ばれる開発方法です。

  • 実現したい機能の振る舞い(要求仕様)を決める
  • 振る舞い(要求仕様)を元にテストコードを作成
  • テストコードを満たすための機能を開発
  • リファクタリングを行う

上記のように開発していきます。

振る舞いの意味については色々な意見があるかと思いますが、この記事では要求仕様として進めさせていただきます。

Ginkgoについて

今回使用するGinkgoについて主要な関数についてまとめさせていただきます。

Ginkgoの概要

BDDを進める上でテストコードの作成を行いやすくするためのライブラリです。
GomegaというMatcherのライブラリと併用して使うことでより自然言語でテストが書きやすくなります。GinkgoにはGomegaと依存関係はないですが、本家のサイトでは使われているので今回こちらも使用していきます。
Ginkgoは簡単にテストスイートの作成とテストスペックのテンプレートの作成が行えます。

Describe

テストスペックを作成すると元から入っている関数です。こちらのテキスト部分でテストの対象が何かを記述します。
こちらの中に要求仕様をまとめて記述を行ったりBeforeEachなどの関数をネストできます。

Context

こちらも機能的にはDescribeと同様ですが、特定の条件が何かを記述します。例えばユーザーの状態等をここで定義します。

It

こちらのItの中でテスト対象のアウトプットが何かを記述します。テストの対象が実際にどのような動きをしてほしいかなど。
同期で実行されるため、非同期の場合のテストを行う場合はDoneを利用します。

JustBeforeEach

BeforeEachブロックがすべて実行され、Itブロックが実行される直前に実行されます。 この事実を利用してBookの仕様を整理することができます。

BeforeEach

BeforeEachブロックはItブロックの前に実行されます。
ネストされたDescribeブロックとContextブロックで複数のBeforeEachブロックが定義されている場合、最も外側のBeforeEachブロックが最初に実行されます。

AfterEach

AfterEachブロックはItブロックの後に実行されます。
ネストされたDescribeブロックとContextブロックで複数のBeforeEachブロックが定義されている場合、最も外側のBeforeEachブロックが最初に実行されます。

BeforeSuite

BeforeSuiteブロックは、テストスペックが実行される前に一度だけ実行されます。
並列で複数のテストスペック実行する場合、各並列ノードプロセスはBeforeSuiteを呼び出します。

AfterSuite

AfterSuiteブロックは、テストスペックが成功したか失敗したかにかかわらず、すべての実行後に実行されます。 さらに、Ginkgoが割り込み信号(^ C)を受信すると、終了する前にAfterSuiteを実行しようとします。

Gomegaについて

GomegaライブラリはBDD向けのアサーションを提供してくれます。簡単にですが説明させていただきます。

Gomegaの概要

BDDを進める上でIt内のアサーションをわかりやすく作成することができます。
Testifyのアサーションに比べ、BDDを行いやすくするように直感的にわかりやすいアサーションが多くあります。
基本的に (ACTUAL).Should(アサーション(EXPECTED))という形で使われます。

Equal(EXPECTED)

ACTUALとEXPECTEDが等しいか比較を行います。
厳密な比較を行い、対象の型が同じかも比較されます。

BeEquivalentTo

Equal同様にACTUALとEXPECTEDが等しいか比較を行います。
違いとしては比較を行う前に、ACTUALの型をEXPECTEDの型に変換します。
したがって型自体の違いはあまり意識しません。

BeNil()

ACTUALがnilであるかを比較します。
Equalでnilを比較するとエラーになるためnilを比較する場合にはこちらを利用します。

BeZero()

ACTUALが0であるかを比較します。nilの場合も0として扱われ成功します。

ContainSubstring(STRING, ARGS…)

ACTUALに生成された部分文字列が含まれている場合は成功します。

ContainElement(ELEMENT)

ACTUALにELEMENTと等しい要素が含まれていると成功します。 ACTUALは配列、スライス、またはマップでなければなりません。それ以外はエラーです。 マップの場合、ContainElementはマップの値を検索します(キーではありません)。

BDDを試してみる

それでは実際にテストを作成していきます。

GinkGo導入方法

go get コマンドでライブラリの導入可能です。
Gomegaも合わせて取得しましょう。

テストスイート作成

Ginkgoのテストスイート作成機能を利用してテストスイートを作成します。

こちらのコマンドでディレクトリ名_suite_test.goというテストスイートが作成されます。
今回は/Triangleというディレクトリに下記のファイルが作成されました。

こちらでテストスイートの作成ができました。

スペックテンプレート作成

Ginkgoのテストスペック作成機能を利用してテストスペックのテンプレートを作成します。

triangleは開発を行う機能名に置き換えてください。
こちらのコマンドで下記のファイルが作成されました。

スペック作成

こちらのvar _ = Describe("Triangle", func() { }の中にスペックの内容を記述します。
今回の仕様がtriangleが面積の計算を行った時に

  • 底辺と高さが正の整数であるときに、面積を計算すると、底辺*高さ/2になる
  • 底辺か高さが負の整数であるときに、面積を計算すると、0になる
  • 底辺か高さが0であるときに、面積を計算すると、0になる

という要求仕様があるとした時に下記のように記述できます。
今回はアサーションを複数書いていますが、意味は一緒です。

Triangleの実装

今回の記事では詳細に触れる必要はあまりないと思っていますが、
前回の記事で作成を行ったトライアングルを元に下記のように実装しました。

Testの実行

Ginkgoのテストコマンドはginkgoです。こちらでテストの実行を行うことができます。

テスト失敗

個人的にBDDのメリットはテストの失敗した時の内容がとても便利だと思っております。
今回はわざとテストを失敗させました。
要求仕様のうちどれだけの機能が実装できていないかが簡単にわかります。

テスト成功

こちらは成功したパターンです。

今回こちらでテストが通過しました。
この後リファクタリングを行い開発が完了します。

今回のテストでは小規模な開発のため、テストを一回行っただけです。
大規模な開発であれば、テストを行うことで進捗率の確認であったり、既存の機能にデグレが発生していないかなどもこまめに確認が取れます。

さいごに

いかがでしたしょうか、私はプログラミングの進捗を報告することがよくあります。
まとめるために時間がかかったり、正確に伝わらなかったりするとストレスを感じるのですが、BDDでは進めたら納得しやすい値を簡単に出せそうだなと思いました。

おすすめ書籍

スターティングGo言語 (CodeZine BOOKS)  Goプログラミング実践入門 標準ライブラリでゼロからWebアプリを作る impress top gearシリーズ  みんなのGo言語[現場で使える実践テクニック]  Go言語でつくるインタプリタ

page_footer_300rect




page_footer_300rect




-BackEnd
-,

執筆者:


comment

メールアドレスが公開されることはありません。

CAPTCHA


関連記事

rails

RailsでERBからJavaScriptにhashを渡す方法

1 はじめに2 カスタムデータ属性とは3 実装例3.1 コントローラの実装3.2 ビューの実装3.3 実行結果4 さいごに はじめに 以前、選択したプルダウンメニューに応じて別のプルダウンメニューの内 ...

Go言語

Go言語のエラーハンドリングとログローテーション

1 はじめに2 エラーハンドリング2.1 error インターフェース2.2 pkg/errors パッケージ3 独自のエラータイプ付き errorsパッケージを作成4 log パッケージ4.1 lo ...

【Ruby Advent Calender 2017】Rubyでスクレイピングをしてみる【11日目】

1 はじめに1.1 概要2 仕様3 ソースコード4 使用したモジュール、Gem5 対象ページを取得6 XPATHから目的のものを抜き出す7 次のページのリンクを取得する8 他のサイトの記事でも試してみ ...

rails

Railsのバリデーション

1 はじめに2 基本的なバリデーション3 EachValidatorクラス4 Validatorクラス5 autoload_pathsの編集6 さいごに はじめに 今回はRailsのActiveRec ...

軽量なAlpine Linuxイメージでgitbookのローカル環境を構築する

1 はじめに2 Alpine Linuxとは3 Docker本体のインストール4 サンプルリポジトリのダウンロード5 dockerイメージ作成6 Gitbook初期化&実行7 Dockerの ...

フォロー

follow us in feedly

AppLink

英語

page_side_300rect

2018年10月
« 9月 11月 »
 123456
78910111213
14151617181920
21222324252627
28293031 

アプリ情報

目標を達成したい方を応援する、TODOアプリもリリースしております。 下記のアイコンから無料でダウンロードできます。

Web版MyCoach

私たちはより広い方にコーチングを知ってもらいたいと考えています。 下記のサイトにて、コーチの方々を紹介しておりますので、よろしければご覧ください。