在spock测试超时时强制在测试内执行任务

问题描述 投票:0回答:1

标题

例如,我有以下测试用例。

class StartupTest {


        def deploymentPath = "build/milestone/deployment"
        void checkConnectedProducts(){
        def productConnected = XXXhelper.countConnectedProducts()
        //Called another function in another class to check the number of connected products, every 1 sec
        while (productConnected>2){
            Thread.sleep(1000)
            productConnected = XXXhelper.countConnectedProducts()
        }
    }

    int countError(){
        def error = xxx.logFinder.search("(ERROR)",TimeFrames.from(LocalDateTime.now().minusSeconds(20)).to(LocalDateTime.now().plusSeconds(20)))
        return error.size()
    }

    @Timeout(80)
    def 'Start_test'() {

    setup:
    //do some setup here

    when: 'Test_started'
    //do something here

    and: 'Check_something'
    //check something here

    then: 'Validate_something'
    checkConnectedProducts()

    cleanup:
    //Call the function in another class to zip the file and send out message to slack
    File log = new File("$deploymentPath/logs")
    def error = countError()
    def zipFile = "xxx.zip"
    IOHelper.createZip(log,zipFile)
    File zipFile = new File(zipFile)

    //Pass the zip to another class
    ZipUploader.Slack(zipFile,error)   

   }
}

因此,如果测试在80秒内运行,清理中的函数可以成功执行,但是我也希望函数即使测试超出超时也可以执行,我不知道如何实现。

如果测试超过超时并返回超时异常,它将在中间停止整个测试,并且清理中的函数将不会执行:

testing groovy spock
1个回答
0
投票

很抱歉,将其发布为答案而不是评论,但我需要代码空间。

鉴于您提供的代码段而不是MCVE,我无法重现您的问题。我复制了这种情况的简化版本,只是用Groovy sleep或Java Thread.sleep语句代替了示例中耗时的操作:

package de.scrum_master.stackoverflow.q60601740

import spock.lang.Specification
import spock.lang.Timeout

import static java.lang.System.currentTimeMillis

class StartupTest extends Specification {
  def startTime = currentTimeMillis()

  def timeElapsed() {
    currentTimeMillis() - startTime
  }

  void checkConnectedProducts() {
    for (int i = 1; i <= 5; i++) {
      println "${timeElapsed()} | checkConnectedProducts #$i, sleeping 1 s"
      Thread.sleep(1000)
    }
  }

  int countError() {
    println "${timeElapsed()} | countError, sleeping 4 s"
    sleep 4000
    return 3
  }

  @Timeout(3)
  def 'Start_test'() {
    setup:
    true

    when: 'Test_started'
    true

    and: 'Check_something'
    true

    then: 'Validate_something'
    checkConnectedProducts()

    cleanup:
    countError()
    println "${timeElapsed()} | cleanup, sleeping 4 s"
    sleep 4000
    println "${timeElapsed()} | cleanup finished"
  }
}

控制台日志看起来像预期的一样:

64 | checkConnectedProducts #1, sleeping 1 s
1112 | checkConnectedProducts #2, sleeping 1 s
2114 | checkConnectedProducts #3, sleeping 1 s
3011 | countError, sleeping 4 s
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 0,50 seconds.
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 1,00 seconds.
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 2,00 seconds.
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 4,00 seconds.
7012 | cleanup, sleeping 4 s
[spock.lang.Timeout] Method 'Start_test' has not yet returned - interrupting. Next try in 8,00 seconds.
11012 | cleanup finished

Method timed out after 3,00 seconds

    at de.scrum_master.stackoverflow.q60601740.StartupTest.checkConnectedProducts(StartupTest.groovy:18)
    at de.scrum_master.stackoverflow.q60601740.StartupTest.Start_test(StartupTest.groovy:40)

如您所见,for循环的前3次迭代(每次花费〜1 s)在3 s超时中断从then:块中调用的方法之前执行。此后,清除块完全运行,包括被调用的方法和直接sleep,除了经过3秒外,每个花费约4 s。总而言之,我们有3 + 4 + 4 = 11秒,因此一切正常。

除非您可以按照Tim的要求提供MCVE来重现您的问题,否则我认为Spock中没有问题,而是您从日志输出中误解了某些内容,或者代码中没有显示给我们的其他问题,例如在额外的线程中执行的清理或压缩操作。

© www.soinside.com 2019 - 2024. All rights reserved.