Dynamic creation of parameterized class - is it possible

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Dynamic creation of parameterized class - is it possible

grzesuav
Hi all

I recently encounter problem which I don't know how resolve in a Spock-way :

I wan't to have parameterized tests, but I would like to have several different test methods executed for one set of parameters. It is crucial for me, because I writing test for gradle plugin using nebula-test, where its perform gradle build on given buildfile. After execution of gradle, I want to assert some expectations. 


Using spock parameterized methods, I could do it with a "then" block with lot of asserts, which is not what I want. For me better solution would be a JUnit4 parameterized class, but I don't know how in best way merge this approach.


Can anyone advise something ?


Thanks in advance,


Grzesiek

--
You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at http://groups.google.com/group/spockframework.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Dynamic creation of parameterized class - is it possible

Leonard Brünings
Hi,

do you only have one set of parameters, or do you have multiple sets parameters as well?

You could define your parameters as a shared list of maps

https://meetspock.appspot.com/script/5669283816275968

import spock.lang.*

class MultiParamSpec extends Specification {
  @Shared
  def parameterSet = [
    [a: 1, b: 2],
    [a: 3, b: 4],
    [a: 5, b: 2]
  ]

  @Unroll
  def "test 1"() {
    expect:
    Math.max(params.a, params.b) == params.c

    where:
    params << parameterSet
  }

  @Unroll("Testing Min(#params.a, #params.b) == #params.c")
  def "test 2"() {
    expect:
    Math.min(params.a, params.b) == params.c

    where:
    params << parameterSet
  }
}


On Friday, May 8, 2015 at 8:56:28 AM UTC+2, [hidden email] wrote:
Hi all

I recently encounter problem which I don't know how resolve in a Spock-way :

I wan't to have parameterized tests, but I would like to have several different test methods executed for one set of parameters. It is crucial for me, because I writing test for gradle plugin using nebula-test, where its perform gradle build on given buildfile. After execution of gradle, I want to assert some expectations. 


Using spock parameterized methods, I could do it with a "then" block with lot of asserts, which is not what I want. For me better solution would be a JUnit4 parameterized class, but I don't know how in best way merge this approach.


Can anyone advise something ?


Thanks in advance,


Grzesiek

--
You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at http://groups.google.com/group/spockframework.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Dynamic creation of parameterized class - is it possible

grzesuav


W dniu piątek, 8 maja 2015 21:28:45 UTC+2 użytkownik Leonard Brünings napisał:
Hi,

do you only have one set of parameters, or do you have multiple sets parameters as well?

You could define your parameters as a shared list of maps

<a href="https://meetspock.appspot.com/script/5669283816275968" target="_blank" rel="nofollow" onmousedown="this.href='https://meetspock.appspot.com/script/5669283816275968';return true;" onclick="this.href='https://meetspock.appspot.com/script/5669283816275968';return true;">https://meetspock.appspot.com/script/5669283816275968

import spock.lang.*

class MultiParamSpec extends Specification {
  @Shared
  def parameterSet = [
    [a: 1, b: 2],
    [a: 3, b: 4],
    [a: 5, b: 2]
  ]

  @Unroll
  def "test 1"() {
    expect:
    Math.max(params.a, params.b) == params.c

    where:
    params << parameterSet
  }

  @Unroll("Testing Min(#params.a, #params.b) == #params.c")
  def "test 2"() {
    expect:
    Math.min(params.a, params.b) == params.c

    where:
    params << parameterSet
  }
}



Hi Leonard,

I have one set of parameters, but when I do as you propose, (AFAIK) each method will be executed for parameters set, which I want to avoid.


In my case, each execution is a execution of external gradle build on buildfile (my set of parameters are different build.gradle files) which I want to avoid if possible. I just wan't to execute set of test method after specific setup occurs, just like in Junit 4 parameterized classes


Regards,

Grzesiek

--
You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at http://groups.google.com/group/spockframework.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Dynamic creation of parameterized class - is it possible

grzesuav
I found a topic where parmeterized specification was discussed :https://groups.google.com/forum/#!searchin/spockframework/setup$20parameterized/spockframework/lSkZYZlGfYc/E52h49SdkAwJ
but it seems that there is no such solution instead creating class hierarchies etc.

Only way is to implement a parameterized test runner which wraps around Sputnik runner, I will try to do it but I don't know how Sputnik initializes Specifications, so I can stuck at this.




 

--
You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at http://groups.google.com/group/spockframework.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Dynamic creation of parameterized class - is it possible

Leonard Brünings
Grzesiek, if you have only one set of parameters then I don't really understand your problem.
Maybe you could give us a little diagram on what you need.

You can also use Spock to evaluate a String into a Specification see https://github.com/spockframework/spock/blob/master/spock-spring/src/test/groovy/org/spockframework/spring/InjectionExamples.groovy
Then you could put your actual code in the embedded Specification and use DataDriven testing for the surrounding test.
It has its uses but should also be used with caution since String content is usually not really covered by refactorings...
and you would have to take care of the reporting too afaik.

cheers
Leonard

On Monday, May 11, 2015 at 4:10:25 PM UTC+2, [hidden email] wrote:
I found a topic where parmeterized specification was discussed :<a href="https://groups.google.com/forum/#!searchin/spockframework/setup$20parameterized/spockframework/lSkZYZlGfYc/E52h49SdkAwJ" target="_blank" rel="nofollow" onmousedown="this.href='https://groups.google.com/forum/#!searchin/spockframework/setup$20parameterized/spockframework/lSkZYZlGfYc/E52h49SdkAwJ';return true;" onclick="this.href='https://groups.google.com/forum/#!searchin/spockframework/setup$20parameterized/spockframework/lSkZYZlGfYc/E52h49SdkAwJ';return true;">https://groups.google.com/forum/#!searchin/spockframework/setup$20parameterized/spockframework/lSkZYZlGfYc/E52h49SdkAwJ
but it seems that there is no such solution instead creating class hierarchies etc.

Only way is to implement a parameterized test runner which wraps around Sputnik runner, I will try to do it but I don't know how Sputnik initializes Specifications, so I can stuck at this.




 

--
You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at http://groups.google.com/group/spockframework.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Dynamic creation of parameterized class - is it possible

grzesuav


W dniu poniedziałek, 11 maja 2015 22:43:57 UTC+2 użytkownik Leonard Brünings napisał:
Grzesiek, if you have only one set of parameters then I don't really understand your problem.
Maybe you could give us a little diagram on what you need.


Hi,
I don't elaborate clearly, by writing "I have one set of parameters" I meant that by set of parameters is shared for all test methods.


So it is exactly as in this example :
class MultiParamSpec extends Specification {
  @Shared
  def parameterSet [
    [a1b2],
    [a3b4],
    [a5b2]
  ]

  @Unroll
  def "test 1"({
    setup: 
        setupFor(params)
    expect:
    Math.max(params.aparams.b== params.c

    where:
    params << parameterSet 
  }

  @Unroll("Testing Min(#params.a, #params.b) == #params.c")
  def "test 2"({
    setup:
       setupFor(params)
    expect:
    Math.min(params.aparams.b== params.c

    where:
    params << parameterSet 
  }
}
 
so for each set of parameters I must do some setup, which is costly and bases only on given parameters, so I would only execute it once for all test method. AFAIK in this example, each method will execute setup for all parameters, which is not what I want.
I would have to :
1) Get a parameter from set
2) Do setup for given parameter
3) Execute all test method for this setup


So what I want is a behavior similar to JUnit parameterized test classes, where you have test class instance for given parameters, and I can done beforeClass() setup for given parameters, before each method will be executed.


You can also use Spock to evaluate a String into a Specification see <a href="https://github.com/spockframework/spock/blob/master/spock-spring/src/test/groovy/org/spockframework/spring/InjectionExamples.groovy" target="_blank" rel="nofollow" onmousedown="this.href='https://www.google.com/url?q\75https%3A%2F%2Fgithub.com%2Fspockframework%2Fspock%2Fblob%2Fmaster%2Fspock-spring%2Fsrc%2Ftest%2Fgroovy%2Forg%2Fspockframework%2Fspring%2FInjectionExamples.groovy\46sa\75D\46sntz\0751\46usg\75AFQjCNFRSOVtzjJEdJhLMEmGIRecnT88Mw';return true;" onclick="this.href='https://www.google.com/url?q\75https%3A%2F%2Fgithub.com%2Fspockframework%2Fspock%2Fblob%2Fmaster%2Fspock-spring%2Fsrc%2Ftest%2Fgroovy%2Forg%2Fspockframework%2Fspring%2FInjectionExamples.groovy\46sa\75D\46sntz\0751\46usg\75AFQjCNFRSOVtzjJEdJhLMEmGIRecnT88Mw';return true;">https://github.com/spockframework/spock/blob/master/spock-spring/src/test/groovy/org/spockframework/spring/InjectionExamples.groovy
Then you could put your actual code in the embedded Specification and use DataDriven testing for the surrounding test.
It has its uses but should also be used with caution since String content is usually not really covered by refactorings...
and you would have to take care of the reporting too afaik.


Thanks,
I will look into it
 
cheers
Leonard



Cheers,

Grzesiek 

--
You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at http://groups.google.com/group/spockframework.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Dynamic creation of parameterized class - is it possible

grzesuav
In reply to this post by Leonard Brünings


W dniu poniedziałek, 11 maja 2015 22:43:57 UTC+2 użytkownik Leonard Brünings napisał:

You can also use Spock to evaluate a String into a Specification see <a href="https://github.com/spockframework/spock/blob/master/spock-spring/src/test/groovy/org/spockframework/spring/InjectionExamples.groovy" target="_blank" rel="nofollow" onmousedown="this.href='https://www.google.com/url?q\75https%3A%2F%2Fgithub.com%2Fspockframework%2Fspock%2Fblob%2Fmaster%2Fspock-spring%2Fsrc%2Ftest%2Fgroovy%2Forg%2Fspockframework%2Fspring%2FInjectionExamples.groovy\46sa\75D\46sntz\0751\46usg\75AFQjCNFRSOVtzjJEdJhLMEmGIRecnT88Mw';return true;" onclick="this.href='https://www.google.com/url?q\75https%3A%2F%2Fgithub.com%2Fspockframework%2Fspock%2Fblob%2Fmaster%2Fspock-spring%2Fsrc%2Ftest%2Fgroovy%2Forg%2Fspockframework%2Fspring%2FInjectionExamples.groovy\46sa\75D\46sntz\0751\46usg\75AFQjCNFRSOVtzjJEdJhLMEmGIRecnT88Mw';return true;">https://github.com/spockframework/spock/blob/master/spock-spring/src/test/groovy/org/spockframework/spring/InjectionExamples.groovy
Then you could put your actual code in the embedded Specification and use DataDriven testing for the surrounding test.
It has its uses but should also be used with caution since String content is usually not really covered by refactorings...
and you would have to take care of the reporting too afaik.

cheers
Leonard


I looked into this example, it could work but I'm not convinced if it worth effort.

I come across this : https://stackoverflow.com/questions/27745691/how-to-combine-runwith-with-runwithparameterized-class
which shows that resolution would be to create a parameterized runner for Sputnik. 

I try to do it, but it looks that gradle have problem with compiling my example :

@CompileStatic
@RunWith(Parameterized.class)
@Parameterized.UseParametersRunnerFactory(SputnikWithParameters.class)
class SputnikWithParametersTest extends Specification {

    private final int _b
    private final int _a

    SputnikWithParametersTest(int a, int b) {
        _a = a
        _b = b
    }

    def setupSpec() {

    }

    def 'some'() {
        when:
            int abs = Math.abs(_a)
        then:
            abs == _b
    }

    @Parameterized.Parameters
    static Collection<int[]> parameters() {
        return Arrays.asList(
                [1, 1] as int[],
                [-2, 2] as int[]
        )
    }
}
 

Error :
:compileTestGroovy
startup failed:
/media/data/dev/workspaces/intleij/trunk/plugins/spock-parameterized-class/src/test/groovy/com/parasoft/spock/extensions/parameterized/clazz/SputnikWithParametersTest.groovy: 19: Constructors are not allowed; instead, define a 'setup()' or 'setupSpec()' method @ line 19, column 5.
       SputnikWithParametersTest(int a, int b) {
       ^


I would expect that it will be a runtime issue when Sputnik will try to run this class, but it seems that groovy compiler understands Spock language requirements. Is it somewhere explained like this mechanism look like ? Is spock extending some compiler feature, or is is done by some other groovy lang feature ? 
I came across this document http://docs.groovy-lang.org/docs/latest/html/documentation/core-domain-specific-languages.html#compilation-customizers but it looks that it could be over my possibilities to write parameterized runner for Sputnik, spock probably defines some requirements on Specs classes, which in Parameterized runner should be changed to allow constructors with arguments. Could somebody involved in spock guts point me where I can change this behavior (if its even possible) ?  


I'm new to groovy, spock and DSL, so apologize if my questions are obvious.

Thanks in advance,


Grzesiek

--
You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at http://groups.google.com/group/spockframework.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Dynamic creation of parameterized class - is it possible

Leonard Brünings
In reply to this post by grzesuav
Hi Grzesiek,

here is a poor mans parameterized spec: http://meetspock.appspot.com/script/5711312218750976

The idea is to have all test in the abstract base class, which defines a method to get the current parameters.
To add a set of parameters you just need to create a new class and implement the method. It is not really pretty,
but it works with the current spock features.

cheers
Leonard

On Tuesday, May 12, 2015 at 9:58:27 AM UTC+2, [hidden email] wrote:


W dniu poniedziałek, 11 maja 2015 22:43:57 UTC+2 użytkownik Leonard Brünings napisał:
Grzesiek, if you have only one set of parameters then I don't really understand your problem.
Maybe you could give us a little diagram on what you need.


Hi,
I don't elaborate clearly, by writing "I have one set of parameters" I meant that by set of parameters is shared for all test methods.


So it is exactly as in this example :
class MultiParamSpec extends Specification {
  @Shared
  def parameterSet [
    [a1b2],
    [a3b4],
    [a5b2]
  ]

  @Unroll
  def "test 1"({
    setup: 
        setupFor(params)
    expect:
    Math.max(params.aparams.b) == params.c

    where:
    params << parameterSet 
  }

  @Unroll("Testing Min(#params.a, #params.b) == #params.c")
  def "test 2"({
    setup:
       setupFor(params)
    expect:
    Math.min(params.aparams.b) == params.c

    where:
    params << parameterSet 
  }
}
 
so for each set of parameters I must do some setup, which is costly and bases only on given parameters, so I would only execute it once for all test method. AFAIK in this example, each method will execute setup for all parameters, which is not what I want.
I would have to :
1) Get a parameter from set
2) Do setup for given parameter
3) Execute all test method for this setup


So what I want is a behavior similar to JUnit parameterized test classes, where you have test class instance for given parameters, and I can done beforeClass() setup for given parameters, before each method will be executed.


You can also use Spock to evaluate a String into a Specification see <a href="https://github.com/spockframework/spock/blob/master/spock-spring/src/test/groovy/org/spockframework/spring/InjectionExamples.groovy" rel="nofollow" target="_blank" onmousedown="this.href='https://www.google.com/url?q\75https%3A%2F%2Fgithub.com%2Fspockframework%2Fspock%2Fblob%2Fmaster%2Fspock-spring%2Fsrc%2Ftest%2Fgroovy%2Forg%2Fspockframework%2Fspring%2FInjectionExamples.groovy\46sa\75D\46sntz\0751\46usg\75AFQjCNFRSOVtzjJEdJhLMEmGIRecnT88Mw';return true;" onclick="this.href='https://www.google.com/url?q\75https%3A%2F%2Fgithub.com%2Fspockframework%2Fspock%2Fblob%2Fmaster%2Fspock-spring%2Fsrc%2Ftest%2Fgroovy%2Forg%2Fspockframework%2Fspring%2FInjectionExamples.groovy\46sa\75D\46sntz\0751\46usg\75AFQjCNFRSOVtzjJEdJhLMEmGIRecnT88Mw';return true;">https://github.com/spockframework/spock/blob/master/spock-spring/src/test/groovy/org/spockframework/spring/InjectionExamples.groovy
Then you could put your actual code in the embedded Specification and use DataDriven testing for the surrounding test.
It has its uses but should also be used with caution since String content is usually not really covered by refactorings...
and you would have to take care of the reporting too afaik.


Thanks,
I will look into it
 
cheers
Leonard



Cheers,

Grzesiek 

--
You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at http://groups.google.com/group/spockframework.
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Dynamic creation of parameterized class - is it possible

grzesuav
W dniu czwartek, 11 czerwca 2015 22:24:56 UTC+2 użytkownik Leonard Brünings napisał:
Hi Grzesiek,

here is a poor mans parameterized spec: <a href="http://meetspock.appspot.com/script/5711312218750976" target="_blank" rel="nofollow" onmousedown="this.href='http://meetspock.appspot.com/script/5711312218750976';return true;" onclick="this.href='http://meetspock.appspot.com/script/5711312218750976';return true;">http://meetspock.appspot.com/script/5711312218750976

The idea is to have all test in the abstract base class, which defines a method to get the current parameters.
To add a set of parameters you just need to create a new class and implement the method. It is not really pretty,
but it works with the current spock features.

cheers
Leonard


Hi Leonard!

Thanks for example, but I decided to leave it as is. I could not find any satisfactory resolution. Multiple classes also are not very convenient solution.  

Closed resolution I mad was using @ClassRule, but it seems that it not works well with spock (I plan to post my problem with class rules later).



Regards,

Grzesiek


--
You received this message because you are subscribed to the Google Groups "Spock Framework - User" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
To post to this group, send email to [hidden email].
Visit this group at http://groups.google.com/group/spockframework.
For more options, visit https://groups.google.com/d/optout.
Loading...