2017-01-25 1 views
0

Existe-t-il une méthode dans Spock pour obtenir de manière transparente le nombre d'exécutions en cours lors de l'utilisation de tables de données sans qu'il soit nécessaire de l'avoir comme paramètre d'entrée explicite?Nombre de tables de données Spock en cours d'exécution

Par exemple

class MathSpec extends Specification { 
    def "maximum of two numbers"(int a, int b, int c) { 
     expect: 
     Math.max(a, b) == c 
     println "this is row:" + $currentRowCount//?? 


     where: 
     a | b | c 
     1 | 3 | 3 
     7 | 4 | 4 
     0 | 0 | 0 
    } 
} 

Répondre

3

C'est vraiment moche car iterationCount est une variable privée, mais possible:

Exemple spec:

package de.scrum_master.app 

import spock.lang.Specification 
import spock.lang.Unroll 

class PieceTest extends Specification { 
    @Unroll 
    def "do something with data table item #item"() { 
    expect: 
    println specificationContext 
     .currentIteration 
     .parent 
     .iterationNameProvider 
     .iterationCount 

    where: 
    item | anotherItem 
    "foo" | 333 
    "bar" | 444 
    "zot" | 555 
    } 
} 

journal de la console:

1 
2 
3 

S'il vous plaît noter que cela ne fonctionne que pour les méthodes @Unroll de fonction ed, non sans cette annotation.


Mise à jour: Expose nombre d'itérations via l'extension globale Spock

Disclaimer: Je l'aime mais je suis Spock ne parle pas couramment dans la programmation Groovy méta. C'est aussi ma première extension Spock.

Peut-être connaissez built-in Spock extensions qui sont la plupart du temps conduit les annotations, tels que @Ignore, @Timeout, @Stepwise, @Issue, @AutoCleanup. Mais il existe également des extensions globales qui ne sont pas décrites dans le manuel mais existent toujours, par ex. ReportLogExtension, IncludeExcludeExtension.

Malheureusement, le manuel ne décrit pas comment créer de telles extensions, mais vous pouvez le découvrir grâce à des recherches de googling et de code source. Cependant, ce n'est rien pour les débutants.

l'extension globale Spock:

Cette extension ajoute un membre dynamique iterationCount à chaque spécification Spock.

package de.scrum_master.app 

import org.spockframework.runtime.AbstractRunListener 
import org.spockframework.runtime.extension.AbstractGlobalExtension 
import org.spockframework.runtime.model.FeatureInfo 
import org.spockframework.runtime.model.IterationInfo 
import org.spockframework.runtime.model.SpecInfo 

class IterationCountExtension extends AbstractGlobalExtension { 
    @Override 
    void visitSpec(SpecInfo spec) { 
    spec.addListener(new IterationCountListener()) 
    } 

    static class IterationCountListener extends AbstractRunListener { 
    MetaClass metaClass 
    int iterationCount 

    @Override 
    void beforeSpec(SpecInfo spec) { 
     println spec.name 
     metaClass = spec.reflection.metaClass 
    } 

    @Override 
    void beforeFeature(FeatureInfo feature) { 
     println " " + feature.name 
     iterationCount = 0 
     metaClass.iterationCount = iterationCount 
    } 

    @Override 
    void beforeIteration(IterationInfo iteration) { 
     println " " + iteration.name 
     metaClass.iterationCount = iterationCount++ 
    } 
    } 
} 

Chaque extension doit être enregistrée.Donc, s'il vous plaît également ajouter un fichier META-INF/services/org.spockframework.runtime.extension.IGlobalExtension avec le contenu suivant à vos ressources de test:

de.scrum_master.app.IterationCountExtension 

spécification Showcase:

package de.scrum_master.app 

import spock.lang.Specification 
import spock.lang.Unroll 

class SampleTest extends Specification { 
    def "no data table"() { 
    expect: 
    println "  " + iterationCount 
    } 

    def "data table items"() { 
    expect: 
    println "  " + iterationCount 

    where: 
    item | anotherItem 
    "foo" | 333 
    "bar" | 444 
    "zot" | 555 
    } 

    @Unroll 
    def "unrolled data table item"() { 
    expect: 
    println "  " + iterationCount 

    where: 
    item | anotherItem 
    "foo" | 333 
    "bar" | 444 
    "zot" | 555 
    } 

    @Unroll 
    def "unrolled data table item #item"() { 
    expect: 
    println "  " + iterationCount 

    where: 
    item | anotherItem 
    "foo" | 333 
    "bar" | 444 
    "zot" | 555 
    } 
} 

journal de la console:

SampleTest 
    no data table 
    no data table 
     0 
    data table items 
    data table items 
     0 
    data table items 
     1 
    data table items 
     2 
    unrolled data table item 
    unrolled data table item[0] 
     0 
    unrolled data table item[1] 
     1 
    unrolled data table item[2] 
     2 
    unrolled data table item #item 
    unrolled data table item foo 
     0 
    unrolled data table item bar 
     1 
    unrolled data table item zot 
     2 

Comme vous pouvez Voir, l'extension fonctionne indépendamment du fait que @Unroll est utilisé ou non. À cet égard, il est également préférable que la solution & sale par le haut.

BTW, si vous souhaitez que le nombre soit basé sur 1 au lieu de 0, passez simplement l'expression iterationCount++ à ++iterationCount dans la méthode d'écouteur d'extension beforeIteration.

+0

Nice find! Je creusais à travers la source, mais je n'y suis pas parvenu ;-) Je suppose qu'une autre mise en garde est qu'elle repose sur les internes de Spock qui ne changent jamais, mais +1 pour l'effort ;-) –

+0

Je ne suis pas allé aussi loin que de lire le sources, mais a utilisé un point d'arrêt et le bon débogueur dans IntelliJ IDEA. Part de gâteau. ;-) – kriegaex

+0

Je viens d'ajouter une variante de solution utilisant une extension Spock globale à ma réponse. Vérifiez si vous aimez. Celui-ci était beaucoup plus amusant à apprendre et à mettre en œuvre que ma solution rapide et sale. :)) – kriegaex

1

Vous pouvez utiliser @Unroll avec #iterationCount, à savoir:

import spock.lang.* 

class MathSpec extends Specification { 

    @Unroll 
    def "maximum of #a and #b is #c (iteration #iterationCount)"() { 
     given: 
     def result = Math.max(a, b) 

     expect: 
     result == c 

     where: 
     a | b | c 
     1 | 3 | 3 
     7 | 4 | 4 
     0 | 0 | 0 
    } 
} 

PS: Ne pas appeler votre classe Math, essayez d'appeler Math.max ;-)

+0

Ok, mais l'utilisation de 'iterationCount' dans le corps de la spécification n'est pas possible? – Opal

+0

@tim_yates - merci, mais je ne peux pas accéder à l'iterationCount dans le corps de la méthode qui est ce dont j'ai besoin – Ian