Гость
Map
Форумы / Java [игнор отключен] [закрыт для гостей] / Тяпничный property-based testing (PBT) / 8 сообщений из 8, страница 1 из 1
18.12.2020, 13:37
    #40029067
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничный property-based testing (PBT)
Привет котики!

Вот что придумал ваш кот. В продолжение 22195620 , 21099367 .

Мне надо было протестить библиотечку поддержки графовых структур. По сути проверить что вершины-ребра
соответсвуют тому что было заказано для каждого объекта-графа. Количество штук - совпадает.

Мне не хотелось перечислять все вариации графов и писать по модульному тесту на каждый.
Пустой. Полно-связный. И прочее. Главное из курса дискретной математики я запомнил утверждение.

Сумма степеней вершин равна удвоенному числу ребер

Это свойство. Проперти.

Я вспомнил PBT https://jqwik.net/property-based-testing.html и заюзал библиотечку net.jqwik:jqwik:LATEST
и вот что у меня получилось.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
package mayton.lib.graph;

import net.jqwik.api.*;

import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * Сумма степеней вершин равна удвоенному числу ребер
 *
 */
@PropertyDefaults(tries = 300)
public class GraphFormulaTest {

    private Random random = new Random();

    @Property
    boolean graphFormulaIsCorrect(@ForAll("RandomGraphs") Graph<Void,Void> graph) {

        int sumVertexPowers = graph.getVertexMap().entrySet().stream()
                .map(Map.Entry::getValue)
                .map(vertex -> vertex.getIncomingEdges().size() + vertex.getOutgoingEdges().size())
                .collect(Collectors.summingInt(Integer::intValue));

        int edgesCount = graph.getEdgeMap().size();

        return sumVertexPowers == 2 * edgesCount;
    }

    @Provide("RandomGraphs")
    Arbitrary<Graph<Void,Void>> randomGraph() {
        return Arbitraries.create(() -> randomGraphSupplier(20));
    }

    private Graph<Void, Void> randomGraphSupplier(int parameter) {
        Graph graph = new Graph<>();
        int n = random.nextInt(parameter);
        for (int i = 0; i < (n * n / 2); i++) {
            graph.linkEdge(random.nextInt(20), random.nextInt(20));
        }
        return graph;
    }


}



Возможно сам граф-генератор не очень удачен. Не покрывает все вариации.

Вопросы.

1) Сделайте code-review.
2) Кто из вас использовал property-based testing в продуктовых задачах?
3) Насколько было полезно?
4) Отключали-ли вы PBT для пред-релизных сборок?
5) Была-ли проблема комбинаторного взрыва для тех тестов которые многомерные?
6) Как вы сочетали обычные тесты и PBT?
...
Рейтинг: 0 / 0
18.12.2020, 15:10
    #40029085
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничный property-based testing (PBT)
Код: java
1.
graph.linkEdge(random.nextInt(20), random.nextInt(20));



что за магическая константа 20? Это тоже самое что и parameter?

непонятно, что делает вообще этот метод. Существуют ои вершины без ребер? Сколько их по дефолту? По идее это валидный кейс для темстирования.

В целом генератор смотрится нормально. Немного смущает вероятность того что не будет протестирован пустой граф при определенных условиях, если за 300 попыток ни разу не выпадет 0.

2) Кто из вас использовал property-based testing в продуктовых задачах?
3) Насколько было полезно?

Используем, но у него достаточно ограниченная область применения, в целом при ООП оно не приносит много пользы. На проектах с чистым ФП, где сначала определяются алгебры операций - там процент полезности выше.
4) Отключали-ли вы PBT для пред-релизных сборок?

Нет, зачем? В чем смысл тогда? Если боишься что будет работать медленно - то значит надо переписать, тут не должно быть внешних зависимостей и работать должно шустро. Если боишься неповторяемости результатов - так в том и смысл, пусть упадет при сборке чем на проде
5) Была-ли проблема комбинаторного взрыва для тех тестов которые многомерные?

О чем ты вообще? Проперти обычно простые и тестируются по отдельности
6) Как вы сочетали обычные тесты и PBT?

А в чем проблема? Это даже проще чем сочетать интеграционные с юнитами. Потому что время выполнения небольшое
[/SRC]
...
Рейтинг: 0 / 0
18.12.2020, 16:19
    #40029110
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничный property-based testing (PBT)
забыл ник
Код: java
1.
graph.linkEdge(random.nextInt(20), random.nextInt(20));



что за магическая константа 20? Это тоже самое что и parameter?

непонятно, что делает вообще этот метод. Существуют ои вершины без ребер? Сколько их по дефолту? По идее это валидный кейс для темстирования.

В целом генератор смотрится нормально. Немного смущает вероятность того что не будет протестирован пустой граф при определенных условиях, если за 300 попыток ни разу не выпадет 0.

Предлагайте ваши пул-реквесты. Но я еще хотел детально почитать по более сложным кейсам когда
мы тестируем 2 измерения а не одно как в моем случае. Константа 20 это просто моя небрежность.
Торопился.
...
Рейтинг: 0 / 0
18.12.2020, 17:09
    #40029120
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничный property-based testing (PBT)
забыл ник

Используем, но у него достаточно ограниченная область применения, в целом при ООП оно не приносит много пользы. На проектах с чистым ФП, где сначала определяются алгебры операций - там процент полезности выше.

Да. Если читать историю происхождения этих фреймворков то все дороги ведут к Haskell и его некой эталонной
реализации PBT-тестирования.
...
Рейтинг: 0 / 0
18.12.2020, 17:34
    #40029124
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничный property-based testing (PBT)
забыл ник

В целом генератор смотрится нормально. Немного смущает вероятность того что не будет протестирован пустой граф при определенных условиях, если за 300 попыток ни разу не выпадет 0.

Я не про медлительность. Я про детерминизм. Допустим при одном случайном состоянии Random::seed мы зашли
в fail(), и при следующем запуске - все снова в зеленом статусе а мы уже информацию об этом утеряли.
...
Рейтинг: 0 / 0
18.12.2020, 18:03
    #40029127
забыл ник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничный property-based testing (PBT)
mayton
забыл ник

В целом генератор смотрится нормально. Немного смущает вероятность того что не будет протестирован пустой граф при определенных условиях, если за 300 попыток ни разу не выпадет 0.

Я не про медлительность. Я про детерминизм. Допустим при одном случайном состоянии Random::seed мы зашли
в fail(), и при следующем запуске - все снова в зеленом статусе а мы уже информацию об этом утеряли.

Так зачем запускать билд после фейла опять? Это раз. А во-вторых логи то остаются
...
Рейтинг: 0 / 0
18.12.2020, 18:04
    #40029129
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничный property-based testing (PBT)
забыл ник
mayton
пропущено...

Я не про медлительность. Я про детерминизм. Допустим при одном случайном состоянии Random::seed мы зашли
в fail(), и при следующем запуске - все снова в зеленом статусе а мы уже информацию об этом утеряли.

Так зачем запускать билд после фейла опять? Это раз. А во-вторых логи то остаются

Да я какраз щас читаю про jqwik. Похоже у него есть файловое хранилище для результатов
тестов. И политика реакции на fail.
...
Рейтинг: 0 / 0
18.12.2020, 19:21
    #40029141
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тяпничный property-based testing (PBT)
Ага. Вот опция.

Код: java
1.
@PropertyDefaults(tries = 300, afterFailure = AfterFailureMode.PREVIOUS_SEED)



Искусственно сломал формулу. Теперь она на любой результат дает fail.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running GraphFormulaProperties
timestamp = 2020-12-18T18:19:42.075452, GraphFormulaProperties:graphFormulaIsCorrect = 
  org.opentest4j.AssertionFailedError:
    Property [GraphFormulaProperties:graphFormulaIsCorrect] failed with sample {0=G(|V|=20,|E|=115)}

                              |-------------------jqwik-------------------
tries = 1                     | # of calls to property
checks = 1                    | # of not rejected calls
generation = EXHAUSTIVE       | parameters are exhaustively generated
after-failure = PREVIOUS_SEED | use the previous seed
edge-cases#mode = MIXIN       | edge cases are mixed in
edge-cases#total = 0          | # of all combined edge cases
edge-cases#tried = 0          | # of edge cases tried in current run
seed = 8702183341123046303    | random seed to reproduce generated values

Sample
------
  graph: G(|V|=20,|E|=115)



Теперь после первого сбоя seed фиксируется до тех пор пока не будет исправлено.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Тяпничный property-based testing (PBT) / 8 сообщений из 8, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]