JUnit 5 – Testy powtarzalne

Jedną z cech testów jednostkowych jest ich powtarzalność. Najlepiej, jeżeli powtórzenie jest wykonywane automatycznie. Jednak nie o tym dziś będziemy mówić. Czasami pisząc testy, musimy uwzględnić, że nasz kod uruchamiany jest w środowisku wielowątkowym. Nie ma w tym nic nadzwyczajnego. Podobnie jest w przypadku, gdy tworzymy testy, których zadaniem jest jakiegoś kodu w wielu kopiach jednocześnie. Dla mnie wzorcową implementacją tego zachowania jest TestNG:

Listing 1. Testy powtarzalne w TestNG

@Test
public class FizzBuzzTestNGRepeatedTest {

	private FizzBuzz sut;

	@BeforeTest
	public void setup() {
		sut = new FizzBuzz();
	}

	@Test(invocationCount = 100, threadPoolSize = 4)
	public void shouldReturnFizzBuzzIfDiv3And5() throws Exception {
		assertEquals("FizzBuzz", sut.fizzBuzz(15));
	}

	@Test(invocationCount = 100, threadPoolSize = 4)
	public void shouldReturnBuzzIfDiv5() throws Exception {
		assertEquals("Buzz", sut.fizzBuzz(5));
	}

	@Test(invocationCount = 100, threadPoolSize = 4)
	public void shouldReturnFizzIfDiv3() throws Exception {
		assertEquals("Fizz", sut.fizzBuzz(3));
	}

	@Test(invocationCount = 100, threadPoolSize = 4)
	public void shouldReturnVal() throws Exception {
		assertEquals("2", sut.fizzBuzz(2));
	}

}

Mamy tu dość dużą elastyczność w konfiguracji testów. Po pierwsze za pomocą parametru invocationCount, możemy określić, ile testów ma zostać wykonanych. Po drugie parametr threadPoolSize pozwala nam na skonfigurowanie liczby wątków użytych do uruchomienia testów.

W przypadku JUnit 5 wygląda to trochę inaczej. Po pierwsze wprowadzono adnotację @RepeatedTest, która pozwala na określenie liczby powtórzeń. Adnotacja ta zachowuje się jak specjalizowana @Test.

Listing 2. Testy powtarzalne w JUnit 5

public class FizzBuzzJUnit5RepeatedTest {

	private FizzBuzz sut;

	@BeforeEach
	public void setup() {
		sut = new FizzBuzz();
	}

	@RepeatedTest(value = 100, name = "Repetition {currentRepetition} of {totalRepetition}")
	public void shouldReturnFizzBuzzIfDiv3And5() throws Exception {
		assertEquals("FizzBuzz", sut.fizzBuzz(15));
	}

	@RepeatedTest(value = 100, name = "Repetition {currentRepetition} of {totalRepetition}")
	public void shouldReturnBuzzIfDiv5() throws Exception {
		assertEquals("Buzz", sut.fizzBuzz(5));
	}

	@RepeatedTest(value = 100, name = "Repetition {currentRepetition} of {totalRepetition}")
	public void shouldReturnFizzIfDiv3() throws Exception {
		assertEquals("Fizz", sut.fizzBuzz(3));
	}

	@RepeatedTest(value = 100, name = "Repetition {currentRepetition} of {totalRepetition}")
	public void shouldReturnVal() throws Exception {
		assertEquals("2", sut.fizzBuzz(2));
	}
}

Po drugie, adnotacja ta ma parametr name, który pozwala na dodanie nazwy specyficznej dla uruchomienia. W nazwie tej możemy wykorzystać trzy flagi:

  • {currentRepetition} – w której jest numer aktualnego przebiegu,
  • {totalRepetition} – w której mamy ilość wszystkich przebiegów,
  • {displayName} – która zawiera nazwę testu zdefiniowaną w @DisplayName.

Możemy też jako wartość parametru podać jedną ze stałych zdefiniowanych w samej adnotacji:

  • SHORT_DISPLAY_NAME – która jest równoważna „repetition {currentRepetition} of {totalRepetition}”,
  • LONG_DISPLAY_NAME – która jest równoważna „{displayName} :: repetition {currentRepetition} of {totalRepetition}”.

Problem polega jednak na tym, że nie możemy skonfigurować liczby wątków, które zostaną wykorzystane do uruchomienia testu. Nie pozostaje nic innego jak użycie specyficznego silnika, którego oczywiście jeszcze nie ma.

2 myśli na temat “JUnit 5 – Testy powtarzalne

  1. Dzieńdobry 😉
    Pytanie trochę nie w temacie: z jakiego IDE oraz motywu kolorystycznego Pan korzysta?
    Przyznam, że na zamieszczonych screenach wygląda to świetnie: przejrzyście, kolory nie rażą, a i ładnie się to prezentuje.

  2. To zależy gdzie 🙂 Na blogu jest to zmodyfikowany syntaxhighlighter-dark. Zresztą można rzucić okiem w CSS. IDE to IntelliJ Idea z motywem Darkul, czcionką Lucida i włączonym podmienianiem znaków na ligatury.

Napisz odpowiedź

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

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax