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 Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  9. ДЛЯ КОГО?
    9

    View Slide

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

    View Slide

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

    View Slide

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



    View Slide

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


    View Slide

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


    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  22. 22
    class User < ApplicationRecord
    end

    View Slide

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

    View 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 Slide

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

    View 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 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 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 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 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 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 Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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


    36

    View Slide

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

    View Slide

  38. GRAPHWALKER
    38

    View Slide

  39. yEd
    39

    View Slide

  40. ПРИМЕР
    40

    View Slide

  41. ПРИМЕР
    41

    View Slide

  42. ПРИМЕР
    42

    View Slide

  43. ПРИМЕР
    43

    View Slide

  44. ПРИМЕР
    44

    View Slide

  45. ПРИМЕР
    45

    View Slide

  46. ПРИМЕР
    46

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  51. 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 Slide

  52. 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 Slide

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

    View Slide

  54. 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 Slide

  55. 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 Slide

  56. 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 Slide

  57. 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 Slide

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

    View Slide

  59. 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 Slide

  60. 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 Slide

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

    View Slide

  62. 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 Slide

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

    View Slide

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

    View Slide

  65. 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 Slide

  66. 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 Slide

  67. 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 Slide

  68. 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 Slide

  69. 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 Slide

  70. 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 Slide

  71. 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 Slide

  72. 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 Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  112. СЕТЬ ПЕТРИ
    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 Slide

  113. СЕТЬ ПЕТРИ
    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 Slide

  114. СЕТЬ ПЕТРИ
    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 Slide

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

    View Slide

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

    View Slide

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


    117

    View Slide

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

    View Slide

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

    View Slide

  120. СОЗДАНИЕ МОДЕЛИ
    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 Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  125. ЗАГРУЗКА СЕТИ
    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 Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  130. 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 Slide

  131. 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 Slide

  132. 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 Slide

  133. 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 Slide

  134. 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 Slide

  135. 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 Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  144. 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 Slide

  145. 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 Slide

  146. 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 Slide

  147. 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 Slide

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

    View Slide

  149. 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 Slide

  150. 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 Slide

  151. 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 Slide

  152. 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 Slide

  153. 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 Slide

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

    View Slide

  155. 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 Slide

  156. 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 Slide

  157. 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 Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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




    164

    View Slide

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


    165

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    180

    View Slide

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

    View Slide