6

私は最近、PHPUnitを使用していくつかのTDDに関与するようになりました。データベース駆動型アプリをテストし、今後数週間にわたって調査および実装することを計画していたDbUnit拡張機能について読む必要があります。

しかし、私は彼自身(セバスティアン・バーグマン)によるこのプレゼンテーションに出くわしました。彼は「できればMySQLに対するテストを避ける」というタイトルのスライドを持っており、私の逃亡に疑問を投げかけています。

MySQLに対してテストすべきでない理由を誰かが説明できますか?

ありがとう

4

3 に答える 3

6

2つの理由:

  • それは遅いです(そしてユニットテストは速い必要があります)
  • それはあなたの制御を超えた余分な障害点を追加します(DB接続が失敗したときにテストは本当に失敗しますか?)

代わりに、作成者が提案しているように、SQLiteなどのインメモリデータベースを使用してDALをテストする必要があります。これにより、上記の問題が解消されます。

ただし、このアプローチには欠点もあります。1つのデータベースダイアレクトからSQLiteへのSQLの移植で問題が発生する可能性があります。これは当然、DALのMySQL固有の部分をテストできないことを意味します。いつものように、それは両刃の剣です-ユニットテストの速度と分離は得られますが、信頼性は失われます(このように呼ぶことができれば)-SQLiteに合格した場合、MySQLで動作することを100%確信できますか?

DAL / DAOテストのコアを統合テストフェーズに任せるのはそれほど悪い考えではないかもしれません。統合テストフェーズでは、使用する実際のDBエンジンに対してそれらをテストし、単体テスト用に小さなものを残します。たとえば、マッピング(つまり、ORMを使用する場合)。

編集高速は決して厳密な要件ではありません-それはちょうど良い一般的なアドバイスです。TDDを実行する場合、開発者は単体テストを頻繁に実行します(このように考えてください。ローカルリポジトリへのすべてのコミット/すべての重要なコード変更には、単体テストを実行することによるコードベースの整合性チェックが必要です)-おそらくすべてではありませんが、確かに一部です。このプロセスを迅速に行う必要があります。

さて、遅いテストは通常​​次のように終了します。

  • 「男、これはとても遅いです...」
  • 「たぶん、そのうちのいくつかを実行することができます...後で残りを実行します」
  • この時点で、後で来ることはありません。
  • 「ねえ、私の最後のコミットは何も壊さなかったし、テストもまったく実行しなかった!」
  • 「どうしてやっぱり走るの?」

実行されていないテストを作成すると、テストを作成する目的がほとんど失われます。

このことは私と一緒に働いている友人に起こりました。彼のチームはテストスイートを+/- 20分実行し(DALテストは不十分で、IoCコンテナーはテストに関与していました)、開発者はいくつかのテストを実行し始め、すぐに「現在のビルドブレーカー」の電子メールが日常的になりました。彼らはかなり大きなスイートを持っていましたが、テストを破ることはそれほど悪くはありませんでした。

全体的に、あなたのアプローチは正しいようです-私はテストをSQLiteに移しません。私が提案したように、統合テストスイートでデータベースレイヤーをテストします(通常の単体テストスイートとは別に実行できるようにします)。

于 2012-07-16T20:38:55.310 に答える
3

セバスティアン・バーグマンが書いたスライド33のタイトルにはまったく同意しません。

(スライドからのメッセージは誤解されやすいので、彼の講義で本当の意味を説明してくれたと思います)

彼の紹介で述べたように、デバッグは最悪ですが、テストは困難です。

実際の環境でmySQLを使用している場合は、mySQLに対してテストする必要があります。そうしないと、SQLiteとmySQLの違いをデバッグしていることに気付くでしょう。

彼の方向性はユニットテスターではなく開発者に向けられていると思います。その意味で、コードデータベースを可能な限り中立に保つために必要な努力をすることも開発者に提案します。ユニットテスターだけでなく、プロジェクトのライフサイクル全体の品質を向上させます。mySQL自体の機能改善からも保護します。(過去には多くの問題がありました)。

ただし、SQLを使用する単一のコードをテストする場合は、他にどのようなテストを行ったとしても、それを本物に対してテストする必要があります。

私の練習は、データベース接続の抽象レイヤーを作成し、そのレイヤーに反応するテストを行うことです。続いて、テストするdbサーバーごとに異なる具象クラスを作成しています。

その環境が与えられれば、SQLiteに対して頻繁にテストできますが、実際のテストは少なくとも1日に1回実行されます。

于 2012-08-04T09:01:02.690 に答える
2

モデルはデータベースと密接に関連しているため、DbUnitを使用してモデル(ORMモデルを含むMVCと言えば)をテストします。他のすべて(主にコントローラー)には、モックオブジェクトを使用します。

単体テストの基本的な考え方は、一度に1単位のアプリケーションコード(クラス)のみをテストすることです。したがって、コードが直接機能しない限り、DBの使用は避けたほうがよいでしょう。

そしてもちろん、パフォーマンスは重要です。たとえば、モデルに対して最大500のテストがあり、ほとんどすべてがDBとフィクスチャを使用しています。非常に高速なコンピューターでこれらのテストをすべて実行するには、約30〜40秒かかります。コードカバレッジレポートの生成には約1分かかります。

于 2012-07-16T20:53:41.320 に答える