title: Spock with DbUnit test cases slowness
body: <p>We have implemented <strong>Spock + Db unit</strong> framework as a part of automated unit testing.</p>
  
  <p>We have now <strong>2000 test cases (Features) for 150 Specifications with DbUnit</strong>. </p>
  
  <p>Here, We add required entries in the DB and then test the behavior of each method.</p>
  
  <p>What We have observed that it takes around 2 Hrs and 30 Mins around time to execute these test cases. </p>
  
  <p>I have timestamped <code>setup</code> fixture and added time stamp in a feature method. Below are my observations:</p>
  
  <pre class="lang-none prettyprint-override"><code>allergy.dao.AllergyFormDAOSpec &gt; Get Allergy Form STANDARD_OUT
      setup method execution started at : Fri Jan 12 19:00:42 IST 2018
  
  allergy.dao.AllergyFormDAOSpec &gt; API to get Allergy Form STANDARD_OUT
  Feature method execution started at : Fri Jan 12 19:00:44 IST 2018
  Feature method execution ended at: Fri Jan 12 19:00:45 IST 2018
  Total time taken to run the one test case: 242
  
  cleanup method execution started at : Fri Jan 12 19:00:45 IST 2018
  Total time taken to run a feature method : 2531
  </code></pre>
  
  <p>Here, I have observed that it takes average 2-4 seconds to load a feature method after setup. But, Original test case execution time is less than a second.</p>
  
  <p>I want to know if I can get pointers on what could be delay here ? As, 3 seconds for 2000 test cases means almost 1 Hr and 30 Min of time taken by Spock other than real feature execution.</p>
  
  <p>To Summarize, We want to reduce total time taken by Spock test cases when we daily run it.</p>
  
  <p><strong>Spec</strong></p>
  
  <pre class="lang-java prettyprint-override"><code>package allergy.dao
  
  import java.util.Date
  
  import org.dbunit.IDatabaseTester;
  import org.dbunit.ext.mssql.InsertIdentityOperation;
  
  import allergy.AllergyForm;
  import be.janbols.spock.extension.dbunit.DbUnit;
  import spock.lang.Shared
  import util.MasterSpec
  
  class AllergyFormDAOSpec extends MasterSpec {
      def dao = new AllergyFormDAO();
      @Shared Date timeStart1
      @Shared Date timeEnd1
  
  @DbUnit(configure={ IDatabaseTester it -&gt;
      it.setUpOperation = InsertIdentityOperation.REFRESH
      it.tearDownOperation = InsertIdentityOperation.DELETE
  })
  def content =  {
      allergy_form(formId:99999,formName:'DummySpockForm',displayIndex:1,deleteFlag:0,is_biological:1)
      allergy_form_facilities(id:99999,formId:99999,facilityid:2)
      form_concentration(id:99999,formId:99999,name:'1:100',deleteflag:0,displayindex:1)
  }
  
  def setup(){
      timeStart1 = new Date()
      println "setup method execution started at : " +  timeStart1
  }
  
  def "API to test delete Form facility"(){
      def startTime = new Date()
      println "Feature method execution started at : " +  startTime
      given:"form Id is given"
          def formId = 99999
      when:"delete form facilities"
          def result =dao.deleteFormFacilities(null, formId)
      then:"validate result"
          (result&gt;0)==true
          def endTime = new Date()
          println "Feature method execution ended at: " +  endTime
          println 'Total time taken to run the one test case: '+ (endTime.getTime() - startTime.getTime())
  }
  
  def cleanup() {
      timeEnd1 = new Date()
      println "cleanup method execution started at : " +  timeEnd1
  
      def difference = timeEnd1.time - timeStart1.time
      println "Total time taken to run a fixture method : " + difference
  }
  }
  </code></pre>
  
  <p><strong>MasterSpec</strong></p>
  
  <pre class="lang-java prettyprint-override"><code>package util
  
  import com.ecw.dao.SqlTranslator
  import catalog.Root
  import spock.lang.Shared
  import spock.lang.Specification
  
  import javax.sql.DataSource
  
  /**
  
   */
  class MasterSpec extends Specification {
  
  @Shared
  Properties properties = new Properties()
  @Shared
  public DataSource dataSource
  @Shared
  protected xmlDataSource = [:]
  
  static int timeCntr = 0;
  
  //setup is to read xml file's content in xmlDataSource Hashmap
  def setup(){
  
      //Get Running Class name without its package
      def className = this.class.name.substring(this.class.name.lastIndexOf('.') + 1)
      def resourceAnno = specificationContext.currentFeature.featureMethod.getAnnotation(FileResource)
  
      if(resourceAnno != null){
          def files = resourceAnno.xmlFiles()
          def packageName = (this.class.package.name).replaceAll('\\.','/')
  
          for(int i=0;i&lt; files.length;i++){
              def f = new File("src/test/resources/"+packageName+"/"+className+"/"+files[i])
              def engine = new groovy.text.GStringTemplateEngine()
              def template = engine.createTemplate(f).make(null)
              def xmlString = template.toString()
  
              //load the hashmap with file name as Key and its content in form of string as Value
              xmlDataSource.put(files[i].split("\\.")[0],xmlString)
          }
      }
  }
  
  def setupSpec() {
      Date timeStart = new Date()
  
      File propertiesFile = new File('src/test/webapps/myApp/conf/connection.properties').withInputStream {
          properties.load it
      }
  
      String strDBName = getPropertyValue("myApp.DBName")
      if(strDBName.indexOf('?') &gt; -1){
          strDBName = strDBName.substring(0, strDBName.indexOf('?'))
      }
      String strServerName = getPropertyValue("myApp.DBHost");
      if(strServerName.indexOf(':') &gt; -1){
          strServerName = strServerName.substring(0, strServerName.indexOf(':'))
      }
      String strUrl = getPropertyValue("myApp.DBUrl")
      String strPort = strUrl.substring(strUrl.lastIndexOf(':') + 1)
  
      //FOR MSSQL
      System.setProperty("myApp.SkipJndi", "yes")
      //dataSource = new JtdsDataSource()
      Object newObject = null;
      if(SqlTranslator.isDbSqlServer()){
          newObject = Class.forName("net.sourceforge.jtds.jdbcx.JtdsDataSource").newInstance()
      } else if(SqlTranslator.isDbMySql()){
          newObject = Class.forName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource").newInstance()
      }
  
      dataSource = (DataSource)newObject
      dataSource.setDatabaseName(strDBName)
      dataSource.setUser(getPropertyValue("myApp.DBUser"))
      dataSource.setPassword(getPropertyValue("myApp.DBPassword"))
      dataSource.setServerName(strServerName)
      dataSource.setPortNumber(Integer.parseInt(strPort))
  
  }
  }
  </code></pre>