質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.40%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Haskell

Haskellは高い機能性をもった関数型プログラミング言語で、他の手続き型プログラミング言語では難しいとされている関数でも容易に行うことができます。強い静的型付け、遅延評価などに対応しています。

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

Q&A

解決済

3回答

6570閲覧

DBなど副作用が絡む場合の自動テストをどう行うか

A_kirisaki

総合スコア2853

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Haskell

Haskellは高い機能性をもった関数型プログラミング言語で、他の手続き型プログラミング言語では難しいとされている関数でも容易に行うことができます。強い静的型付け、遅延評価などに対応しています。

Rust

Rustは、MoFoが支援するプログラミング言語。高速性を維持しつつも、メモリ管理を安全に行うことが可能な言語です。同じコンパイル言語であるC言語やC++では困難だったマルチスレッドを実装しやすく、並行性という点においても優れています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

0グッド

5クリップ

投稿2020/04/14 08:04

タグにはGo、Rust、Haskellと入れさせていただきましたが、それに限らず静的型付け言語でテストを行うにはどうすれば良いのかを考えています。方針的には2つあるかと思います。

  • 副作用の薄いラッパーを作り注入して、テスト時はモックと差し替える
  • 本番と同じコード(副作用をそのまま)を書いてテスト環境を作ってテストする。

前者のほうが実装としてはスマートですがやはり手間がかかります。それにDockerで気軽にコンテナを立てられたり、クラウド環境もコード化できている昨今の事情を考えると後者の手法でも良いのではないかと思っています。

おそらくベストプラクティスのでない問ではあるのでしょうが、実際現場でのテストコードの運用を踏まえた上でどうするのか良いかご教授いただければと思います。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

動的静的型付け言語で」と限定する意味がよくわかりませんが、単体テストと統合テストを混同してる気がする。

単体テスト→モックを使う
統合テスト→テスト用DBを使う

のがふつーじゃないかと。

そもそもテストするフェーズそのものが違うので、本番と同等のDBまで作って、そこへ接続してテストできるぐらいまでコードを作り込んでから全部ガッチャンコしてテストする、という発想がナシじゃないかと思いますが。

投稿2020/04/14 08:22

編集2020/04/14 08:33
gentaro

総合スコア8947

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

A_kirisaki

2020/04/14 08:28

「静的」です。そこに限定したのは型のせいでモックが作りにくいという事情があります。そして質問で述べたように昨今のような事情なら結合テストでやるようなものも単体テストレベルでやってしまった方が楽なのではないか、という疑問もあります。
gentaro

2020/04/14 08:40

あ、打ち間違いです。失礼。 テスト対象のシステムの規模が小さいとか、個人開発でやるんだったら好きなようにすればいいと思いますが、大規模開発になると事情は異なってくるでしょう。 テストを自動化する意味というのは、繰り返し何度も気軽にテストを回し、バグが発生した場合は直ちに原因を特定するためにあります。 システムの規模が大きくなると、ちょっとしたコード修正のたびにDBまで貫通したテストを毎回回すというのは速度面でも現実的じゃないですし、誰のどの修正が影響しているのか、という点でも見通しが悪くなります。 また、テストしたい観点も単体テストと統合・システムテストレベルでは異なってくるはずで、パフォーマンスやミドルウェアのトラブル時のテスト等、非機能要件に関わるものもありますが、そういうテストとある関数の閾値を意識したテスト、みたいなものは全く性質が異なりますし、全部一気にやる必要はありません。
A_kirisaki

2020/04/14 08:45

そうですね、規模によってもこの辺も変わってきそうな感じがします。 大規模な開発に携わったことがないのでその観点が抜けていました。 単体テストと結合テストの違いをもっと意識しようと思います。
guest

0

煮え切らない回答ではありますが、自分なら以下の観点を考慮しながら都度判断します。

  • (モックできる仕組み、あるいは逆にテスト用DBを用意するスクリプトなどの)実装・メンテコスト
  • テストの実行にかかる時間
  • 自動テストで何を保証したいか(これが一番大事)

投稿2020/04/14 08:48

igrep

総合スコア428

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

A_kirisaki

2020/04/14 08:51

> 自動テストで何を保証したいか まさしくその視点が抜けていました。そもそもテストで何を保証したいのかをよく考えるべきだったようです。
guest

0

ネットワーク接続をしない、メソッド単位のいわゆる単体テストレベルの確認を実施するのであれば、DBなどの外界へのアクセスはinterfaceを切って、モックを生成することが多いと思います。
Goだと golang/mock を使っているケースをよく見ます。もちろん自前でモックを作成しても問題はないです。

localhost内のネットワーク接続を伴うようなE2Eテストであればdocker-composeなどを用いてコンテナのDBにデータを格納してテストするケースが考えられます。

※自動テストが何を指すのか明確ではないですが、Pull Request が発行されたときにテスト実行して、その結果をフィードバックする、くらいに考えています。

自動テストでテストしたい内容にもよると思いますが、実際にSQLが発行され、その結果が正しいことを自動でテストしたいのであれば、後者のdockerなどのコンテナのDBをテストに用いることが多いのではないでしょうか。


(自動テストとは別に、別途テスト環境を構築してテストされることは必須かと)

投稿2020/04/14 08:38

d_tutuz

総合スコア730

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

A_kirisaki

2020/04/14 08:48

やはりある程度の規模を見込むのならばモックの利用が現実的のようですね。 golang/mockについては調査のときs目につけていたのでもっと深く調べてみたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.40%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問