Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

ДЛЯ КОГО? 9

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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


Slide 13

Slide 13 text

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


Slide 14

Slide 14 text

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


Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

22 class User < ApplicationRecord end

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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".

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

GRAPHWALKER 38

Slide 39

Slide 39 text

yEd 39

Slide 40

Slide 40 text

ПРИМЕР 40

Slide 41

Slide 41 text

ПРИМЕР 41

Slide 42

Slide 42 text

ПРИМЕР 42

Slide 43

Slide 43 text

ПРИМЕР 43

Slide 44

Slide 44 text

ПРИМЕР 44

Slide 45

Slide 45 text

ПРИМЕР 45

Slide 46

Slide 46 text

ПРИМЕР 46

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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(); } }

Slide 52

Slide 52 text

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(); } }

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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); } }

Slide 56

Slide 56 text

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); } }

Slide 57

Slide 57 text

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 ++; } }

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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”)); } }

Slide 60

Slide 60 text

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); } }

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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()); } }

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

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

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

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

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

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

Slide 98

Slide 98 text

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

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

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

Slide 101

Slide 101 text

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

Slide 102

Slide 102 text

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

Slide 103

Slide 103 text

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

Slide 104

Slide 104 text

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

Slide 105

Slide 105 text

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

Slide 106

Slide 106 text

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

Slide 107

Slide 107 text

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

Slide 108

Slide 108 text

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

Slide 109

Slide 109 text

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

Slide 110

Slide 110 text

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

Slide 111

Slide 111 text

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

Slide 112

Slide 112 text

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

Slide 113

Slide 113 text

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

Slide 114

Slide 114 text

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

Slide 115

Slide 115 text

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

Slide 116

Slide 116 text

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

Slide 117

Slide 117 text

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

Slide 118

Slide 118 text

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

Slide 119

Slide 119 text

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

Slide 120

Slide 120 text

СОЗДАНИЕ МОДЕЛИ 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" } ] }

Slide 121

Slide 121 text

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

Slide 122

Slide 122 text

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

Slide 123

Slide 123 text

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

Slide 124

Slide 124 text

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

Slide 125

Slide 125 text

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

Slide 126

Slide 126 text

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

Slide 127

Slide 127 text

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

Slide 128

Slide 128 text

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

Slide 129

Slide 129 text

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

Slide 130

Slide 130 text

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

Slide 131

Slide 131 text

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

Slide 132

Slide 132 text

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

Slide 133

Slide 133 text

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

Slide 134

Slide 134 text

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

Slide 135

Slide 135 text

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

Slide 136

Slide 136 text

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

Slide 137

Slide 137 text

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

Slide 138

Slide 138 text

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

Slide 139

Slide 139 text

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

Slide 140

Slide 140 text

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

Slide 141

Slide 141 text

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

Slide 142

Slide 142 text

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

Slide 143

Slide 143 text

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

Slide 144

Slide 144 text

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

Slide 145

Slide 145 text

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

Slide 146

Slide 146 text

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

Slide 147

Slide 147 text

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.

Slide 148

Slide 148 text

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

Slide 149

Slide 149 text

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

Slide 150

Slide 150 text

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

Slide 151

Slide 151 text

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

Slide 152

Slide 152 text

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

Slide 153

Slide 153 text

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.

Slide 154

Slide 154 text

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

Slide 155

Slide 155 text

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

Slide 156

Slide 156 text

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

Slide 157

Slide 157 text

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".

Slide 158

Slide 158 text

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

Slide 159

Slide 159 text

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

Slide 160

Slide 160 text

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

Slide 161

Slide 161 text

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

Slide 162

Slide 162 text

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

Slide 163

Slide 163 text

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

Slide 164

Slide 164 text

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

Slide 165

Slide 165 text

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

Slide 166

Slide 166 text

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

Slide 167

Slide 167 text

P.S. Что еще?

Slide 168

Slide 168 text

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

Slide 169

Slide 169 text

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

Slide 170

Slide 170 text

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

Slide 171

Slide 171 text

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

Slide 172

Slide 172 text

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

Slide 173

Slide 173 text

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

Slide 174

Slide 174 text

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

Slide 175

Slide 175 text

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

Slide 176

Slide 176 text

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

Slide 177

Slide 177 text

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

Slide 178

Slide 178 text

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

Slide 179

Slide 179 text

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

Slide 180

Slide 180 text

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

Slide 181

Slide 181 text

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