【问题标题】:Symfony 1.4 functional test not displaying new dataSymfony 1.4 功能测试不显示新数据
【发布时间】:2013-07-12 18:09:37
【问题描述】:

我正在对我的 Symfony 1.4 项目进行功能测试,但它一直失败,因为它没有获取最新数据。

测试组成一个新的站点条目,然后在该站点进行调查,然后将数据添加到调查中。这些中的每一个都在单独的页面和每个作品上。数据肯定存在于数据库中。保存最后一个表单survey_data 后,它会返回到调查页面,在该页面中应该获取调查详细信息以及添加到其中的所有数据项的列表。这适用于开发和生产环境,但在我的功能测试中,survey_data 列表为空。查看日志,它不会尝试从数据库中获取数据(Doctrine & Postgres)。但是,如果我在几秒钟后在浏览器中手动加载页面,列表就在那里,如果我运行一个直接进入页面的测试(不清除数据库),列表就在那里,所以测试登录有权查看该页面和内容,但一开始不会显示,好像在添加survey_data之前已经缓存了页面调查页面。

所以我的问题是,如何确保我的功能测试从数据库中获取最新数据,或者如何在将新项目保存到数据库后刷新本地数据对象缓存?

附加: 我的功能测试扩展了sfPHPUnitBaseFunctionalTestCase,我使用 sfBrowser 类来检查页面的内容并浏览它们

【问题讨论】:

  • “它不尝试获取数据”是什么意思?这是否意味着您的survey_data 详细信息中的数据库查询未执行?如果是这样,也许您的功能测试没有将您的用户重定向到正确的页面?
  • 正确,不执行对子数据详细信息的查询。它正在返回正确的页面,我通过检查返回页面的来源以及报告它正在使用的操作和视图的调试语句来确认这一点。

标签: caching symfony-1.4 functional-testing


【解决方案1】:

问题似乎在于 Doctrine 在执行期间缓存了它更新的任何对象。这会在生产环境中的每个 Web 请求之后被清除 - 每次执行一个请求 - 但在测试环境中,它似乎在请求之间持续存在,因为它们都发生在同一次执行中。

在测试将新项目添加到列表的过程时变得很麻烦 - 列表在内存中(测试浏览器之前已经访问过它的页面),新项目被创建,保存但它们之间的链接不是在内存中形成的。

相关对象的针对性刷新

如果您知道要强制刷新的对象,您可以:

$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();
    }
  }
}

因此,每次myTestFunctional 获取 url 或单击更改页面时,它都会清除内存中存储的任何 Doctrine 对象。不微妙,但有效,并且不会使测试本身更费力地编写!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-20
    • 1970-01-01
    • 2013-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-06
    相关资源
    最近更新 更多