kotest и все-все-все

height:300 drop-shadow

Паша Финкельштейн, JetBrains

Кто я

  • Developer Advocate
  • Люблю тестировать
  • Люблю изучать новое
  • Люблю Kotlin
@asm0di0 at Twitter  @asm0dey at Telegram  @snowone_conf

О чём это

  • Для тестирования используется множество инструментов
  • В джаве богатая экосистема
  • И «проверенные годами» инструменты
@asm0di0 at Twitter  @asm0dey at Telegram  @snowone_conf

Что дал миру JVM Kotlin

  • DSL
  • Extension methods
  • Функции — first-class citizens
@asm0di0 at Twitter  @asm0dey at Telegram  @snowone_conf

И множество новых библиотек!

@asm0di0 at Twitter  @asm0dey at Telegram  @snowone_conf

Но зачем?

@asm0di0 at Twitter  @asm0dey at Telegram  @snowone_conf

Структура

Сейчас как-то так:

class MyVeryImportantTest {
    @Test
    void feature_should_work_somehow(){ /*snip*/ }
    @Test
    void feature_should_work_somehow2(){ /*snip*/ }
    @Test
    void feature_should_work_somehow3(){ /*snip*/ }
}
@asm0di0 at Twitter  @asm0dey at Telegram  @snowone_conf

Добро пожаловать в плоский мир

@asm0di0 at Twitter  @asm0dey at Telegram  @snowone_conf

А хочется прекрасного

passwordService {
    shouldHash {
        length { /* snip */ }
        salt { /* snip  */ }
    }
    shouldCheck {
        validPasswords()
        invalidPasswords()
    }   
}
@asm0di0 at Twitter  @asm0dey at Telegram  @snowone_conf

Parametrized tests

TestNG

@DataProvider(name = "test1")
public static Object[][] primeNumbers() {
    return new Object[][] { {2, true}, {6, false}, 
        {19, true}, {22, false}, {23, true}};
}

@Test(dataProvider = "test1") 
void testPrimeNumberChecker(Integer inputNumber, 
        Boolean expectedResult){ /* snip */}
@asm0di0 at Twitter  @asm0dey at Telegram  @snowone_conf

Parametrized tests

JUnit 5

static Stream<Arguments> stringIntAndListProvider() {
    return Stream.of(
        arguments("apple", 1, Arrays.asList("a", "b")),
        arguments("lemon", 2, Arrays.asList("x", "y"))
    );
} 
@ParameterizedTest
@MethodSource("stringIntAndListProvider")
void testWithMultiArgMethodSource(String str, 
    int num, List<String> list) {/* snip */}
@asm0di0 at Twitter  @asm0dey at Telegram  @snowone_conf

Всё ещё шумновато

  • Аннотации
  • Arrays.asList (в новой джаве лучше)
  • Строки, в которых можно ошибиться
  • Отдельные методы
@asm0di0 at Twitter  @asm0dey at Telegram  @snowone_conf

Тесты должны читаться легко

@asm0di0 at Twitter  @asm0dey at Telegram  @snowone_conf

Сага о

безопасности

Безопасность на лесопилке

Надо хранить пароли. Но как?

  • Plain
  • MD5(plain)
  • MD5(plain+salt)
  • MD5(md5(plain)+salt)

Быстро!
200 GH/s @ 8x Nvidia GTX 1080 Founders Edition with Hashcat

@asm0di0 at Twitter  @asm0dey at Telegram  @snowone_conf

И что делать?

Плакать

Или использовать bcrypt/scrypt

Хэш начинается с магического $2a$10

$2a — версия bcrypt
$10 — количество раундов «соления»

Они очень медленные (100/1000 в секунду)

@asm0di0 at Twitter  @asm0dey at Telegram  @snowone_conf

Kotlintest

It's demo time!

@asm0di0 at Twitter  @asm0dey at Telegram  @snowone_conf

Что надо запомнить

kotest решает для нас проблемы

  • Структурирования
  • Параметризованных тестов
  • Property-based тестирования
@asm0di0 at Twitter  @asm0dey at Telegram  @snowone_conf

Спасибо! Вопросы?

asm0di0 @ Twitter
asm0dey @ Telegram
it.asm0dey.ru

@asm0di0 at Twitter  @asm0dey at Telegram  @snowone_conf