Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Тестирование на основе сетей Петри

Тестирование на основе сетей Петри

A talk about automated exploratory testing based on Petri net models for HeisenBug Piter 2018 (https://2018.heisenbug-piter.ru/talks/2018/spb/6feubdtqqwqocya2w4cwq2/). The recording of the talk is available on YouTube (https://www.youtube.com/watch?v=TeKHZw61pb8).

Alex Rodionov

May 17, 2018
Tweet

More Decks by Alex Rodionov

Other Decks in Programming

Transcript

  1. ТЕСТИРОВАНИЕ НА ОСНОВЕ
    СЕТЕЙ ПЕТРИ

    View full-size slide

  2. !
    Лёша Родионов
    2

    View full-size slide

  3. !
    Лёша Родионов
    3

    View full-size slide

  4. !
    Лёша Родионов
    @p0deje
    4

    View full-size slide

  5. !
    Лёша Родионов
    @p0deje
    5

    View full-size slide

  6. !
    Лёша Родионов
    @p0deje
    6

    View full-size slide

  7. !
    Лёша Родионов
    @p0deje
    7

    View full-size slide

  8. ТЕСТИРОВАНИЕ НА ОСНОВЕ
    СЕТЕЙ ПЕТРИ

    View full-size slide

  9. ДЛЯ КОГО?
    9

    View full-size slide

  10. ДЛЯ КОГО?
    1.Для тех, у кого много тестов и багов.
    10

    View full-size slide

  11. ДЛЯ КОГО?
    1.Для тех, у кого много тестов и багов.
    2.Для тех, кто только планирует
    автоматизированное тестирование.
    11

    View full-size slide

  12. 1. Недостаточность обычных тестов



    View full-size slide

  13. 1. Недостаточность обычных тестов
    2. Тестирование на основе моделей


    View full-size slide

  14. 1. Недостаточность обычных тестов
    2. Тестирование на основе моделей
    3. Сети Петри


    View full-size slide

  15. 1. Недостаточность обычных тестов
    2. Тестирование на основе моделей
    3. Сети Петри
    4. Тестирование на основе сетей Петри

    View full-size slide

  16. 1. Недостаточность обычных тестов
    2. Тестирование на основе моделей
    3. Сети Петри
    4. Тестирование на основе сетей Петри

    View full-size slide

  17. ОБЫЧНЫЙ ТЕСТ
    A
    A
    A
    17

    View full-size slide

  18. ОБЫЧНЫЙ ТЕСТ
    Arrange: выполняет предусловия
    A
    A
    18

    View full-size slide

  19. ОБЫЧНЫЙ ТЕСТ
    Arrange: выполняет предусловия
    Act: выполняет какое-то действие
    A
    19

    View full-size slide

  20. ОБЫЧНЫЙ ТЕСТ
    Arrange: выполняет предусловия
    Act: выполняет какое-то действие
    Assert: верифицирует состояние/поведение
    20

    View full-size slide

  21. ОБЫЧНЫЙ ТЕСТ
    Arrange: выполняет предусловия
    Act: выполняет какое-то действие
    Assert: верифицирует состояние/поведение
    21

    View full-size slide

  22. 22
    class User < ApplicationRecord
    end

    View full-size slide

  23. 23
    class User < ApplicationRecord
    end
    it 'destroys user’ do
    user = User.create!
    user.destroy
    expect(User.count).to eq(0)
    end

    View full-size slide

  24. 24
    arrange
    act
    assert
    class User < ApplicationRecord
    end
    it 'destroys user’ do
    user = User.create!
    user.destroy
    expect(User.count).to eq(0)
    end

    View full-size slide

  25. 25
    class User < ApplicationRecord
    end
    it 'destroys user’ do
    user = User.create!
    user.destroy
    expect(User.count).to eq(0)
    end

    View full-size slide

  26. 26
    class User < ApplicationRecord
    has_many :notes
    end
    class Note < ApplicationRecord
    belongs_to :user
    end
    it 'destroys user’ do
    user = User.create!
    user.destroy
    expect(User.count).to eq(0)
    end

    View full-size slide

  27. 27
    class User < ApplicationRecord
    has_many :notes
    end
    class Note < ApplicationRecord
    belongs_to :user
    end
    it 'destroys user with a note’ do
    user = User.create!(note: Note.create!)
    user.destroy
    expect(User.count).to eq(0)
    end

    View full-size slide

  28. 28
    class User < ApplicationRecord
    has_many :notes
    end
    class Note < ApplicationRecord
    belongs_to :user
    end
    it 'destroys user with a note’ do
    user = User.create!(note: Note.create!)
    user.destroy
    expect(User.count).to eq(0)
    end

    View full-size slide

  29. 29
    class User < ApplicationRecord
    has_many :notes
    end
    class Note < ApplicationRecord
    belongs_to :user
    end
    ActiveRecord ::InvalidForeignKey:
    PG ::ForeignKeyViolation: ERROR:
    update or delete on table "users" violates
    foreign key constraint “fk_rails_83d9817008"
    on table "notes"
    DETAIL: Key (id)=(1) is still referenced
    from table “notes".

    View full-size slide

  30. 30
    class User < ApplicationRecord
    has_many :notes, dependent: :destroy
    end
    class Note < ApplicationRecord
    belongs_to :user
    end
    it 'destroys user with a note’ do
    user = User.create!(note: Note.create!)
    user.destroy
    expect(User.count).to eq(0)
    end

    View full-size slide

  31. 31
    class User < ApplicationRecord
    has_many :notes, dependent: :destroy
    end
    class Note < ApplicationRecord
    belongs_to :user
    end
    it 'destroys user with a note’ do
    user = User.create!(note: Note.create!)
    user.destroy
    expect(User.count).to eq(0)
    end

    View full-size slide

  32. КОМБИНАЦИИ СОСТОЯНИЙ
    32

    View full-size slide

  33. 33
    1.Писать больше тестов?
    КОМБИНАЦИИ СОСТОЯНИЙ

    View full-size slide

  34. 34
    1.Писать больше тестов?
    2.Рандомные данные?
    КОМБИНАЦИИ СОСТОЯНИЙ

    View full-size slide

  35. 1. Недостаточность обычных тестов
    2. Тестирование на основе моделей
    3. Сети Петри
    4. Тестирование на основе сетей Петри

    View full-size slide

  36. ТЕСТИРОВАНИЕ НА ОСНОВЕ МОДЕЛЕЙ
    1.Создаем модель системы


    36

    View full-size slide

  37. ТЕСТИРОВАНИЕ НА ОСНОВЕ МОДЕЛЕЙ
    1.Создаем модель системы
    2.Генерируем на основе модели
    тесты
    37

    View full-size slide

  38. GRAPHWALKER
    38

    View full-size slide

  39. ПРИМЕР
    40

    View full-size slide

  40. ПРИМЕР
    41

    View full-size slide

  41. ПРИМЕР
    42

    View full-size slide

  42. ПРИМЕР
    43

    View full-size slide

  43. ПРИМЕР
    44

    View full-size slide

  44. ПРИМЕР
    45

    View full-size slide

  45. ПРИМЕР
    46

    View full-size slide

  46. 47
    @GraphWalker(value = "random(edge_coverage(100))",
    start = "v_NotesListView")
    public class NotesListTest {
    }

    View full-size slide

  47. 48
    @GraphWalker(value = "random(edge_coverage(100))",
    start = "v_NotesListView")
    public class NotesListTest {
    }

    View full-size slide

  48. 49
    @GraphWalker(value = "random(edge_coverage(100))",
    start = "v_NotesListView")
    public class NotesListTest {
    }

    View full-size slide

  49. 50
    @GraphWalker(value = "random(edge_coverage(100))",
    start = "v_NotesListView")
    public class NotesListTest {
    @Override
    public void e_GoToNewNoteView() {
    }
    }

    View full-size slide

  50. 51
    @GraphWalker(value = "random(edge_coverage(100))",
    start = "v_NotesListView")
    public class NotesListTest {
    @Override
    public void e_GoToNewNoteView() {
    driver.pressKeyCode(AndroidKeyCode.KEYCODE_MENU);
    driver.findElementByClassName("android.widget.TextView").click();
    }
    }

    View full-size slide

  51. 52
    @GraphWalker(value = "random(edge_coverage(100))",
    start = "v_NotesListView")
    public class NotesListTest {
    @Override
    public void e_Discard() {
    driver.pressKeyCode(AndroidKeyCode.KEYCODE_MENU);
    driver.findElementByClassName("android.widget.TextView").click();
    }
    }

    View full-size slide

  52. 53
    @GraphWalker(value = "random(edge_coverage(100))",
    start = "v_NotesListView")
    public class NotesListTest {
    @Override
    public void e_Create() {
    }
    }

    View full-size slide

  53. 54
    @GraphWalker(value = "random(edge_coverage(100))",
    start = "v_NotesListView")
    public class NotesListTest {
    @Override
    public void e_Create() {
    String noteName = "test+" + new Random().nextInt();
    }
    }

    View full-size slide

  54. 55
    @GraphWalker(value = "random(edge_coverage(100))",
    start = "v_NotesListView")
    public class NotesListTest {
    @Override
    public void e_Create() {
    String noteName = "test+" + new Random().nextInt();
    driver.findElement(By.xpath(" //android.widget.EditText[1]"))
    .sendKeys(noteName);
    }
    }

    View full-size slide

  55. 56
    @GraphWalker(value = "random(edge_coverage(100))",
    start = "v_NotesListView")
    public class NotesListTest {
    @Override
    public void e_Create() {
    String noteName = "test+" + new Random().nextInt();
    driver.findElement(By.xpath(" //android.widget.EditText[1]"))
    .sendKeys(noteName);
    driver.hideKeyboard();
    driver.pressKeyCode(AndroidKeyCode.KEYCODE_BACK);
    }
    }

    View full-size slide

  56. 57
    @GraphWalker(value = "random(edge_coverage(100))",
    start = "v_NotesListView")
    public class NotesListTest {
    @Override
    public void e_Create() {
    String noteName = "test+" + new Random().nextInt();
    driver.findElement(By.xpath(" //android.widget.EditText[1]"))
    .sendKeys(noteName);
    driver.hideKeyboard();
    driver.pressKeyCode(AndroidKeyCode.KEYCODE_BACK);
    expectedNumberOfNotes ++;
    }
    }

    View full-size slide

  57. 58
    @GraphWalker(value = "random(edge_coverage(100))",
    start = "v_NotesListView")
    public class NotesListTest {
    @Override
    public void v_NotesListView() {
    }
    }

    View full-size slide

  58. 59
    @GraphWalker(value = "random(edge_coverage(100))",
    start = "v_NotesListView")
    public class NotesListTest {
    @Override
    public void v_NotesListView() {
    WebElement notesList =
    driver.findElementByClassName("android.widget.TextView");
    assertTrue(notesList.getText().equals("Note pad”));
    }
    }

    View full-size slide

  59. 60
    @GraphWalker(value = "random(edge_coverage(100))",
    start = "v_NotesListView")
    public class NotesListTest {
    @Override
    public void v_NotesListView() {
    WebElement notesList =
    driver.findElementByClassName("android.widget.TextView");
    assertTrue(notesList.getText().equals("Note pad”));
    List notesInList =
    driver.findElement(By.className("android.widget.ListView"))
    .findElements(By.className("android.widget.TextView"));
    int actualNumberOfNotes = notesInList.size();
    assertEquals(expectedNumberOfNotes, actualNumberOfNotes);
    }
    }

    View full-size slide

  60. 61
    @GraphWalker(value = "random(edge_coverage(100))",
    start = "v_NotesListView")
    public class NotesListTest {
    @Override
    public void v_NewNoteView() {
    }
    }

    View full-size slide

  61. 62
    @GraphWalker(value = "random(edge_coverage(100))",
    start = "v_NotesListView")
    public class NotesListTest {
    @Override
    public void v_NewNoteView() {
    WebElement notesEditor =
    driver.findElementByClassName("android.widget.EditText");
    Assert.assertTrue(notesEditor.isDisplayed());
    }
    }

    View full-size slide

  62. 63
    $ mvn graphwalker:test
    [INFO] Tests:
    [INFO] NotesListTest(RandomPath, VertexCoverage, 100)

    View full-size slide

  63. 64
    $ mvn graphwalker:test
    [INFO] Tests:
    [INFO] NotesListTest(RandomPath, VertexCoverage, 100)
    Before element v_NotesListView
    After element v_NotesListView

    View full-size slide

  64. 65
    $ mvn graphwalker:test
    [INFO] Tests:
    [INFO] NotesListTest(RandomPath, VertexCoverage, 100)
    Before element v_NotesListView
    After element v_NotesListView
    Before element e_GoToNewNoteView
    After element e_GoToNewNoteView

    View full-size slide

  65. 66
    $ mvn graphwalker:test
    [INFO] Tests:
    [INFO] NotesListTest(RandomPath, VertexCoverage, 100)
    Before element v_NotesListView
    After element v_NotesListView
    Before element e_GoToNewNoteView
    After element e_GoToNewNoteView
    Before element v_NewNoteView
    After element v_NewNoteView

    View full-size slide

  66. 67
    $ mvn graphwalker:test
    [INFO] Tests:
    [INFO] NotesListTest(RandomPath, VertexCoverage, 100)
    Before element v_NotesListView
    After element v_NotesListView
    Before element e_GoToNewNoteView
    After element e_GoToNewNoteView
    Before element v_NewNoteView
    After element v_NewNoteView
    Before element e_Create
    After element e_Create

    View full-size slide

  67. 68
    $ mvn graphwalker:test
    [INFO] Tests:
    [INFO] NotesListTest(RandomPath, VertexCoverage, 100)
    Before element v_NotesListView
    After element v_NotesListView
    Before element e_GoToNewNoteView
    After element e_GoToNewNoteView
    Before element v_NewNoteView
    After element v_NewNoteView
    Before element e_Create
    After element e_Create
    Before element v_NotesListView
    After element v_NotesListView

    View full-size slide

  68. 69
    $ mvn graphwalker:test
    [INFO] Tests:
    [INFO] NotesListTest(RandomPath, VertexCoverage, 100)
    Before element v_NotesListView
    After element v_NotesListView
    Before element e_GoToNewNoteView
    After element e_GoToNewNoteView
    Before element v_NewNoteView
    After element v_NewNoteView
    Before element e_Create
    After element e_Create
    Before element v_NotesListView
    After element v_NotesListView
    Before element e_GoToNewNoteView
    After element e_GoToNewNoteView

    View full-size slide

  69. 70
    $ mvn graphwalker:test
    [INFO] Tests:
    [INFO] NotesListTest(RandomPath, VertexCoverage, 100)
    Before element v_NotesListView
    After element v_NotesListView
    Before element e_GoToNewNoteView
    After element e_GoToNewNoteView
    Before element v_NewNoteView
    After element v_NewNoteView
    Before element e_Create
    After element e_Create
    Before element v_NotesListView
    After element v_NotesListView
    Before element e_GoToNewNoteView
    After element e_GoToNewNoteView
    Before element v_NewNoteView
    After element v_NewNoteView

    View full-size slide

  70. 71
    $ mvn graphwalker:test
    [INFO] Tests:
    [INFO] NotesListTest(RandomPath, VertexCoverage, 100)
    Before element v_NotesListView
    After element v_NotesListView
    Before element e_GoToNewNoteView
    After element e_GoToNewNoteView
    Before element v_NewNoteView
    After element v_NewNoteView
    Before element e_Create
    After element e_Create
    Before element v_NotesListView
    After element v_NotesListView
    Before element e_GoToNewNoteView
    After element e_GoToNewNoteView
    Before element v_NewNoteView
    After element v_NewNoteView
    Before element e_Discard
    After element e_Discard

    View full-size slide

  71. 72
    $ mvn graphwalker:test
    [INFO] Tests:
    [INFO] NotesListTest(RandomPath, VertexCoverage, 100)
    Before element v_NotesListView
    After element v_NotesListView
    Before element e_GoToNewNoteView
    After element e_GoToNewNoteView
    Before element v_NewNoteView
    After element v_NewNoteView
    Before element e_Create
    After element e_Create
    Before element v_NotesListView
    After element v_NotesListView
    Before element e_GoToNewNoteView
    After element e_GoToNewNoteView
    Before element v_NewNoteView
    After element v_NewNoteView
    Before element e_Discard
    After element e_Discard
    Before element v_NotesListView
    After element v_NotesListView

    View full-size slide

  72. GRAPHWALKER
    1.Java/Python
    2.Конечные автоматы
    73

    View full-size slide

  73. КОНЕЧНЫЙ АВТОМАТ
    74

    View full-size slide

  74. КОНЕЧНЫЙ АВТОМАТ
    75

    View full-size slide

  75. КОНЕЧНЫЙ АВТОМАТ
    76

    View full-size slide

  76. КОНЕЧНЫЙ АВТОМАТ
    77

    View full-size slide

  77. КОНЕЧНЫЙ АВТОМАТ
    78

    View full-size slide

  78. КОНЕЧНЫЙ АВТОМАТ
    79

    View full-size slide

  79. КОНЕЧНЫЙ АВТОМАТ
    1.Дублирование
    2.Concurrency = state explosion
    80

    View full-size slide

  80. 1. Недостаточность обычных тестов
    2. Тестирование на основе моделей
    3. Сети Петри
    4. Тестирование на основе сетей Петри

    View full-size slide

  81. СЕТЬ ПЕТРИ
    82
    not created
    Create User
    created

    View full-size slide

  82. СЕТЬ ПЕТРИ
    83
    позиции (places) хранят метки
    not created
    Create User
    created

    View full-size slide

  83. СЕТЬ ПЕТРИ
    84
    позиции (places) хранят метки
    переходы (transitions) перемещают
    метки
    not created
    Create User
    created

    View full-size slide

  84. СЕТЬ ПЕТРИ
    85
    позиции (places) хранят метки
    дуги связывают позиции и переходы
    переходы (transitions) перемещают
    метки
    not created
    Create User
    created

    View full-size slide

  85. СЕТЬ ПЕТРИ
    86
    позиция not created
    содержит метку
    not created
    Create User
    created

    View full-size slide

  86. СЕТЬ ПЕТРИ
    87
    переход Create User может
    сработать
    not created
    Create User
    created

    View full-size slide

  87. СЕТЬ ПЕТРИ
    88
    срабатывание удаляет
    метку из not created и
    добавляет в created
    not created
    Create User
    created

    View full-size slide

  88. 89
    1. Переходы могут быть связаны только с позициями (и наоборот)
    СЕТЬ ПЕТРИ

    View full-size slide

  89. 90
    1. Переходы могут быть связаны только с позициями (и наоборот)
    2. Переход может сработать когда в каждой входной позиции есть
    по меньшей мере одна метка
    СЕТЬ ПЕТРИ

    View full-size slide

  90. 91
    1. Переходы могут быть связаны только с позициями (и наоборот)
    2. Переход может сработать когда в каждой входной позиции есть
    по меньшей мере одна метка
    3. Срабатывание перехода забирает по одной метке из каждой
    входной позиции и добавляет по одной метке в каждую
    выходную позицию
    СЕТЬ ПЕТРИ

    View full-size slide

  91. not created
    Create User
    created
    СЕТЬ ПЕТРИ
    92
    ip allowed

    View full-size slide

  92. СЕТЬ ПЕТРИ
    93
    not created
    Create User
    created
    ip allowed
    not created
    Create User
    created
    ip allowed

    View full-size slide

  93. СЕТЬ ПЕТРИ
    94
    pending review
    not created
    Create User
    created

    View full-size slide

  94. СЕТЬ ПЕТРИ
    95
    pending review
    not created
    Create User
    created
    pending review
    not created
    Create User
    created

    View full-size slide

  95. СЕТЬ ПЕТРИ
    96
    not created
    Create User
    created

    View full-size slide

  96. СЕТЬ ПЕТРИ
    97
    not created
    Create User
    created
    not created
    Create User
    created

    View full-size slide

  97. КОНЕЧНЫЙ АВТОМАТ
    98

    View full-size slide

  98. СЕТЬ ПЕТРИ
    99
    user not created
    user created
    note created

    View full-size slide

  99. СЕТЬ ПЕТРИ
    100
    user not created
    user created
    note created
    Create User

    View full-size slide

  100. СЕТЬ ПЕТРИ
    101
    user not created
    user created
    note created
    Create User
    Destroy User

    View full-size slide

  101. СЕТЬ ПЕТРИ
    102
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note

    View full-size slide

  102. СЕТЬ ПЕТРИ
    103
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note

    View full-size slide

  103. СЕТЬ ПЕТРИ
    104
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note

    View full-size slide

  104. СЕТЬ ПЕТРИ
    105
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note

    View full-size slide

  105. СЕТЬ ПЕТРИ
    106
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note

    View full-size slide

  106. КОНЕЧНЫЙ АВТОМАТ
    107

    View full-size slide

  107. СЕТЬ ПЕТРИ
    108
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note
    post created

    View full-size slide

  108. СЕТЬ ПЕТРИ
    109
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note
    post created
    Create Post

    View full-size slide

  109. СЕТЬ ПЕТРИ
    110
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note
    post created
    Create Post Destroy Post

    View full-size slide

  110. КОНЕЧНЫЙ АВТОМАТ
    111

    View full-size slide

  111. СЕТЬ ПЕТРИ
    112
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note
    post created
    Create Post Destroy Post
    video created

    View full-size slide

  112. СЕТЬ ПЕТРИ
    113
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note
    post created
    Create Post Destroy Post
    Create Video
    video created

    View full-size slide

  113. СЕТЬ ПЕТРИ
    114
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note
    post created
    Create Post Destroy Post
    Create Video Destroy Video
    video created

    View full-size slide

  114. 1. Недостаточность обычных тестов
    2. Тестирование на основе моделей
    3. Сети Петри
    4. Тестирование на основе сетей Петри

    View full-size slide

  115. ТЕСТИРОВАНИЕ НА ОСНОВЕ СЕТЕЙ ПЕТРИ
    116

    View full-size slide

  116. ТЕСТИРОВАНИЕ НА ОСНОВЕ СЕТЕЙ ПЕТРИ
    1.Создаем модель системы
    используя cеть Петри


    117

    View full-size slide

  117. ТЕСТИРОВАНИЕ НА ОСНОВЕ СЕТЕЙ ПЕТРИ
    1.Создаем модель системы
    используя cеть Петри
    2.Генерируем на основе модели
    тесты
    118

    View full-size slide

  118. СОЗДАНИЕ МОДЕЛИ
    119

    View full-size slide

  119. СОЗДАНИЕ МОДЕЛИ
    120
    {
    "places": [
    {
    "guid": "e57c0830-148f-11e8-bb7f-adf9986e1043",
    "identifier": "user created"
    }
    ],
    "transitions": [
    {
    "guid": “df65a6e0-148f-11e8-bb7f-adf9986e1043"
    "identifier": "Create User",
    }
    ],
    "arcs": [
    {
    "from_guid": "e57c0830-148f-11e8-bb7f-adf9986e1043",
    "to_guid": “df65a6e0-148f-11e8-bb7f-adf9986e1043"
    }
    ]
    }

    View full-size slide

  120. ЗАГРУЗКА СЕТИ
    121

    View full-size slide

  121. ЗАГРУЗКА СЕТИ
    122
    class Node
    def input_arcs
    # ...
    end
    def output_arcs
    # ...
    end
    end

    View full-size slide

  122. ЗАГРУЗКА СЕТИ
    123
    class Node
    def input_arcs
    # ...
    end
    def output_arcs
    # ...
    end
    end
    class Place < Node
    end

    View full-size slide

  123. ЗАГРУЗКА СЕТИ
    124
    class Node
    def input_arcs
    # ...
    end
    def output_arcs
    # ...
    end
    end
    class Place < Node
    end
    class Transition < Node
    end

    View full-size slide

  124. ЗАГРУЗКА СЕТИ
    125
    class Node
    def input_arcs
    # ...
    end
    def output_arcs
    # ...
    end
    end
    class Place < Node
    end
    class Transition < Node
    end
    class Arc
    def from
    # ...
    end
    def to
    # ...
    end
    end

    View full-size slide

  125. ЗАГРУЗКА СЕТИ
    126
    class Runner
    def enabled?(transition)
    # ...
    end
    def fire(transition)
    # ...
    end
    def marking
    # ...
    end
    end

    View full-size slide

  126. СВЯЗЬ СЕТИ С ТЕСТОВЫМ КОДОМ
    127

    View full-size slide

  127. СВЯЗЬ СЕТИ С ТЕСТОВЫМ КОДОМ
    128
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note

    View full-size slide

  128. 129
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note
    class UserNoteNet < Rhizome ::Net
    end

    View full-size slide

  129. 130
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note
    class UserNoteNet < Rhizome ::Net
    runner { Runner.new('user-note.bpf', marking: ['user not created']) }
    end

    View full-size slide

  130. 131
    class UserNoteNet < Rhizome ::Net
    runner { Runner.new('user-note.bpf', marking: ['user not created']) }
    transition('Create User') { @user = User.create! }
    transition('Destroy User') { @user.destroy }
    end
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note

    View full-size slide

  131. 132
    class UserNoteNet < Rhizome ::Net
    runner { Runner.new('user-note.bpf', marking: ['user not created']) }
    transition('Create User') { @user = User.create! }
    transition('Destroy User') { @user.destroy }
    transition('Create Note') { @note = Note.create!(user: @user) }
    transition('Destroy Note') { @note.destroy }
    end
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note

    View full-size slide

  132. 133
    class UserNoteNet < Rhizome ::Net
    runner { Runner.new('user-note.bpf', marking: ['user not created']) }
    transition('Create User') { @user = User.create! }
    transition('Destroy User') { @user.destroy }
    transition('Create Note') { @note = Note.create!(user: @user) }
    transition('Destroy Note') { @note.destroy }
    place('user not created') do
    empty { expect(User.count).to be > 0 }
    filled { expect(User.count).to eq(0) }
    end
    end
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note

    View full-size slide

  133. 134
    class UserNoteNet < Rhizome ::Net
    runner { Runner.new('user-note.bpf', marking: ['user not created']) }
    transition('Create User') { @user = User.create! }
    transition('Destroy User') { @user.destroy }
    transition('Create Note') { @note = Note.create!(user: @user) }
    transition('Destroy Note') { @note.destroy }
    place('user not created') do
    empty { expect(User.count).to be > 0 }
    filled { expect(User.count).to eq(0) }
    end
    place('user created') do
    empty { expect(User.count).to eq(0) }
    filled { expect(User.count).to be > 0 }
    end
    end
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note

    View full-size slide

  134. class UserNoteNet < Rhizome ::Net
    runner { Runner.new('user-note.bpf', marking: ['user not created']) }
    transition('Create User') { @user = User.create! }
    transition('Destroy User') { @user.destroy }
    transition('Create Note') { @note = Note.create!(user: @user) }
    transition('Destroy Note') { @note.destroy }
    place('user not created') do
    empty { expect(User.count).to be > 0 }
    filled { expect(User.count).to eq(0) }
    end
    place('user created') do
    empty { expect(User.count).to eq(0) }
    filled { expect(User.count).to be > 0 }
    end
    place('note created') do
    empty { expect(Note.count).to eq(0) }
    filled { expect(Note.count).to be > 0 }
    end
    end
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note
    135

    View full-size slide

  135. ОБХОД СЕТИ
    1. Даем каждому переходу одинаковую вероятность (4 перехода = 0,25 каждому)
    136

    View full-size slide

  136. ОБХОД СЕТИ
    1. Даем каждому переходу одинаковую вероятность (4 перехода = 0,25 каждому)
    2. Генерируем случайное число - порог вероятности выбора перехода
    137

    View full-size slide

  137. ОБХОД СЕТИ
    1. Даем каждому переходу одинаковую вероятность (4 перехода = 0,25 каждому)
    2. Генерируем случайное число - порог вероятности выбора перехода
    3. Выбираем первый переход с подходящей под порог вероятностью, который
    может сработать
    138

    View full-size slide

  138. ОБХОД СЕТИ
    1. Даем каждому переходу одинаковую вероятность (4 перехода = 0,25 каждому)
    2. Генерируем случайное число - порог вероятности выбора перехода
    3. Выбираем первый переход с подходящей под порог вероятностью, который
    может сработать
    4. Срабатываем переход
    139

    View full-size slide

  139. ОБХОД СЕТИ
    1. Даем каждому переходу одинаковую вероятность (4 перехода = 0,25 каждому)
    2. Генерируем случайное число - порог вероятности выбора перехода
    3. Выбираем первый переход с подходящей под порог вероятностью, который
    может сработать
    4. Срабатываем переход
    5. Проверяем пустые и заполненные позиции
    140

    View full-size slide

  140. ОБХОД СЕТИ
    1. Даем каждому переходу одинаковую вероятность (4 перехода = 0,25 каждому)
    2. Генерируем случайное число - порог вероятности выбора перехода
    3. Выбираем первый переход с подходящей под порог вероятностью, который
    может сработать
    4. Срабатываем переход
    5. Проверяем пустые и заполненные позиции
    6. Уменьшаем вероятность сработанного перехода в 2 раза
    141

    View full-size slide

  141. ОБХОД СЕТИ
    1. Даем каждому переходу одинаковую вероятность (4 перехода = 0,25 каждому)
    2. Генерируем случайное число - порог вероятности выбора перехода
    3. Выбираем первый переход с подходящей под порог вероятностью, который
    может сработать
    4. Срабатываем переход
    5. Проверяем пустые и заполненные позиции
    6. Уменьшаем вероятность сработанного перехода в 2 раза
    7. Если все переходы сработали хотя бы раз, останавливаемся. Если нет, повторяем
    с пункта 2
    142

    View full-size slide

  142. 143
    $ bin/rhizome
    Traversing user_note net:
    Initial marking: user not created

    View full-size slide

  143. 144
    $ bin/rhizome
    Traversing user_note net:
    Initial marking: user not created
    Executing Create User
    New marking: user created
    Transitions left: Destroy User, Create Note, Destroy Note

    View full-size slide

  144. 145
    $ bin/rhizome
    Traversing user_note net:
    Initial marking: user not created
    Executing Create User
    New marking: user created
    Transitions left: Destroy User, Create Note, Destroy Note
    Executing Create Note
    New marking: user created, note created
    Transitions left: Destroy User, Destroy Note

    View full-size slide

  145. 146
    $ bin/rhizome
    Traversing user_note net:
    Initial marking: user not created
    Executing Create User
    New marking: user created
    Transitions left: Destroy User, Create Note, Destroy Note
    Executing Create Note
    New marking: user created, note created
    Transitions left: Destroy User, Destroy Note
    Executing Destroy Note
    New marking: user created
    Transitions left: Destroy User

    View full-size slide

  146. 147
    $ bin/rhizome
    Traversing user_note net:
    Initial marking: user not created
    Executing Create User
    New marking: user created
    Transitions left: Destroy User, Create Note, Destroy Note
    Executing Create Note
    New marking: user created, note created
    Transitions left: Destroy User, Destroy Note
    Executing Destroy Note
    New marking: user created
    Transitions left: Destroy User
    Executing Destroy User
    New marking: user not created
    Finished traversing user_note net.

    View full-size slide

  147. 148
    $ bin/rhizome
    Traversing user_note net:
    Initial marking: user not created

    View full-size slide

  148. 149
    $ bin/rhizome
    Traversing user_note net:
    Initial marking: user not created
    Executing Create User
    New marking: user created
    Transitions left: Destroy User, Create Note, Destroy Note

    View full-size slide

  149. 150
    $ bin/rhizome
    Traversing user_note net:
    Initial marking: user not created
    Executing Create User
    New marking: user created
    Transitions left: Destroy User, Create Note, Destroy Note
    Executing Destroy User
    New marking: user not created
    Transitions left: Create Note, Destroy Note

    View full-size slide

  150. 151
    $ bin/rhizome
    Traversing user_note net:
    Initial marking: user not created
    Executing Create User
    New marking: user created
    Transitions left: Destroy User, Create Note, Destroy Note
    Executing Destroy User
    New marking: user not created
    Transitions left: Create Note, Destroy Note
    Executing Create User
    New marking: user created
    Transitions left: Create Note, Destroy Note

    View full-size slide

  151. 152
    $ bin/rhizome
    Traversing user_note net:
    Initial marking: user not created
    Executing Create User
    New marking: user created
    Transitions left: Destroy User, Create Note, Destroy Note
    Executing Destroy User
    New marking: user not created
    Transitions left: Create Note, Destroy Note
    Executing Create User
    New marking: user created
    Transitions left: Create Note, Destroy Note
    Executing Create Note
    New marking: user created, note created
    Transitions left: Destroy Note

    View full-size slide

  152. 153
    $ bin/rhizome
    Traversing user_note net:
    Initial marking: user not created
    Executing Create User
    New marking: user created
    Transitions left: Destroy User, Create Note, Destroy Note
    Executing Destroy User
    New marking: user not created
    Transitions left: Create Note, Destroy Note
    Executing Create User
    New marking: user created
    Transitions left: Create Note, Destroy Note
    Executing Create Note
    New marking: user created, note created
    Transitions left: Destroy Note
    Executing Destroy Note
    New marking: user created
    Finished traversing user_note net.

    View full-size slide

  153. 154
    $ bin/rhizome
    Traversing user_note net:
    Initial marking: user not created

    View full-size slide

  154. 155
    $ bin/rhizome
    Traversing user_note net:
    Initial marking: user not created
    Executing Create User
    New marking: user created
    Transitions left: Destroy User, Create Note, Destroy Note

    View full-size slide

  155. 156
    $ bin/rhizome
    Traversing user_note net:
    Initial marking: user not created
    Executing Create User
    New marking: user created
    Transitions left: Destroy User, Create Note, Destroy Note
    Executing Create Note
    New marking: user created, note created
    Transitions left: Destroy User, Destroy Note

    View full-size slide

  156. 157
    $ bin/rhizome
    Traversing user_note net:
    Initial marking: user not created
    Executing Create User
    New marking: user created
    Transitions left: Destroy User, Create Note, Destroy Note
    Executing Create Note
    New marking: user created, note created
    Transitions left: Destroy User, Destroy Note
    Executing Destroy User 

    ActiveRecord ::InvalidForeignKey:
    PG ::ForeignKeyViolation: ERROR: update or delete
    on table "users" violates foreign key constraint
    "fk_rails_83d9817008" on table "notes"
    DETAIL: Key (id)=(1) is still referenced
    from table “notes".

    View full-size slide

  157. RHIZOME
    1. Воспроизводимость тестов с помощью seed
    158

    View full-size slide

  158. RHIZOME
    1. Воспроизводимость тестов с помощью seed
    2. Параллелизация как у любого другого
    фреймворка
    159

    View full-size slide

  159. RHIZOME
    1. Воспроизводимость тестов с помощью seed
    2. Параллелизация как у любого другого
    фреймворка
    3. Фреймворк общего назначения (хоть с
    Selenium)
    160

    View full-size slide

  160. ОБЫЧНЫЙ ТЕСТ (RSPEC)
    161
    RHIZOME

    View full-size slide

  161. ОБЫЧНЫЙ ТЕСТ (RSPEC) RHIZOME
    1000 LoC
    162
    100 LoC

    View full-size slide

  162. ОБЫЧНЫЙ ТЕСТ (RSPEC) RHIZOME
    1000 LoC
    1m
    163
    100 LoC
    1m

    View full-size slide

  163. ТЕСТИРОВАНИЕ НА ОСНОВЕ СЕТЕЙ ПЕТРИ
    1. Тестовое покрытие увеличилось




    164

    View full-size slide

  164. ТЕСТИРОВАНИЕ НА ОСНОВЕ СЕТЕЙ ПЕТРИ
    1. Тестовое покрытие увеличилось
    2. Время выполнения тестов осталось
    прежним


    165

    View full-size slide

  165. ТЕСТИРОВАНИЕ НА ОСНОВЕ СЕТЕЙ ПЕТРИ
    1. Тестовое покрытие увеличилось
    2. Время выполнения тестов осталось
    прежним
    3. Время на написание/поддержку тестов
    сократилось
    166

    View full-size slide

  166. P.S. Что еще?

    View full-size slide

  167. 168
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note

    View full-size slide

  168. 169
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note

    View full-size slide

  169. 170
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note

    View full-size slide

  170. 171
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note

    View full-size slide

  171. 172
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note

    View full-size slide

  172. RESET ARC
    173
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note
    очищает позицию
    после срабатывания

    View full-size slide

  173. INHIBITOR ARC
    174
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note
    разрешает срабатывание
    перехода только если в
    позиции нет меток

    View full-size slide

  174. БЕЗОПАСНЫЕ СЕТИ ПЕТРИ
    175
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note
    не больше одной
    метки в позиции

    View full-size slide

  175. ОБЫЧНЫЕ СЕТИ ПЕТРИ
    176
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note

    View full-size slide

  176. ЦВЕТНЫЕ СЕТИ ПЕТРИ
    177
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note
    метка хранит данные

    View full-size slide

  177. ARC GUARD
    178
    user not created
    user created
    note created
    Create User
    Destroy User
    Create Note
    Destroy Note
    разрешает срабатывание
    перехода только если
    guard = true
    user is admin

    View full-size slide

  178. user not created
    user created
    Create User
    Destroy User
    ИЕРАРХИЧЕСКИЕ СЕТИ ПЕТРИ
    179
    Note note created
    Create Note
    Destroy Note

    View full-size slide

  179. ОТЛОЖЕННЫЕ ПЕРЕХОДЫ
    ВРЕМЕННЫЕ СЕТИ ПЕТРИ
    СТОХАСТИЧЕСКИЕ СЕТИ ПЕТРИ
    АЛГОРИТМЫ ДЛЯ АНАЛИЗА

    180

    View full-size slide

  180. #
    Лёша Родионов
    @p0deje

    View full-size slide