Search code examples
specs2

specs2- Take action on test failure


Is there a way to take a certain action if my test fails? I have a test that uses selenium/fluentlinium to fill texts/click buttons and assert results. I'd like to be able to take an action whenever a test condition fails. Something like the following

class TestSpecial extends Specification{
  "Website should" {
    "do the right thing" in new WithBrowser( webDriver = WebDriverFactory( FIREFOX ) ){
      browser.$( ".xyz1" ).text( "a" )
      browser.$( ".xyz2" ).click() 
      browser.$( ".xyz3" ).getText must equalTo( "foo" )

      browser.$( ".xyz1" ).text( "b" )
      browser.$( ".xyz2" ).click() 
      browser.$( ".xyz3" ).getText must equalTo( "bar" )
    }
    onFailure
    {
      //context remains same, so I can use browser
      MySnapshotFunction.takeSnapshot( browser )
    }
  }
}

Is there a way to make the test throw on failure so that I can take snapshot in the catch block?

I think one way is to use the suggestion given in:

How to do setup/teardown in specs2 when using "in new WithApplication"

Create my own 'WithBrowser' custom implementation that marks each test as failure before starting and requires the user of that implementation to mark the test as passed at the end of test block. The custom implementation in the teardown code takes a snapshot. I have set sight on using this approach, but would welcome any better/simpler solutions to this.


Solution

  • You should be able to use the Around trait:

    import org.specs2.mutable._
    import org.specs2.execute._
    
    trait TakeSnapshot extends org.specs2.mutable.Around {
      def browser: Browser
    
      abstract override def around[R : AsResult](r: =>R) = super.around {
        val result = AsResult(r)
        if (!result.isSuccess) {
          takeSnapshot(browser)
        }
        result
      }
    
      def takeSnapshot(browser: Browser) =
        println("take snapshot")
      }
    }
    
    // then 
    "do the right thing" in 
       new WithBrowser(webDriver=WebDriverFactory(FIREFOX)) with TakeSnapshot {
      browser.$( ".xyz1" ).text( "a" )
      browser.$( ".xyz2" ).click() 
      browser.$( ".xyz3" ).getText must equalTo( "foo" )
    
      browser.$( ".xyz1" ).text( "b" )
      browser.$( ".xyz2" ).click() 
      browser.$( ".xyz3" ).getText must equalTo( "bar" )  
    }
    

    When I execute it on a failing example I get a trace like

    execute t      // comes from a println in WithBrowser
    take snapshot
    quit browser   // comes from a println in Browser