【问题标题】:CakePHP Test Fixtures Drop My Tables Permanently After Running A Test CaseCakePHP 测试装置在运行测试用例后永久删除我的表
【发布时间】:2011-02-01 21:55:24
【问题描述】:

我不确定我在 CakePHP 单元测试配置中做错了什么。每次我运行一个测试用例时,我的测试数据库中都会丢失与我的夹具关联的模型表。

运行单个测试用例后,我必须使用 phpMyAdmin 重新导入我的数据库表。

以下是相关文件:

这是我要测试comment.php 的类。该表在测试后被删除。

  App::import('Sanitize');

  class Comment extends AppModel{
  public $name      = 'Comment';

  public $actsAs    = array('Tree');

     public $belongsTo = array('User' => array('fields'=>array('id', 'username')));

  public $validate = array(
  'text'        => array(
  'rule'      =>array('between', 1, 4000),
  'required'  =>'true',
  'allowEmpty'=>'false',
  'message'   => "You can't leave your comment text empty!")
  );

database.php

class DATABASE_CONFIG {

var $default = array(
'driver'     => 'mysql',
'persistent' => false,
'host'       => 'project.db',
'login'      => 'projectman',
'password'   => 'projectpassword',
'database'   => 'projectdb',
'prefix'     => ''
);

var $test = array(
'driver'     => 'mysql',
'persistent' => false,
'host'       => 'project.db',
'login'      => 'projectman',
'password'   => 'projectpassword',
'database'   => 'testprojectdb',
'prefix'     => ''
 );
 }

我的comment.test.php 文件。这是不断被丢弃的表。

<?php
App::import('Model', 'Comment');

class CommentTestCase extends CakeTestCase
{

  public $fixtures = array('app.comment');

  function start(){
    $this->Comment =& ClassRegistry::init('Comment');
    $this->Comment->useDbConfig = 'test_suite';
  }

这是我的comment_fixture.php 类:

  <?php
   class CommentFixture extends CakeTestFixture
   {
     var $name = "Comment";

     var $import = 'Comment';
   }

以防万一,这里是 CommentTestCase 类中的一个典型测试方法

   function testMsgNotificationUserComment(){
   $user_id       = '1';
    $submission_id = '1';
    $parent_id = $this->Comment->commentOnModel('Submission', $submission_id,     '0',    $user_id, "Says: A");

  $other_user_id = '2';
   $msg_id = $this->Comment->commentOnModel('Submission', $submission_id, $parent_id,      $other_user_id, "Says: B");

  $expected = array(array('Comment'=>array('id'=>$msg_id, 'text'=>"Says: B", 'submission_id'=>$submission_id, 'topic_id'=>'0', 'ack'=>'0')));

  $result = $this->Comment->getMessages($user_id);

  $this->assertEqual($result, $expected);
}

我已经处理了一天了,我开始对 CakePHP 的单元测试感到厌烦。除了这个问题,Servral 时代现在我已经在运行测试后通过“默认”数据库配置插入了数据!我的配置怎么了?!

【问题讨论】:

    标签: cakephp testing


    【解决方案1】:

    我认为是这样的。 Fixtures 是具有fixed 内容的fixed 表格。它们不是您在生产或开发过程中以其他方式使用的表。这就是为什么他们在database.php 中有一个单独的连接,您应该使用不同的数据库或至少为测试表使用不同的前缀。这些将在每次测试之前根据您的固定装置创建并在之后拆除,因此您始终针对一组已知数据进行测试。

    【讨论】:

    • 那么是不是不能先运行一个测试用例,比如CommentTestCase,然后马上再次运行CommentTestCase?我只是尝试使用 CakePHP test.php 页面来多次运行 CommentTestCase 而无需重新导入整个数据库。
    • @Frank 你可以连续运行它多次,只要你在夹具中提供数据。测试用例并不意味着只使用数据库中的数据来运行,数据库设置(和拆卸)是测试运行的一部分。
    • @Frank 你可以告诉夹具从现有表中获取数据,但它仍会设置一个单独的表(至少你应该这样做)最后把它撕下来。我希望你已经阅读了手册? book.cakephp.org/view/358/Preparing-test-data
    • 是的,我已经多次阅读手册的测试部分,试图弄清楚发生了什么。您提到:“只要您提供夹具中的数据”。在我的测试用例中,我不是在夹具中而是在测试方法中生成数据。我想这是不正确的,它必须在固定装置中?
    • @Frank 为了区分,我认为你应该使用fixtures来生成数据。我想,在这种情况下 where 你生成数据并没有太大的区别。关键是,如果您使用的是夹具,它们会在测试结束时拆除您的测试表。我对 Cake 测试的细节知之甚少,无法告诉您是否或如何放弃使用固定装置。由于您可能没有做任何特别的事情,因此您应该将您的方法放入已建立的框架中(在单独的表中使用固定装置)。
    【解决方案2】:

    您的数据库配置看起来不错...

    你不应该这样做

    $this->Comment->useDbConfig = 'test_suite';
    

    我的建议

    您应该使用cake bake shell 为您的所有模型创建模型并让它覆盖它们(显然首先备份任何自定义模型)。您不需要通过验证和关联提示(比如“n”),但对所有覆盖都是肯定的(同样,请先备份您的代码)。

    当您这样做时,它还会为模型创建一个基本测试用例和一个夹具。

    使用它创建的测试用例,并添加到它...

    然后你需要调用你使用的每一个fixture和所有关联的fixture...所有hasMany和belongsTo和HABTM关联都需要加载fixture,但它们不会在测试中自动调用套房。

    note.test.php

    <?php 
    App::import('Model', 'Note');
    class NoteTestCase extends CakeTestCase {
        var $Note = null;
        var $fixtures = array(
            'app.note',
            'app.version',
            'app.corp',
            'app.advertisement',
            'app.member',
            'app.member_detail',
            'app.member_newsletter',
            'app.groups_members_join',
            'app.group',
            'app.job',
            'app.job_category',
            'app.jobs_categories_join',
            );
        function startTest() {
            $this->Note =& ClassRegistry::init('Note');
        }
        function testNoteInstance() {
            $this->assertTrue(is_a($this->Note, 'Note'));
        }
        function testNoteFind() {
            $this->Note->recursive = -1;
            $results = $this->Note->find('first');
            $this->assertTrue(!empty($results));
            $expected = array('Note' => array(
                'id' => 1,
                'model' => 'Lorem ipsum dolor sit amet',
                'model_id' => 1,
                'created' => '2010-03-30 16:26:59',
                'member_id' => 1,
                'body' => 'Lorem ipsum dolor sit amet, aliquet feugiat. Convallis morbi fringilla gravida,phasellus feugiat dapibus velit nunc, pulvinar eget sollicitudin venenatis cum nullam,vivamus ut a sed, mollitia lectus. Nulla vestibulum massa neque ut et, id hendrerit sit,feugiat in taciti enim proin nibh, tempor dignissim, rhoncus duis vestibulum nunc mattis convallis.',
                'is_active' => 1
            ));
            $this->assertEqual($results, $expected);
        }
        function testJobWithNotes() {
            $this->Job =& ClassRegistry::init('Job');
            $uniqueValue = rand(0,time());
            $savedJob = $this->Job->saveAll(array(
                'Job' => array(
                    'title' => "Test Job [$uniqueValue] from ".__FILE__,
                ),
                'Note' => array(
                    array(
                        'model' => "Job",
                        'body' => "Here is a unique value [$uniqueValue]")
                )));
            $this->assertTrue($savedJob);
            $this->assertEqual($this->Note->find('first',array(
                'fields' => array('body'),
                'conditions' => array('model_id' => $this->Job->id, 'model' => $this->Job->name))),
                array('Note'=>array('body'=>"Here is a unique value [$uniqueValue]")));
        }
    }
    ?>
    

    如果你想要的话,这里是

    note_fixture.php

    <?php 
    class NoteFixture extends CakeTestFixture {
        var $name = 'Note';
        var $fields = array(
            'id' => array('type'=>'integer', 'null' => false, 'default' => NULL, 'key' => 'primary'),
            'model' => array('type'=>'string', 'null' => false, 'default' => NULL, 'length' => 32),
            'model_id' => array('type'=>'integer', 'null' => false, 'default' => NULL),
            'created' => array('type'=>'datetime', 'null' => false, 'default' => NULL),
            'member_id' => array('type'=>'integer', 'null' => false, 'default' => NULL),
            'body' => array('type'=>'text', 'null' => false, 'default' => NULL),
            'is_active' => array('type'=>'boolean', 'null' => false, 'default' => '1'),
            'indexes' => array('PRIMARY' => array('column' => 'id', 'unique' => 1))
        );
        var $records = array(array(
            'id' => 1,
            'model' => 'Lorem ipsum dolor sit amet',
            'model_id' => 1,
            'created' => '2010-03-30 16:26:59',
            'member_id' => 1,
            'body' => 'Lorem ipsum dolor sit amet, aliquet feugiat. Convallis morbi fringilla gravida,phasellus feugiat dapibus velit nunc, pulvinar eget sollicitudin venenatis cum nullam,vivamus ut a sed, mollitia lectus. Nulla vestibulum massa neque ut et, id hendrerit sit,feugiat in taciti enim proin nibh, tempor dignissim, rhoncus duis vestibulum nunc mattis convallis.',
            'is_active' => 1
        ));
    }
    ?>
    

    【讨论】:

      【解决方案3】:

      在你的 CakeTestCase 类中,放一个成员dropTables

      <?php
      App::import('Model', 'Comment');
      
      class CommentTestCase extends CakeTestCase
      {
      
        public $fixtures = array('app.comment');
        public $dropTables = false; // <- here it is 
      
        function start(){
          $this->Comment =& ClassRegistry::init('Comment');
          $this->Comment->useDbConfig = 'test_suite';
        }
      

      【讨论】:

      • 我有 $droptables = false 但我的表仍然每次都被删除。
      猜你喜欢
      • 2019-01-15
      • 2018-08-17
      • 1970-01-01
      • 2019-02-08
      • 1970-01-01
      • 1970-01-01
      • 2021-11-05
      • 1970-01-01
      • 2012-08-15
      相关资源
      最近更新 更多