3

Symfony 1.4 プロジェクトに対して機能テストを実行していますが、最新のデータをフェッチしないため失敗し続けています。

テストは新しいサイト エントリを作成し、次にサイトで調査を行い、調査にデータを追加します。これらはそれぞれ別のページにあり、それぞれの作品です。データは確実にデータベースに存在します。最後のフォーム、survey_data を保存した後、調査ページに戻り、調査の詳細と追加されたすべてのデータ項目のリストを取得します。これは開発環境と本番環境で機能しますが、私の機能テストでは、survey_data リストは空です。ログを調べると、データベース (Doctrine & Postgres) からデータをフェッチしようとしません。しかし、数秒後に手動でブラウザにページをロードすると、リストが表示されます。(データベースをクリアせずに) ページに直接アクセスするテストを実行すると、リストが表示されるため、テスト ログインには表示する権利があります。そのページとコンテンツですが、最初は表示されません。

私の質問は、機能テストで DB から最新のデータを確実に取得するにはどうすればよいか、または新しい項目をデータベースに保存した後にローカル データ オブジェクト キャッシュを更新するにはどうすればよいかということです。

追加: 機能テストが拡張sfPHPUnitBaseFunctionalTestCaseされ、sfBrowser クラスを使用してページのコンテンツをチェックし、それらをナビゲートします

4

1 に答える 1

0

この問題は、Doctrine が実行中に更新するオブジェクトをキャッシュすることにあるようです。これは、実稼働環境での各 Web リクエストの後にクリアされます (実行ごとに 1 つのリクエスト)。ただし、テスト環境では、すべてが同じ実行で発生しているため、リクエスト間で持続するように見えます。

たとえば、新しいアイテムをリストに追加するプロセスをテストするときは面倒です-リストはメモリ内にあり(テストブラウザは以前にそのページにアクセスしました)、新しいアイテムが作成され、保存されますが、それらの間のリンクはありませんメモリ内で形成されます。

関連オブジェクトの対象を絞った更新

強制的に更新しようとしているオブジェクトがわかっている場合は、次のことができます。

$SomeDoctrineRecordObject->refreshRelated();          // for all relationships
$SomeDoctrineRecordObject->refreshRelated($relation); // for a specific one

(上記の List と Item の例では、$list->refreshRelated('item'))

これは Doctrine オブジェクトを既に使用している場合にのみ役立ちます。それ以外の場合は、更新する必要があるたびにルートまたはデータベースからプルする必要があります。より一般的なアプローチは、sfTestFunctionalクラスを拡張してメソッドをオーバーライドすることです。これにより、リレーションシップが変更される可能性があるため、更新をトリガーする必要があります。

すべてのオブジェクトの一般的なリフレッシュ

Doctrine のオブジェクトキャッシュをクリアするコード:

$manager = Doctrine_Manager::getInstance();
$connection = $manager->getCurrentConnection();
$tables = $connection->getTables();
foreach ( $tables as $table ) {
  $table->clear();
}

そして、それをカスタムの機能テスト オブジェクトにフックする方法の例:

class myTestFunctional extends sfTestFunctional
{
  public function get( $uri, $parameters = array(), $changeStack = true )
  {
    $this->clearEntityCache();
    return parent::get( $uri, $parameters, $changeStack );
  }
  public function click( $name, $arguments = array(), $options = array() )
  {
    $this->clearEntityCache();
    return parent::click( $name, $arguments, $options );
  }
  protected function clearEntityCache()
  {
    $manager = Doctrine_Manager::getInstance();
    $connection = $manager->getCurrentConnection();
    $tables = $connection->getTables();
    foreach ( $tables as $table ) {
      $table->clear();
    }
  }
}

したがって、URL を取得するかクリックしてページを変更するたびmyTestFunctionalに、メモリに保存されている Doctrine オブジェクトが消去されます。微妙ではありませんが、効果的であり、テスト自体を書くのが面倒になることはありません!

于 2013-11-21T00:40:42.420 に答える