Domanda

I'm using Spock and hate hard asserts for functional tests. I've written a SoftAssert class and everything works, I just want to make it look more like Groovy's power asserts.

Here is my existing method:

public void verifyEquals(def expected, def actual, String message = '') {
    try {
        assert expected == actual
    } catch (AssertionError e) {
        LOGGER.warn("Verification failed, expected: ${expected.toString()} but got ${actual}.\n ${message}")
        softAssertList.add(new SoftAssert(message, e))
    }
}

I'm just catching the failure, simple enough. Now what is lacking is the nice output that Groovy does so well. Instead of the statements I pass into verifyEquals such as: verifyEquals(8, (3 + x) * z)

8 == (3 + x) * z
  |     | |  | |
  |     | 0  | |
  |     3    | 2
  |          6
false

I get expected == actual

expected == actual
   |     |    |
   8     |    6
       false

This happens because the statement is calculated prior to passing it into the method. Does anyone know how to keep the test in the format of verifyEquals(8, (3 + x) * z) while passing in the parameters and how to keep the Power Assert error from the original parameters?

È stato utile?

Soluzione

The verify method should accept a Closure (code block) containing the assertion, execute it, and store any exception thrown. Usage then looks as follows: verify { assert 8 == (3 + x) * z }.

If you annotate the method with Spock's @ConditionBlock annotation and put it in a place where Spock can find it at compile time (e.g. base class), the assert keyword can even be omitted.

Note that Spock's conditions aren't the same as Groovy's power asserts. If you catch Spock's ConditionNotSatisfiedError, you'll get further information about the assertion (e.g. a full syntax tree), which you can exploit to provide better feedback. If you don't need this additional information, then catching AssertionError is fine.

Altri suggerimenti

Maybe my answer is a little bit off topic, but this question was the closest to what I was searching for here and I want to share my own findings. I found this pattern quite useful when using Spock:

try {
  assert myPage.myField.text() == "field valueXXX"
}
catch (ConditionNotSatisfiedError e) {
  // Enrich Groovy PowerAssertion with additional text
  def condition = e.condition
  throw new ConditionNotSatisfiedError(
    new Condition(
      condition.values,
      condition.text,
      condition.position,
      "Attention, the Selenium driver obviously cannot delete the session cookie " +
        "JSESSIONID_MY_PROJECT because of 'http-only'!\n" +
        "Please deploy my.project.mobile.smoke instead of my.project.mobile."
    )
  )
}

The error log looks like this:

Condition not satisfied:

myPage.myField.text() == "field value"
|         |       |      |
|         |       |      false
|         |       |      3 differences (78% similarity)
|         |       |      field value(---)
|         |       |      field value(XXX)
|         |       field valueXXX
|         myField - SimplePageContent (owner: my.project.module.geb.pages.MyPage, args: [], value: null)
my.project.module.AdminPage

Attention, the Selenium driver obviously cannot delete the session cookie JSESSIONID_MY_PROJECT because of 'http-only'!
Please deploy my.project.mobile.smoke instead of my.project.mobile.

Expected :field valueXXX
Actual   :field value

  <Click to see difference>

    at my.project.module.MySampleIT.#testName(MySampleIT.groovy:57)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top