Skip to content

Instantly share code, notes, and snippets.

@Arnauld
Created February 4, 2016 22:31
Show Gist options
  • Save Arnauld/97a87e547ab52c5b8244 to your computer and use it in GitHub Desktop.
Save Arnauld/97a87e547ab52c5b8244 to your computer and use it in GitHub Desktop.

1er paragraph

ie => i.e.

Simple comme TDD.

Pas de point à la fin

Et en plus ces tests étaient détectés automatiquement par la chaîne de build Jenkins, exécutés tout le temps lors de mon développement…

détectés automatiquement par l'usine logicielle et la chaine d'intégration continue...

    @Test
    public void doSomething(){
        MyService service = new Myservice();
        boolean noProblem = service.doSomething();
        if (!noProblem) {
            throw new RuntimeException("Houston, we have a problem !")
        }
    }

Un assert serait quand même le bienvenu :)

Le Concombre et le Cornichon

Cette langue, ce sera l’anglais en suivant la syntaxe du Gherkin et le framework que vous allez ajouter à JUnit, ce sera Cucumber.

En fait, tu peux prendre n'importe quelle langue supportée. Il suffit de préciser en en-tête du fichier feature. Gherkin - Spoken languages

Gherkin est le langage (Given/When/Then); fait bizarre la syntaxe "du" Gherkin, peut être la "syntaxe Gherkin" tout court?

# language: fr
Fonctionnalité:

  Scénario: Le métro 1 dans le réseau de transport simplifié

    Etant donné le réseau de transport simplifié "Parisien"
    Alors le métro 1 devrait passer dans chaque station toutes les 5mins à partir de 6h00

  Scénario: Rer A dans le réseau de transport simplifié

    Etant donné le réseau de transport simplifié "Parisien"
    Alors le rer A devrait passer toutes les 10mins à "la Défense" à partir de 5h37
    Alors les temps de transport cumulés depuis "la Défense" devraient être:
      | Charles de Gaulle Etoile | 5min  |
      | Auber                    | 7min  |
      | Chatelet les Halles      | 10min |

et le framework que vous allez ajouter à JUnit, ce sera Cucumber.

JUnit est utilisé comme lanceur, pour déclenché l'execution du cucumber.

Ensuite parce que j’aime bien avoir dans le meme dossiers les fichiers Gherkin et les fichiers Java s’y rapportant, il faut l’indiquer à Maven.

Argggghhhlhlhhhh

Le runner cucumber supporte des options qui se passent par annotations, l’une d’elle « strict », permet d’avoir un test en failure si des steps restent à implémenter.

Il est possible de configurer l'execution de cucumber en ajoutant l'annotation @CucumberOptions. Elle a plusieurs propriétés, l'une d'elle "strict" permet d'avoir...

@RunWith(Cucumber.class)
@CucumberOptions(strict=true)
public class MyServiceTest {
} 

Les autres options permettent d'indiquer l'emplacement des fichiers features ou des classes Java contenant nos annotations @Given, @When, @Then... si ceux-ci ne sont pas dans le même package ou un sous-package du lanceur.

La syntaxe du Gherkin.

Pas de point à la fin

Dans le Java notre test est éclaté dans différentes méthodes au niveau de ma classe Java.

gnnnnn?

par vos collaborateur fonctionnels.

collaborateurS

C’est un peu l’annotation « @Before » de JUnit.

Il y a aussi un @Before et un @After en cucumber. On les appelle les Hooks. On peut en avoir autant que l'on veut et on peux même rendre leur invocation conditionée par la présence (ou la non-présence de tags)

@Before("@authenticated_user")
public void defineCurrentUserAsAuthenticated() {
	world.setCurrentUser(personaFactory.newAuthenticatedUser());
}

Des groupes de scénarii :

on parle aussi de template de scenarii.

Dans les étapes les valeurs entre « »

c'est des chevrons simples. Peut être que fournir un exemple serait pas mal:

  @limitOrder @timeInForce
  Scenario Outline: Time in Force - Accepted parameter

    When one try to place a default limit order with the following specifics:
      | way  | time in force   |
      | sell | <time-in-force> |
    Then the order book should be updated with this new order

  Examples:
    | time-in-force |
    | fok           |
    | iok           |
    | gtd           |
    | gtc           |

Des étapes ...

Pareil un exemple avec un peut tout serait pas mal.

A noter que les mots clés « And » et « But » reprennent simplement le mot clé précédant.

Ils permettent surtout d'alléger un peu la lecture du scénario. le But permet aussi de mettre l'emphase sur ue phrase bien particulière.

Des paramètres dans les étapes

Un/des exemples?

Il est également possible d’avoir des paramètres de type listes et map ainsi que des chaines sur plusieurs lignes.

Un exemple :)

  Scenario: Default Order

    Given an empty order book
    And the following orders have been placed:
      | way  | qty | price |
      | Buy  | 150 | 8.4   |
      | Buy  | 15  | 9.9   |
      | Sell |     | 12.4  |
      | Sell |     |       |

    Then the order book should be composed of the following orders:
      | order type  | way  | qty | price |
      | Limit Order | Buy  | 150 | 8.4   |
      | Limit Order | Buy  | 15  | 9.9   |
      | Limit Order | Sell | 100 | 12.4  |
      | Limit Order | Sell | 100 | 10.1  |
    @Given("^the following orders have been placed(?: in order)?:$")
    public void placeOrders(List<OrderProto> rows) throws Throwable {
        rows.forEach(r -> r.placeOrder(world.getOrderBook(), world));
    }
public class OrderProto {

    public String broker;
    public String instrument;
    public String orderType;
    public String way;
    public Integer qty;
    public BigDecimal price;
    public String timeInForce;

    public void placeOrder(OrderBook book, World world) {
        Order order = toOrder(world);
        book.placeOrder(order);
    }

    public Order toOrder(World world) {
    	TimeInForce tif = world.parseTimeInForceOrDefault(timeInForce, TimeInForce.GTD);
    	int quantity = qty!=null ? qty : 10;
    	...
    }
}

Le World

Pour utiliser un « World », il faut intégrer le pico container a votre projet :

Euh pas forcément, y a Spring aussi :)

Pour utiliser un « World », Le plus simple est d'utiliser une librarie d'injection de dépendance comme 'pico container'. Il a l'interêt d'être extrémement simple et beaucoup plus rapide que Spring. L'injection des dépendances se fait par constructeur.

Les Tags

Le Gherkin permet enfin d’identifier des scénarii par des tags.

On "identifie" pas.

Il est possible de mettre autant de tags que l'on souhaite (et même plusieurs par lignes). Les tags permettent d'ajouter des informations supplémentaires aux scénarios. Il s'agit de méta informations ajoutées aux scénarii. Ces informations peuvent être utilisées pour

  • marquer le domaine fonctionel que le scénario couvre, il s'agit alors d'informations purement déclaratives qui peuvent aider à construire une converture fonctionnelle de notre application
  • filtrer l'execution de certain scénario, par exemple ne lancer que les scénarios concernant la fonctionalité "@payment", ou au contraire ne pas lancer les scénarii qui sont en court de développement et qui sont taggés "@wip"
  • déclencher des Hooks spécifiques
@RunWith(Cucumber.class)
@CucumberOptions(strict=true,
                 tags = {"~@wip", "@payment"})
public class MyServiceTest {
} 

Il manque un petit mot de fin ou une conclusion :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment