在实时测试网站上进行集成测试,在测试套件完成后恢复数据

时间:2015-04-30 06:58:33

标签: mysql ruby-on-rails postgresql selenium integration-testing

我想使用实时网站selenium编写的集成/自动化测试用例说test.example.com。该网站正在举办example.com的网站。

当我运行测试用例时,会创建,更新和删除新数据。完成测试套件后,我想将数据库恢复到运行测试用例之前的状态。

因此,例如在运行测试用例之前的数据库状态 - > S1 和运行测试用例后的数据库状态 - > S2

我希望数据库回到s1状态。

我正在使用rails框架和mysql / pg数据库

一个解决方案可能是在运行测试用例之前转储数据库,然后在测试用例运行完成后恢复数据。

什么是其他解决方案?

由于

1 个答案:

答案 0 :(得分:0)

我确实完成了那个解决方案,直到数据库变得很大并且程序很长时间。

所以我把它改成了一种回滚。

作为设置中的一部分 所有测试用例调用的主类

  def run_once_beginning
    DEBUG("start","Running start function")
    DefaultDatabase.prepare_rollback
    DefaultDatabase.resetDB
  end

  def run_once_end
    DEBUG("start","Running end function")
    DefaultDatabase.drop_all_triggers
    DefaultDatabase.resetDB
  end

  def setup    
    if(State.instance.started == false)
      State.instance.started = true
      run_once_beginning
      at_exit do
        run_once_end
      end
    end
  end

DefaultDatabase.rb

def prepare_rollback

   query = "CREATE TABLE IF NOT EXISTS `changes` (`table_name` varchar(60) NOT NULL, PRIMARY KEY (`table_name`))"
HandleDB.sendQuery(query)

   query = "show tables;"
   tables = HandleDB.sendQuery(query)
   exclude = ["phpsessions", "cameras", "changes", "connections", "sysevents"]
   triggers = "";
   tables.each{ |name|
     if (exclude.index(name) == nil)
       triggers += "DROP TRIGGER IF EXISTS ins_#{name};"
       triggers += "CREATE TRIGGER ins_#{name} AFTER INSERT ON #{name}
                 FOR EACH ROW BEGIN
                 INSERT IGNORE INTO `changes` VALUES ('#{name}');
                 END;"
       triggers += "DROP TRIGGER IF EXISTS up_#{name};"
       triggers += "CREATE TRIGGER up_#{name} AFTER UPDATE ON #{name}
                 FOR EACH ROW BEGIN
                 INSERT IGNORE INTO `changes` VALUES ('#{name}');
                 END;"
       triggers += "DROP TRIGGER IF EXISTS del_#{name};"
       triggers += "CREATE TRIGGER del_#{name} AFTER DELETE ON #{name}
                 FOR EACH ROW BEGIN
                 INSERT IGNORE INTO `changes` VALUES ('#{name}');
                 END;"
     end
   }

   setup_connecion = Mysql.new(Constants::DB["ServerAddress"],"root", Constants::DB["Password"],
  Constants::DB["Database"],Constants::DB["ServerPort"], nil, Mysql::CLIENT_MULTI_STATEMENTS)

   setup_connecion.query(triggers)

# Clear out all the results.
   while setup_connecion.more_results
     setup_connecion.next_result
   end
   query = "DROP PROCEDURE IF EXISTS RestoreProc;"
   setup_connecion.query(query)

# This is a mysql stored procedure. It will use a cursor for extracting names of
# changed tables from the changed-table and then truncate these tables and
# repopulate them with data from the default db.
   query = "CREATE PROCEDURE RestoreProc()
     BEGIN
       DECLARE changed_name VARCHAR(60);
       DECLARE no_more_changes INT DEFAULT 0;
       DECLARE tables_cursor CURSOR FOR SELECT table_name FROM changes;
       DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_more_changes = 1;

       OPEN tables_cursor;
       FETCH tables_cursor INTO changed_name;

       IF changed_name IS NOT NULL THEN
         REPEAT
           SET @sql_text=CONCAT('TRUNCATE ', changed_name);
           PREPARE stmt FROM @sql_text;
           EXECUTE stmt;
           DEALLOCATE PREPARE stmt;

           SET @sql_text=CONCAT('INSERT INTO ', changed_name, ' SELECT * FROM default_db.', changed_name);
           PREPARE stmt FROM @sql_text;
           EXECUTE stmt;
           DEALLOCATE PREPARE stmt;

           FETCH tables_cursor INTO changed_name;
         UNTIL no_more_changes = 1
         END REPEAT;
       END IF;

       CLOSE tables_cursor;
       TRUNCATE changes;
   END ;"

   setup_connecion.query(query)
   setup_connecion.close
end

def drop_all_triggers
    query = "show tables;"
    tables = HandleDB.sendQuery(query)
    triggers = ""
    tables.each{ |name|
      triggers += "DROP TRIGGER IF EXISTS del_#{name};"
      triggers += "DROP TRIGGER IF EXISTS up_#{name};"
      triggers += "DROP TRIGGER IF EXISTS ins_#{name};"
    }

    triggers_connection = Mysql.new(Constants::DB["ServerAddress"],"root", Constants::DB["Password"],
                     Constants::DB["Database"],Constants::DB["ServerPort"], nil, Mysql::CLIENT_MULTI_STATEMENTS)

    triggers_connection.query(triggers)
    triggers_connection.close
  end

def resetDB
    restore_connection = Mysql.new(Constants::DB["ServerAddress"],Constants::DB["User"], Constants::DB["Password"],
      Constants::DB["Database"], Constants::DB["ServerPort"], nil, Mysql::CLIENT_MULTI_RESULTS)
    restore_connection.query("CALL RestoreProc();")
    restore_connection.close
  end

要使其工作,需要原始数据库的副本,使其返回名为“default_db”的状态。

“排除”是不会更改的表格