Similar presentations:
Визуализация тестового покрытия на практике
1.
Визуализация тестовогопокрытия на практике
1
2.
2Храбров
Кирилл
[email protected]
@kirill_khrabrov
3.
3Операционные и логистические
процессы в магазинах
4.
4Галя,
отмена!
4
5.
5Стабильность работы нашего продукта –
критически важная цель для команды
6.
6План
Тестовое покрытие
7.
7План
Тестовое покрытие
Продумываем архитектуру
8.
8План
Тестовое покрытие
Продумываем архитектуру
«Фактический результат» (FR)
«Ожидаемый результат» (ER)
Анализ FR vs ER и его визуализация
9.
9План
Тестовое покрытие
Продумываем архитектуру
Теперь у нас есть
какой-то план и мы
будем его
придерживаться!
«Фактический результат» (FR)
«Ожидаемый результат» (ER)
Анализ FR vs ER и его визуализация
Примеры использования
10.
Тестовоепокрытие
Плотность покрытия
тестами
требований либо исполняемого
кода
10
11.
Тестовоепокрытие
Плотность покрытия
тестами
требований либо исполняемого
кода
Можно выразить в процентном
соотношении покрытия требований к
написанным тестам
11
12.
Тестовоепокрытие
12
13.
Тестовоепокрытие
13
14.
Тестовоепокрытие
14
15.
ТестовоеСобирать информацию
покрытие
по покрытию требований
сложно
15
16.
ТестовоеСобирать информацию
покрытие
по покрытию требований
сложно
Требования все время
меняются
16
17.
ТестовоеСобирать информацию
покрытие
по покрытию требований
сложно
Требования все время
меняются
Зависит от человеческого
фактора
17
18.
ТестовоеСобирать информацию
покрытие
по покрытию требований
сложно
Требования все время
меняются
Зависит от человеческого
фактора
18
Необходимо составлять
матрицы трассировки
требований
19.
ТестовоеСобирать информацию
покрытие
19
по покрытию требований
сложно
Необходимо составлять
матрицы трассировки
требований
Требования все время
меняются
Результаты анализа
не очевидны
Зависит от человеческого
фактора
20.
ТестовоеСобирать информацию
покрытие
20
по покрытию требований
сложно
Необходимо составлять
матрицы трассировки
требований
Требования все время
меняются
Результаты анализа
не очевидны
Зависит от человеческого
фактора
Требования не атомарн
или их нет вообще
21.
ТестовоеСобирать информацию
покрытие
21
по покрытию требований
сложно
Необходимо составлять
матрицы трассировки
требований
Требования все время
меняются
Результаты анализа
не очевидны
Зависит от человеческого
фактора
Требования не атомарн
или их нет вообще
22.
Тестовоепокрытие
А покрыты ли у нас
тестами методы API,
которыми часто
пользуются?
22
23.
Продумываем архитектуруБудет красиво!
23
24.
Продумываем архитектуруДанные об использовании API
24
25.
Продумываем архитектуру25
Данные об использовании API
Данные о покрытых тестами методах A
26.
Продумываем архитектуру26
Данные об использовании API
Данные о покрытых тестами методах A
Парсинг источников данных
27.
Продумываем архитектуру27
Данные об использовании API
Данные о покрытых тестами методах A
Парсинг источников данных
Сохранение результатов парсинга
28.
Продумываем архитектуру28
Данные об использовании API
Данные о покрытых тестами методах A
Парсинг источников данных
Сохранение результатов парсинга
Обработка результатов парсинга
29.
Продумываем архитектуру29
Данные об использовании API
Данные о покрытых тестами методах A
Парсинг источников данных
Сохранение результатов парсинга
Обработка результатов парсинга
Визуализация результатов обработки
30.
Продумываем архитектуру30
Данные об использовании API
Данные о покрытых тестами методах A
Парсинг источников данных
Сохранение результатов парсинга
Обработка результатов парсинга
Визуализация результатов обработки
Вывод результатов визуализации
31.
Тестовоеhttps://github.com/kirillkhrabrov/coverage_analisys
покрытие
31
32.
Продумываем архитектуруER_Data
32
33.
«Ожидаемый результат»ER_Data
Активность пользователя можем
собирать с помощью средств анализа
веб трафика
33
34.
«Ожидаемый результат»ER_Data
Воспроизвести
наиболее
частые
пользовательские сценарии, понять какие
методы АПИ при этом используются и
обратить наше внимание на них
34
35.
«Ожидаемый результат»ER_Data
Активность вызовов клиентом
API методов может собираться
в логах
35
36.
«Ожидаемый результат»ER_Data
36
37.
{«Ожидаемый результат»
"rawResponse": {},
"hits": {
"hits": [
{
"_source": {
"full_path": "/api/departments/",
"status_code": 200,
"event": "REQUEST_SUCCESS",
"level": "info",
"method": "GET",
"time": "2023-10-31T23:26:14.372054Z"
}
},
...
]
}
ER_Data
}
37
38.
{«Ожидаемый результат»
"rawResponse": {},
"hits": {
"hits": [
{
"_source": {
"full_path": "/api/departments/",
"status_code": 200,
"event": "REQUEST_SUCCESS",
"level": "info",
"method": "GET",
"time": "2023-10-31T23:26:14.372054Z"
}
},
...
]
}
ER_Data
}
38
39.
{«Ожидаемый результат»
"rawResponse": {},
"hits": {
"hits": [
{
"_source": {
"full_path": "/api/departments/",
"status_code": 200,
"event": "REQUEST_SUCCESS",
"level": "info",
"method": "GET",
"time": "2023-10-31T23:26:14.372054Z"
}
},
...
]
}
ER_Data
}
39
40.
{«Ожидаемый результат»
"rawResponse": {},
"hits": {
"hits": [
{
"_source": {
"full_path": "/api/departments/",
"status_code": 200,
"event": "REQUEST_SUCCESS",
"level": "info",
"method": "GET",
"time": "2023-10-31T23:26:14.372054Z"
}
},
...
]
}
ER_Data
}
40
41.
Продумываем архитектуруER_Data
FR_Data
41
42.
«Фактический результат»FR_Data
pytest --alluredir=$ALLURE_RESULTS
42
43.
«Ожидаемый результат»FR_Data
43
44.
«Ожидаемый результат»FR_Data
UUID4_log_fact_result.json
UUID4_attachment.txt
UUID4_step_fact_result.json
44
45.
«Ожидаемый результат»UUID4_log_fact_result.json
FR_Data
{
"name": "Test case ID 0e1f67c5",
"status": "passed",
"steps": [
{
"name": "Call API method POST /api/basket-local-inventory/items/",
"status": "passed"
},
...
],
"attachments": [
{
"name": "log",
"source": "2426f438-688d-4c9c-945a-0c3b97650a8a_attachment.txt",
"type": "text/plain"
}
],
"uuid": "22842bc8-4947-44c3-8025-4fd4b3dbfc1f"
}
45
46.
«Ожидаемый результат»UUID4_log_fact_result.json
FR_Data
{
"name": "Test case ID 0e1f67c5",
"status": "passed",
"steps": [
{
"name": "Call API method POST /api/basket-local-inventory/items/",
"status": "passed"
},
...
],
"attachments": [
{
"name": "log",
"source": "2426f438-688d-4c9c-945a-0c3b97650a8a_attachment.txt",
"type": "text/plain"
}
],
"uuid": "22842bc8-4947-44c3-8025-4fd4b3dbfc1f"
}
46
47.
«Ожидаемый результат»FR_Data
47
UUID4_attachment.txt
2023-10-30T23:26:14.145055Z:[INFO] PATCH /api/v1/items/a6a9d4a2-5bc2-439d-8708690baec6f138/item_stacks/ Response status code: 204
2023-10-31T23:26:15.227335Z:[INFO] GET /api-web/employees/ Response status
code: 200
2023-10-31T23:26:15.211632Z:[INFO] GET /api-web/info-messages-forrecipients/?ordering=-status Response status code: 200
2023-10-31T23:26:15.178278Z:[INFO] GET /api-web/info-messages/?ordering=title
Response status code: 200
2023-10-31T23:26:15.207456Z:[INFO] GET
/api/v4/tasks/?open_tasks=True&store_tasks=true Response status code: 200
2023-10-31T23:26:15.201468Z:[INFO] GET /api-web/info-messages/?ordering=title
Response status code: 200
2023-10-31T23:26:15.200463Z:[INFO] DELETE /api-web/info-messages/39db433d-4db8492e-946a-6f343c28a553/ Response status code: 204
48.
«Ожидаемый результат»FR_Data
48
UUID4_attachment.txt
2023-10-30T23:26:14.145055Z:[INFO] PATCH /api/v1/items/a6a9d4a2-5bc2-439d-8708690baec6f138/item_stacks/ Response status code: 204
2023-10-31T23:26:15.227335Z:[INFO] GET /api-web/employees/ Response status
code: 200
2023-10-31T23:26:15.211632Z:[INFO] GET /api-web/info-messages-forrecipients/?ordering=-status Response status code: 200
2023-10-31T23:26:15.178278Z:[INFO] GET /api-web/info-messages/?ordering=title
Response status code: 200
2023-10-31T23:26:15.207456Z:[INFO] GET
/api/v4/tasks/?open_tasks=True&store_tasks=true Response status code: 200
2023-10-31T23:26:15.201468Z:[INFO] GET /api-web/info-messages/?ordering=title
Response status code: 200
2023-10-31T23:26:15.200463Z:[INFO] DELETE /api-web/info-messages/39db433d-4db8492e-946a-6f343c28a553/ Response status code: 204
49.
«Ожидаемый результат»FR_Data
UUID4_step_fact_result.json
{
"name": "Test case ID f43581bb",
"status": "passed",
"steps": [
{
"name": "Call API method GET /api/tasks/",
"status": "passed",
"steps": [
{
"name": "Check status code 200",
"status": "passed"
}
]
},
...
],
"uuid": "f5735865-a702-46e1-973b-e84662d9806f"
}
49
50.
«Ожидаемый результат»FR_Data
UUID4_step_fact_result.json
{
"name": "Test case ID f43581bb",
"status": "passed",
"steps": [
{
"name": "Call API method GET /api/tasks/",
"status": "passed",
"steps": [
{
"name": "Check status code 200",
"status": "passed"
}
]
},
...
],
"uuid": "f5735865-a702-46e1-973b-e84662d9806f"
}
50
51.
Продумываем архитектуруER_Data
DataParser
FR_Data
51
52.
DataParserDataParser
Методы чтения источников
Методы обработки данных в
источниках
Методы сохранения информации об
API методах
52
53.
DataParserDataParser
class DataParser:
def __init__(...):
pass
def _get_elk_response(..) -> dict:
pass
def __get_files_from_dir(...):
pass
def __read_file(...) -> str or dict:
pass
def __form_attachments_files_list_from_file(...) -> list:
pass
...
53
54.
DataParserDataParser
54
55.
DataParserDataParser
55
56.
DataParserDataParser
56
57.
57PATTERN_HTTP_REQ = r'(GET|POST|PUT|DELETE|PATCH).*(\/api\S*)'
re.findall(PATTERN_HTTP_REQ, file_content)
58.
58http_path = '/api-web/stores/c0ff8864-e29f-41b1-867d-a741b76be6ce/'
59.
59PATTERN_UUID4 = r'[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}'
http_after_masked_uuid = re.sub(
DataParser.PATTERN_UUID4,
'{id}',
http_path
)
60.
60http_after_masked_uuid = '/api-web/group-tasks/{id}/'
61.
61http_path = '/api-web/stores/B15444/dashboards/'
62.
62PATTERN_OBJ_ID = r'\/[^v]?\d{1,5}\D?\/'
http_after_masked_id = re.sub(
DataParser.PATTERN_OBJ_ID,
'{obj_id}',
http_path
)
63.
63http_after_masked_id = '/api-web/stores/{obj_id}/dashboards/'
64.
64GET /api-web/stores/B15444/dashboards/c0ff8864-e29f-41b1-867da741b76be6ce/?created_from=21-09-2023&created_to=22-09-2023
65.
65GET /api-web/stores/B15444/dashboards/{id}/?created_from=21-092023&created_to=22-09-2023
66.
66GET /api-web/stores/{obj_id}/dashboards/{id}/?created_from=21-092023&created_to=22-09-2023
67.
67GET /api-web/stores/{obj_id}/dashboards/{id}/?created_from=21-092023&created_to=22-09-2023
http_method = 'GET'
http_path = '/api-web/stores/{obj_id}/dashboards/{id}/'
query_params = [
'created_from=21-09-2023',
'created_to=22-09-2023'
]
68.
Продумываем архитектуруER_Data
DataFrame
DataFrame
DataFrame
DataParser
DataFrame
DataFrame
FR_Data
DataFrame
68
69.
69DataFrame
DataFrame
API метод
Перечень query параметров
Статус test run
Response status codes
Критичность
Частота вызовов
70.
70DataFrame
DataFrame
class DataFrame:
def __init__(self, api_method: str, test_status=None,
query_list=[], status_code=[]):
"""
Class for collecting info about single API Method
"""
self.api_method = api_method
self.query_list = query_list
self.passed = 1 if test_status == "passed" else 0
self.failed = 1 if test_status == "failed" else 0
self.broken = 1 if test_status == "broken" else 0
self.skipped = 1 if test_status == "skipped" else 0
self.status_codes = status_code
self.criticality = 0
self.frequency = 1
71.
71DataFrame
DataFrame
72.
Продумываем архитектуруER_Data
DataFrame
DataFrame
DataSet
DataFrame
DataParser
DataFrame
DataFrame
FR_Data
DataFrame
DataSet
72
73.
73DataSet
DataSet
Массив DataFrame’ов
Таблица критичности
Методы сохранения DataFrame’ов
74.
74DataSet
DataSet
class DataSet:
def __init__(...):
pass
def _increase_status(self, data_frame: DataFrame):
pass
def _increase_frequency(self, data_frame: DataFrame):
pass
def _append_query_params(self, data_frame: DataFrame):
pass
def append_data_frame(self, data_frame: DataFrame):
pass
75.
75DataSet
DataSet
def append_data_frame(self, data_frame: DataFrame):
if data_frame.api_method not in [
data_frame.api_method for data_frame in self.result_data_set
]:
self.result_data_set.append(data_frame)
self._increase_frequency(data_frame=data_frame)
self._increase_status(data_frame=data_frame)
self._append_query_params(data_frame=data_frame)
self._append_status_codes(data_frame=data_frame)
self._set_criticality(data_frame=data_frame)
76.
76DataSet
DataSet
def _increase_frequency(self, data_frame: DataFrame):
for saved_data_frame in self.result_data_set:
if saved_data_frame.api_method == data_frame.api_method:
saved_data_frame.frequency += 1
self.logger.debug(f"increased frequency for
{saved_data_frame.api_method}")
77.
Продумываем архитектуруDataSet
77
78.
Продумываем архитектуруER_Data
DataFrame
DataFrame
DataSet
DataFrame
Coverage
Analysis
DataParser
DataFrame
DataFrame
FR_Data
DataFrame
DataSet
78
79.
79CoverageAnalysis
Coverage
Analysis
Методы обработки DataSet’ов
Методы получения
результирующих массивов
данных
80.
80ER
CoverageAnalysis
Непротестированные
используемые API методы
FR
Протестированные
неиспользуемые API
методы
Протестированные
используемые API
методы
81.
81CoverageAnalysis
Coverage
Analysis
class CoverageAnalisys:
def __init__(...):
pass
def get_untested_status_codes_params(...) -> list:
pass
def get_untested_query_params(...) -> list:
pass
def get_untested_used_api_methods(...) -> list:
pass
def get_tested_api_methods(...) -> list:
pass
def get_fact_stat(...) -> list:
pass
82.
82CoverageAnalysis
Coverage
Analysis
def get_untested_used_api_methods(
self,
expected_result_lst: list = None,
fact_result_lst: list = None
) -> list:
expected_list = expected_result_lst if expected_result_lst else
self.expected_data_set_result
fact_list = fact_result_lst if fact_result_lst else
self.fact_data_set_result
return list(filter(
lambda data_frame: data_frame.api_method not in [
data_frame.api_method for data_frame in fact_list
],
expected_list
))
83.
83CoverageAnalysis
Coverage
Analysis
top_50_expected_sorted_by_freq =
coverage_analyzer.get_top_n_api_methods(
data_set=expected_data_set,
top_n=50
)
untested_from_top_50_api_methods_freq =
coverage_analyzer.get_untested_used_api_methods(
expected_result_lst=top_50_expected_sorted_by_freq
)
84.
84CoverageAnalysis
Coverage
Analysis
85.
Продумываем архитектуруER_Data
DataFrame
DataFrame
DataSet
DataFrame
Coverage
Analysis
DataParser
DataFrame
DataFrame
FR_Data
DataFrame
DataSet
Coverage
Visualize
85
86.
86CoverageVisualize
Coverage
Visualize
Pandas
Python библиотека для
анализа данных
87.
87CoverageVisualize
Coverage
Visualize
Pandas
Python библиотека для
анализа данных
Series
Data
Frame
Series
Series
Series
Одномерный
массив
c
набором
ассоциированных
меток
(индексов),
вдоль
каждого элемента из списка.
DataFrame
является
табличной
структурой
данных, столбцы, строки объекты Series
88.
88CoverageVisualize
Coverage
Visualize
Варианты
отображения
89.
89CoverageVisualize
Coverage
Visualize
90.
90CoverageVisualize
Coverage
Visualize
Таблица
Круговая диаграмма
Столбчатая гистограмма
91.
91CoverageVisualize
Coverage
Visualize
Процесс Конвертации в pandas’
DataFrame
Методы визуализации результатов
обработки DataSet’ов
92.
92CoverageVisualize
Coverage
Visualize
class PData:
def __init__(self, data: list, columns: list, sort_by: str = None):
out_data = []
for data_frame in data:
data_part = [
getattr(data_frame, attr_name) for attr_name in columns
]
out_data.append(data_part)
self.data = out_data
self.columns = columns
self.df = pd.DataFrame(self.data, columns=self.columns)
if sort_by:
self.df.sort_values(by=sort_by)
93.
93CoverageVisualize
Coverage
Visualize
class CoverageVisualize:
"""
Class for building tables, hists, diagrams
and saving it to pandas_results dir
"""
@staticmethod
def build_info_table(...):
pass
@staticmethod
def build_info_gist_on_code_coverage(...):
pass
@staticmethod
def build_info_barh_on_code_coverage(...):
pass
94.
94Знаете, я и сам своего
рода визуализатор
95.
ПрименениеТоп 50 используемых API методов, отсортированных по
частоте
Топ 50 используемых API методов, отсортированных по
критичности
95
96.
ПрименениеТоп 50 используемых API методов, отсортированных по
частоте
Топ 50 используемых API методов, отсортированных по
критичности
Протестированные API методы, отсортированные по частоте
Протестированные API методы, отсортированные по
критичности
96
97.
Применение97
Топ 50 используемых API методов, отсортированных по
частоте
Топ 50 используемых API методов, отсортированных по
критичности
Протестированные API методы, отсортированные по частоте
Протестированные API методы, отсортированные по
критичности
Не покрытые тестами query параметры из Топ 50 критичных
используемых
методовstatus codes из Топ 50 критичных используемых
Не покрытые тестами
методов
98.
Применение98
Топ 50 используемых API методов, отсортированных по
частоте
Топ 50 используемых API методов, отсортированных по
критичности
Протестированные API методы, отсортированные по частоте
Протестированные API методы, отсортированные по
критичности
Не покрытые тестами query параметры из Топ 50 критичных
используемых
методовstatus codes из Топ 50 критичных используемых
Не покрытые тестами
методов
Не протестированные критичные API методы из ТОП 50
Не протестированные частые API методы из ТОП 50
99.
Применение99
Топ 50 используемых API методов, отсортированных по
частоте
Топ 50 используемых API методов, отсортированных по
критичности
Протестированные API методы, отсортированные по частоте
Протестированные API методы, отсортированные по
критичности
Не покрытые тестами query параметры из Топ 50 критичных
используемых
методовstatus codes из Топ 50 критичных используемых
Не покрытые тестами
методов
Не протестированные критичные API методы из ТОП 50
Не протестированные частые API методы из ТОП 50
Структура прогона тестов самых популярных API методов
Диаграмма покрытия API тестами
100.
ПрименениеТоп 50 используемых API методов,
отсортированных по частоте
top_50_expected_sorted_by_freq = coverage_analyzer.get_top_n_api_methods(
data_set=expected_data_set,
top_n=50
)
top_50_expected_sorted_by_freq_df = PData(
data=top_50_expected_sorted_by_freq,
columns=["api_method", "frequency"],
sort_by='frequency'
).df
CoverageVisualize.build_info_table(
df=top_50_expected_sorted_by_freq_df,
title='Топ 50 используемых API методов, отсортированных по частоте'
)
100
101.
ПрименениеТоп 50 используемых API методов,
отсортированных по частоте
top_50_expected_sorted_by_freq = coverage_analyzer.get_top_n_api_methods(
data_set=expected_data_set,
top_n=50
)
top_50_expected_sorted_by_freq_df = PData(
data=top_50_expected_sorted_by_freq,
columns=["api_method", "frequency"],
sort_by='frequency'
).df
CoverageVisualize.build_info_table(
df=top_50_expected_sorted_by_freq_df,
title='Топ 50 используемых API методов, отсортированных по частоте'
)
101
102.
ПрименениеТоп 50 используемых API методов,
отсортированных по частоте
top_50_expected_sorted_by_freq = coverage_analyzer.get_top_n_api_methods(
data_set=expected_data_set,
top_n=50
)
top_50_expected_sorted_by_freq_df = PData(
data=top_50_expected_sorted_by_freq,
columns=["api_method", "frequency"],
sort_by='frequency'
).df
CoverageVisualize.build_info_table(
df=top_50_expected_sorted_by_freq_df,
title='Топ 50 используемых API методов, отсортированных по частоте'
)
102
103.
Применение103
Топ 50 используемых API методов,
отсортированных по частоте
api_method
frequency
GET /api-web/info-messages/
577
GET /api/v2/basket-local-inventory/
557
GET /api/v2/basket/
403
GET /api/seals/actions/{id}/
392
DELETE /api-web/info-messages/{id}/
336
GET /api-web/info-messages-for-recipients/
301
GET /api/items/{id}/
292
PATCH /api/v1/items/{id}/item_stacks/
291
GET /api-web/group-poll-tasks/{id}/
286
GET /api-web/group-poll-tasks/{id}/tasks/
284
GET /api-web/group-tasks/{id}/
284
104.
ПрименениеТоп 50 используемых API методов,
отсортированных по критичности
top_50_expected_sorted_by_crit = coverage_analyzer.get_top_n_api_methods(
data_set=expected_data_set,
top_n=50,
sort_by='criticality'
)
top_50_expected_sorted_by_crit_df = PData(
data=top_50_expected_sorted_by_crit,
columns=["api_method", "criticality"],
sort_by='criticality'
).df
CoverageVisualize.build_info_table(
df=top_50_expected_sorted_by_crit_df,
title='Топ 50 используемых API методов, отсортированных по критичности'
)
104
105.
Применение105
Топ 50 используемых API методов,
отсортированных по критичности
api_method
criticality
GET /api/config/
1.0
PATCH /api/config/
1.0
GET /api/v5/main/
1.0
POST /api/v1/login/
1.0
PATCH /api/employees/{obj_id}/
0.9
GET /api/employees/{obj_id}/
0.9
GET /api/employees/
0.9
PATCH /api/tasks/{id}/state/
0.8
GET /api/tasks/{id}/
0.8
GET /api/v4/tasks/{id}/
0.8
POST /api/tasks/{id}/submit-poll-task-answers/
0.8
106.
ПрименениеНе покрытые тестами query
параметры из Топ 50 критичных
используемых методов
untested_queries_from_top_50_expected =
coverage_analyzer.get_untested_query_params(
expected_result_lst=top_50_expected_sorted_by_crit,
fact_result_lst=fact_sorted_by_crit
)
untested_queries_from_top_50_expected_df = PData(
data=untested_queries_from_top_50_expected,
columns=["api_method", "query_list", "criticality"],
sort_by='criticality'
).df
CoverageVisualize.build_info_table(
df=untested_queries_from_top_50_expected_df,
title='Не покрытые тестами query параметры из Топ 50 критичных
используемых методов'
)
106
107.
ПрименениеНе покрытые тестами query
параметры из Топ 50 критичных
используемых методов
untested_queries_from_top_50_expected =
coverage_analyzer.get_untested_query_params(
expected_result_lst=top_50_expected_sorted_by_crit,
fact_result_lst=fact_sorted_by_crit
)
untested_queries_from_top_50_expected_df = PData(
data=untested_queries_from_top_50_expected,
columns=["api_method", "query_list", "criticality"],
sort_by='criticality'
).df
CoverageVisualize.build_info_table(
df=untested_queries_from_top_50_expected_df,
title='Не покрытые тестами query параметры из Топ 50 критичных
используемых методов'
)
107
108.
ПрименениеНе покрытые тестами query
параметры из Топ 50 критичных
используемых методов
untested_queries_from_top_50_expected =
coverage_analyzer.get_untested_query_params(
expected_result_lst=top_50_expected_sorted_by_crit,
fact_result_lst=fact_sorted_by_crit
)
untested_queries_from_top_50_expected_df = PData(
data=untested_queries_from_top_50_expected,
columns=["api_method", "query_list", "criticality"],
sort_by='criticality'
).df
CoverageVisualize.build_info_table(
df=untested_queries_from_top_50_expected_df,
title='Не покрытые тестами query параметры из Топ 50 критичных
используемых методов'
)
108
109.
ПрименениеНе покрытые тестами query
параметры из Топ 50 критичных
используемых методов
untested_queries_from_top_50_expected =
coverage_analyzer.get_untested_query_params(
expected_result_lst=top_50_expected_sorted_by_crit,
fact_result_lst=fact_sorted_by_crit
)
untested_queries_from_top_50_expected_df = PData(
data=untested_queries_from_top_50_expected,
columns=["api_method", "query_list", "criticality"],
sort_by='criticality'
).df
CoverageVisualize.build_info_table(
df=untested_queries_from_top_50_expected_df,
title='Не покрытые тестами query параметры из Топ 50 критичных
используемых методов'
)
109
110.
Применение110
Не покрытые тестами query
параметры из Топ 50 критичных
используемых методов
api_method
query_list
criticality
GET /api-web/info-messages/
['ordering=-total_recipients_number',
'search=name’, 'ordering=title',
'ordering=total_recipients_number',
'ordering=created_at', 'ordering=-title']
0.5
GET /api/items/
['plu=3215907', 'plu=1048', 'plu=5680',
'plu=2046261', 'plu=4059501']
0.0
111.
ПрименениеНе покрытые тестами status codes
из
Топ
50
критичных
используемых методов
untested_codes_from_top_50_expected =
coverage_analyzer.get_untested_status_codes_params(
expected_result_lst=top_50_expected_sorted_by_crit,
fact_result_lst=fact_sorted_by_crit
)
untested_codes_from_top_50_expected_df = PData(
data=untested_codes_from_top_50_expected,
columns=["api_method", "status_codes", "criticality"],
sort_by='criticality'
).df
CoverageVisualize.build_info_table(
df=untested_codes_from_top_50_expected_df,
title='Не покрытые тестами status codes из Топ 50 критичных
используемых методов'
)
111
112.
ПрименениеНе покрытые тестами status codes
из
Топ
50
критичных
используемых методов
untested_codes_from_top_50_expected =
coverage_analyzer.get_untested_status_codes_params(
expected_result_lst=top_50_expected_sorted_by_crit,
fact_result_lst=fact_sorted_by_crit
)
untested_codes_from_top_50_expected_df = PData(
data=untested_codes_from_top_50_expected,
columns=["api_method", "status_codes", "criticality"],
sort_by='criticality'
).df
CoverageVisualize.build_info_table(
df=untested_codes_from_top_50_expected_df,
title='Не покрытые тестами status codes из Топ 50 критичных
используемых методов'
)
112
113.
ПрименениеНе покрытые тестами status codes из
Топ 50 критичных используемых
методов
api_method
113
status_codes
criticality
GET /api/stores/{obj_id}/markdown-items/
[503]
0.9
GET /api/employees/{obj_id}/
[500]
0.9
PATCH /api/employees/{obj_id}/
[404]
0.9
[400, 401]
0.9
[400, 401, 404]
0.8
GET /api/v4/tasks/{id}/
[500, 503]
0.8
GET /api/tasks/{id}/
[500]
0.8
[400, 404]
0.8
DELETE /api/basket-placing/{id}/
[500]
0.7
PATCH /api/basket-placing/
[401]
0.7
POST /api/v2/basket/items/
[400]
0.7
DELETE /api/stores/{obj_id}/markdown-items/{id}/
PATCH /api/tasks/{id}/state/
POST /api/tasks/{id}/submit-poll-task-answers/
114.
ПрименениеНе
протестированные
критичные API методы из ТОП
50
untested_from_top_50_api_methods_crit =
coverage_analyzer.get_untested_used_api_methods(
expected_result_lst=top_50_expected_sorted_by_crit
)
untested_from_top_50_api_methods_crit_df = PData(
data=untested_from_top_50_api_methods_crit,
columns=["api_method", "criticality"],
sort_by='criticality'
).df
CoverageVisualize.build_info_table(
df=untested_from_top_50_api_methods_crit_df,
title='Не протестированные критичные API методы из ТОП 50'
)
114
115.
ПрименениеНе
протестированные
критичные API методы из ТОП
50
api_method
115
criticality
GET /api/employees/delegate/
0.9
GET /api/stores/{obj_id}/markdown-filters/
0.9
PATCH /api/employees/set_default_clear/
0.9
POST /api/stores/{obj_id}/markdown-items/{id}/markdown_created/
0.9
GET /api/v5/tasks/
0.8
PATCH /api/tasks/{id}/items/
0.8
GET /api/basket-placing/
0.7
POST /api/basket-placing/
0.7
POST /api/basket-local-inventory/update_and_get_all_items/
0.7
GET /api-web/statistics/
0.5
116.
ПрименениеСтруктура прогона тестов
самых
популярных
API
методов
top_15_fact_stat = coverage_analyzer.get_fact_stat(
expected_result_lst=coverage_analyzer.get_top_n_api_methods(fact_data_set, 15)
)
stats_for_tested_from_top_df = PData(
data=coverage_analyzer.get_fact_stat(top_15_fact_stat),
columns=["api_method", "skipped", "broken", "passed", "failed", "frequency"],
sort_by='frequency'
).df
barh_stats_for_tested_from_top = CoverageVisualize.build_info_barh_on_code_coverage(
df=stats_for_tested_from_top_df,
title='Структура прогона тестов самых популярных API методов',
xlabel='Количество вызовов в тестах',
ylabel="Методы API",
x="api_method",
y=["broken", "skipped", "passed", "failed"])
116
117.
ПрименениеСтруктура прогона тестов
самых
популярных
API
методов
117
118.
ПрименениеДиаграмма
тестами
покрытия
API
all_untested = coverage_analyzer.get_untested_used_api_methods()
all_tested = coverage_analyzer.get_tested_api_methods()
gist = CoverageVisualize.build_info_gist_on_code_coverage(
values=[len(all_tested), len(all_untested)],
labels=["Покрыто", "Не Покрыто"],
title='Диаграмма покрытия API тестами'
)
118
119.
ПрименениеДиаграмма
тестами
покрытия
API
all_untested = coverage_analyzer.get_untested_used_api_methods()
all_tested = coverage_analyzer.get_tested_api_methods()
gist = CoverageVisualize.build_info_gist_on_code_coverage(
values=[len(all_tested), len(all_untested)],
labels=["Покрыто", "Не Покрыто"],
title='Диаграмма покрытия API тестами'
)
119
120.
ПрименениеДиаграмма
тестами
покрытия
API
all_untested = coverage_analyzer.get_untested_used_api_methods()
all_tested = coverage_analyzer.get_tested_api_methods()
gist = CoverageVisualize.build_info_gist_on_code_coverage(
values=[len(all_tested), len(all_untested)],
labels=["Покрыто", "Не Покрыто"],
title='Диаграмма покрытия API тестами'
)
120
121.
ПрименениеДиаграмма
тестами
покрытия
API
33,3%
Не покрыто
66,7%
Покрыто
121
122.
Как выдать результатplt.savefig(os.path.abspath('pandas_results') + f'/{kwargs["title"]}.pdf')
122
123.
Как выдать результатstages:
- linting
- build
- run-tests
- coverage
coverage_vis:
stage: coverage
script:
- ls
- mkdir pandas_results
- python coverage_visualizer.py
artifacts:
paths:
- ./pandas_results/*
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" ||
$CI_PIPELINE_SOURCE == "push"
when: manual
- when: always
123
124.
Как выдать результатstages:
- linting
- build
- run-tests
- coverage
coverage_vis:
stage: coverage
script:
- ls
- mkdir pandas_results
- python coverage_visualizer.py
artifacts:
paths:
- ./pandas_results/*
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" ||
$CI_PIPELINE_SOURCE == "push"
when: manual
- when: always
124
125.
Как выдать результатstages:
- linting
- build
- run-tests
- coverage
coverage_vis:
stage: coverage
script:
- ls
- mkdir pandas_results
- python coverage_visualizer.py
artifacts:
paths:
- ./pandas_results/*
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" ||
$CI_PIPELINE_SOURCE == "push"
when: manual
- when: always
125
126.
Как выдать результатstages:
- linting
- build
- run-tests
- coverage
coverage_vis:
stage: coverage
script:
- ls
- mkdir pandas_results
- python coverage_visualizer.py
artifacts:
paths:
- ./pandas_results/*
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" ||
$CI_PIPELINE_SOURCE == "push"
when: manual
- when: always
126
127.
Как выдать результатstages:
- linting
- build
- run-tests
- coverage
coverage_vis:
stage: coverage
script:
- ls
- mkdir pandas_results
- python coverage_visualizer.py
artifacts:
paths:
- ./pandas_results/*
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" ||
$CI_PIPELINE_SOURCE == "push"
when: manual
- when: always
127
128.
Анализ ER vs FR и его визуализация128
129.
ИтогиПришло время
подводить итоги
129
130.
ИтогиПолучить информацию о пользовательской
активности использования API
130
131.
ИтогиПолучить информацию о пользовательской
активности использования API
Быстро получить информацию о
соотношении покрытых / не покрытых авто
тестами API методах
131
132.
ИтогиПолучить информацию о пользовательской
активности использования API
Быстро получить информацию о
соотношении покрытых / не покрытых авто
тестами API методах
Сконцентрироваться на покрытии реально
используемых API методах
132
133.
ИтогиПолучить информацию о пользовательской
активности использования API
Быстро получить информацию о
соотношении покрытых / не покрытых авто
тестами API методах
Сконцентрироваться на покрытии реально
используемых API методах
Сократить количество не покрытых тестами API
методов
133