JUnit 5 w IntelliJ IDEA i Maven (jak uruchomić, czyli powrót do blogowania)

Cześć! po dłuuuugiej przerwie.

Na początek w dwóch zdaniach się wytłumaczę. Od trzeciego kwietnia

IntellijIDEA
IntellijIDEA

zacząłem pracę przy nowym projekcie. Projekcie na tyle ciekawym (może kiedyś o tym będzie), że pochłonął mnie i mój czas zupełnie bez reszty. O blogowaniu i pisaniu konkursowego projektu nie było mowy. Oczywiście nie ma róży bez ognia, w projekcie tym jest bardzo mało algorytmiki dlatego dla podtrzymania umiejętności implementacji algorytmów podejmuję różne działania głównie związane z HackerRank i nie tylko.

Kilka dni temu musiałem oprogramować drzewo binarne. Po szybkim przeskanowaniu internetu znalazłem tylko algorytmy rekurencyjne. Nie mam zaufania do rekurencji w kodzie biznesowym, dlatego postanowiłem w celach ćwiczeniowych oprogramować bibliotekę podstawowych funkcji drzewa binarnego bez użycia rekurencji. Chcę to zrobić bez chwilowych ambicji tworzenia biblioteki użytkowej, dlatego mogłem przyjąć następujące założenia:

  1. biblioteka pseudo-funkcyjna. Pseudo bo struktura danych oddzielona od kodu a kod użytkowy w klasie zawierającej tylko metody – bezstanowe funkcje. Mając taki kod łatwo go przekształcić w czyste funkcje.
  2. dogmatyczne używanie TDD. Dogmatyczne bo nigdy w życiu nie miałem czasu, cierpliwości, warunków biznesowych itd, żeby w całym cyklu życia projektu konsekwentnie używać TDD
  3. użycie JUnit 5, bo kiedyś trzeba odpalić nową, jeszcze ciepłą wersję

I właśnie z JUnit 5 jest związany opisywany problem. Utworzyłem typowy Maven project w IntelliJ IDEA. Na wstępie dostałem pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>robert.trening</groupId>
    <artifactId>bst-metrix</artifactId>
    <version>1.0-SNAPSHOT</version>
</project>
Dodajemy klasę testów
Dodajemy klasę testów

Używając kontekstowego menu dodania testu (czyli Alt+Enter w oknie edycji na nazwie klasy, którą chcemy testować), klikając zaznaczone na screenshocie Fix dodałem do pom.xml zależności dla testów:

 

 

 

    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.0.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

Uruchamiając (Ctrl+Shift+F10) testy w środowisku IDE widzimy, że wszystko jest OK:

Natomiast uruchamiając projekt przy pomocy Mavena (w IDE lub poleceniem

mvn clean test

w konsoli) widzimy, że testy się nie uruchamiają.

$ mvn clean test
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building bst-metrix 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
...
...
...

-------------------------------------------------------
 T E S T S
-------------------------------------------------------

Results :

Tests run: 0, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.245 s
[INFO] Finished at: 2017-09-28T10:13:07+02:00
[INFO] Final Memory: 15M/132M
[INFO] ------------------------------------------------------------------------

Rozwiązanie tego problemu jest zasadniczą treścią niniejszego posta.

Dzieje się tak dlatego, że Maven nie wie jak wykonać nasze testy. Musimy go tego nauczyć dodając w ‘pomie’ sekcję <build>…</build> a w niej odpowiednie ‘pluginy’. Nie znalazłem sposobu, żeby zrobić to poprzez mechanizmy IDE musiałem więc pokodować w XMLu. Dodałem następujący fragment kodu:

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19</version>
                <dependencies>
                    <!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-surefire-provider -->
                    <dependency>
                        <groupId>org.junit.platform</groupId>
                        <artifactId>junit-platform-surefire-provider</artifactId>
                        <version>1.0.0</version>
                    </dependency>
                    <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine -->
                    <dependency>
                        <groupId>org.junit.jupiter</groupId>
                        <artifactId>junit-jupiter-engine</artifactId>
                        <version>5.0.0</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

Po tym zabiegu, testy zaczęły się wykonywać:

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running robert.trening.bstmetrix.api.BinaryTreeTraversalTest
Tests run: 13, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.2 sec - in robert.trening.bstmetrix.api.BinaryTreeTraversalTest
Running robert.trening.bstmetrix.api.BuildBstTest
Tests run: 8, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 0.002 sec <<< FAILURE! - in robert.trening.bstmetrix.api.BuildBstTest
buildBstRecursiveFunctionTree()  Time elapsed: 0 sec  <<< FAILURE!
org.opentest4j.AssertionFailedError: expected: not equal but was: <null>
        at robert.trening.bstmetrix.api.BuildBstTest.buildBstRecursiveFunctionTree(BuildBstTest.java:87)

buildBstRecursiveFunctionOne()  Time elapsed: 0 sec  <<< FAILURE!
org.opentest4j.AssertionFailedError: expected: not equal but was: <null>
        at robert.trening.bstmetrix.api.BuildBstTest.buildBstRecursiveFunctionOne(BuildBstTest.java:75)

Running robert.trening.bstmetrix.model.BinaryTreeTest
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.001 sec - in robert.trening.bstmetrix.model.BinaryTreeTest

Results :

Failed tests:
  BuildBstTest.buildBstRecursiveFunctionOne:75 expected: not equal but was: <null>
  BuildBstTest.buildBstRecursiveFunctionTree:87 expected: not equal but was: <null>

Tests run: 23, Failures: 2, Errors: 0, Skipped: 0

zwraca jednak uwagę brzydki ‘WARNING’ Mavena wykonującego swoją magię:

$ mvn clean test
...
...
...
[WARNING] Using platform encoding (Cp1250 actually) to copy filtered resources, i.e. build is platform dependent!
...
...
...

usuńmy go dodając w ‘pomie’ odpowiednią właściwość:

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

Po tym zabiegu wszystko wygląda OK a cały pom.xml wygląda następująco:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>robert.trening</groupId>
    <artifactId>bst-metrix</artifactId>
    <version>1.0-SNAPSHOT</version>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19</version>
                <dependencies>
                    <!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-surefire-provider -->
                    <dependency>
                        <groupId>org.junit.platform</groupId>
                        <artifactId>junit-platform-surefire-provider</artifactId>
                        <version>1.0.0</version>
                    </dependency>
                    <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine -->
                    <dependency>
                        <groupId>org.junit.jupiter</groupId>
                        <artifactId>junit-jupiter-engine</artifactId>
                        <version>5.0.0</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.0.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

Uwaga: numery wersji pojawiają się bezpośrednio w definicjach zależności dla przejrzystości zapisu. Dwa testy “fajlują” dla zwiększenia dramaturgii działania w TDD.

W niniejszym wpisie korzystano z materiałów:

http://junit.org/junit5/docs/current/user-guide/#running-tests-build

https://maven.apache.org/pom.html#Build_Settings

Mój kod implementacji drzewa binarnego z przydatnymi funkcjami można zobaczyć tutaj:

https://github.com/RobertPod/BinaryTree

Kod będzie rozwijany do chwili aż mi się znudzi. W razie takiej czy innej potrzeby można go używać w dowolny sposób.

to be continued … I hope

Autor: Robert

Biegnąc za marzeniami (nie tylko po górach)....

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *