1
|
|
|
# -*- coding: utf-8 -*- |
2
|
|
|
# pylint: disable=invalid-name, too-many-ancestors |
3
|
|
|
|
4
|
|
|
from datetime import datetime |
5
|
|
|
|
6
|
|
|
from tcms.core.helpers.comments import add_comment |
7
|
|
|
from tcms.testcases.models import BugSystem |
8
|
|
|
from tcms.testruns.data import TestExecutionDataMixin |
9
|
|
|
from tcms.testruns.data import get_run_bug_ids |
10
|
|
|
from tcms.tests import BaseCaseRun |
11
|
|
|
from tcms.tests import BasePlanCase |
12
|
|
|
from tcms.tests.factories import TestExecutionFactory |
13
|
|
|
from tcms.tests.factories import TestExecutionStatus |
14
|
|
|
from tcms.tests.factories import TestRunFactory |
15
|
|
|
|
16
|
|
|
|
17
|
|
|
class TestGetCaseRunsStatsByStatusFromEmptyTestRun(BasePlanCase): |
18
|
|
|
|
19
|
|
|
@classmethod |
20
|
|
|
def setUpTestData(cls): |
21
|
|
|
super(TestGetCaseRunsStatsByStatusFromEmptyTestRun, cls).setUpTestData() |
22
|
|
|
|
23
|
|
|
cls.empty_test_run = TestRunFactory(manager=cls.tester, default_tester=cls.tester, |
24
|
|
|
plan=cls.plan) |
25
|
|
|
|
26
|
|
|
cls.statuss = TestExecutionStatus.objects.all().order_by('pk') |
27
|
|
|
|
28
|
|
|
def test_get_from_empty_case_runs(self): |
29
|
|
|
data = self.empty_test_run.stats_executions_status(self.statuss) |
30
|
|
|
|
31
|
|
|
subtotal = dict((status.pk, [0, status]) |
32
|
|
|
for status in self.statuss) |
33
|
|
|
|
34
|
|
|
self.assertEqual(subtotal, data.StatusSubtotal) |
35
|
|
|
self.assertEqual(0, data.CaseRunsTotalCount) |
36
|
|
|
self.assertEqual(.0, data.CompletedPercentage) |
37
|
|
|
self.assertEqual(.0, data.FailurePercentage) |
38
|
|
|
|
39
|
|
|
|
40
|
|
|
class TestGetCaseRunsStatsByStatus(BasePlanCase): |
41
|
|
|
|
42
|
|
|
@classmethod |
43
|
|
|
def setUpTestData(cls): |
44
|
|
|
super(TestGetCaseRunsStatsByStatus, cls).setUpTestData() |
45
|
|
|
|
46
|
|
|
cls.statuss = TestExecutionStatus.objects.all().order_by('pk') |
47
|
|
|
|
48
|
|
|
cls.status_idle = TestExecutionStatus.objects.get(name='IDLE') |
49
|
|
|
cls.status_failed = TestExecutionStatus.objects.get(name='FAILED') |
50
|
|
|
cls.status_waived = TestExecutionStatus.objects.get(name='WAIVED') |
51
|
|
|
|
52
|
|
|
cls.test_run = TestRunFactory(product_version=cls.version, plan=cls.plan, |
53
|
|
|
manager=cls.tester, default_tester=cls.tester) |
54
|
|
|
|
55
|
|
|
for case, status in ((cls.case_1, cls.status_idle), |
56
|
|
|
(cls.case_2, cls.status_failed), |
57
|
|
|
(cls.case_3, cls.status_failed), |
58
|
|
|
(cls.case_4, cls.status_waived), |
59
|
|
|
(cls.case_5, cls.status_waived), |
60
|
|
|
(cls.case_6, cls.status_waived)): |
61
|
|
|
TestExecutionFactory(assignee=cls.tester, tested_by=cls.tester, |
62
|
|
|
run=cls.test_run, case=case, status=status) |
63
|
|
|
|
64
|
|
|
def test_get_stats(self): |
65
|
|
|
data = self.test_run.stats_executions_status(self.statuss) |
66
|
|
|
|
67
|
|
|
subtotal = dict((status.pk, [0, status]) |
68
|
|
|
for status in self.statuss) |
69
|
|
|
subtotal[self.status_idle.pk][0] = 1 |
70
|
|
|
subtotal[self.status_failed.pk][0] = 2 |
71
|
|
|
subtotal[self.status_waived.pk][0] = 3 |
72
|
|
|
|
73
|
|
|
expected_completed_percentage = 5.0 * 100 / 6 |
74
|
|
|
expected_failure_percentage = 2.0 * 100 / 6 |
75
|
|
|
|
76
|
|
|
self.assertEqual(subtotal, data.StatusSubtotal) |
77
|
|
|
self.assertEqual(6, data.CaseRunsTotalCount) |
78
|
|
|
self.assertEqual(expected_completed_percentage, data.CompletedPercentage) |
79
|
|
|
self.assertEqual(expected_failure_percentage, data.FailurePercentage) |
80
|
|
|
|
81
|
|
|
|
82
|
|
|
class TestGetRunBugIDs(BaseCaseRun): |
83
|
|
|
"""Test get_run_bug_ids""" |
84
|
|
|
|
85
|
|
|
@classmethod |
86
|
|
|
def setUpTestData(cls): |
87
|
|
|
super(TestGetRunBugIDs, cls).setUpTestData() |
88
|
|
|
|
89
|
|
|
cls.bugzilla = BugSystem.objects.get(name='Bugzilla') |
90
|
|
|
|
91
|
|
|
cls.execution_1.add_bug('123456', bug_system_id=cls.bugzilla.pk) |
92
|
|
|
cls.execution_1.add_bug('100000', bug_system_id=cls.bugzilla.pk) |
93
|
|
|
cls.execution_1.add_bug('100001', bug_system_id=cls.bugzilla.pk) |
94
|
|
|
cls.execution_2.add_bug('100001', bug_system_id=cls.bugzilla.pk) |
95
|
|
|
|
96
|
|
|
def test_get_bug_ids_when_no_bug_is_added(self): |
97
|
|
|
bug_ids = get_run_bug_ids(self.test_run_1.pk) |
98
|
|
|
self.assertEqual(0, len(bug_ids)) |
99
|
|
|
|
100
|
|
|
def test_get_bug_ids(self): |
101
|
|
|
bug_ids = get_run_bug_ids(self.test_run.pk) |
102
|
|
|
|
103
|
|
|
self.assertEqual(3, len(bug_ids)) |
104
|
|
|
|
105
|
|
|
# Convert result to list in order to compare more easily |
106
|
|
|
received_bugs = [] |
107
|
|
|
for bug in bug_ids: |
108
|
|
|
received_bugs.append(bug['bug_system__url_reg_exp'] % bug['bug_id']) |
109
|
|
|
|
110
|
|
|
self.assertIn(self.bugzilla.url_reg_exp % '123456', received_bugs) |
111
|
|
|
self.assertIn(self.bugzilla.url_reg_exp % '100000', received_bugs) |
112
|
|
|
self.assertIn(self.bugzilla.url_reg_exp % '100001', received_bugs) |
113
|
|
|
|
114
|
|
|
|
115
|
|
|
class TestGetExecutionBugs(BaseCaseRun): |
116
|
|
|
"""Test TestExecutionDataMixin.get_caseruns_bugs""" |
117
|
|
|
|
118
|
|
|
@classmethod |
119
|
|
|
def setUpTestData(cls): |
120
|
|
|
super().setUpTestData() |
121
|
|
|
|
122
|
|
|
cls.bugzilla = BugSystem.objects.get(name='Bugzilla') |
123
|
|
|
cls.jira = BugSystem.objects.get(name='JIRA') |
124
|
|
|
|
125
|
|
|
cls.bz_bug_1 = '12345' |
126
|
|
|
cls.execution_1.add_bug(cls.bz_bug_1, bug_system_id=cls.bugzilla.pk) |
127
|
|
|
cls.bz_bug_2 = '10000' |
128
|
|
|
cls.execution_1.add_bug(cls.bz_bug_2, bug_system_id=cls.bugzilla.pk) |
129
|
|
|
cls.jira_nitrate_1 = 'NITRATE-1' |
130
|
|
|
cls.execution_1.add_bug(cls.jira_nitrate_1, bug_system_id=cls.jira.pk) |
131
|
|
|
cls.jira_nitrate_2 = 'NITRATE-2' |
132
|
|
|
cls.execution_2.add_bug(cls.jira_nitrate_2, bug_system_id=cls.jira.pk) |
133
|
|
|
|
134
|
|
|
def test_empty_if_no_bugs(self): |
135
|
|
|
data = TestExecutionDataMixin() |
136
|
|
|
result = data.get_execution_bugs(self.test_run_1.pk) |
137
|
|
|
self.assertEqual({}, result) |
138
|
|
|
|
139
|
|
|
def test_get_bugs(self): |
140
|
|
|
data = TestExecutionDataMixin() |
141
|
|
|
result = data.get_execution_bugs(self.test_run.pk) |
142
|
|
|
expected_result = { |
143
|
|
|
self.execution_1.pk: [ |
144
|
|
|
{ |
145
|
|
|
'bug_id': self.bz_bug_1, |
146
|
|
|
'case_run': self.execution_1.pk, |
147
|
|
|
'bug_system__url_reg_exp': self.bugzilla.url_reg_exp, |
148
|
|
|
'bug_url': self.bugzilla.url_reg_exp % self.bz_bug_1, |
149
|
|
|
}, |
150
|
|
|
{ |
151
|
|
|
'bug_id': self.bz_bug_2, |
152
|
|
|
'case_run': self.execution_1.pk, |
153
|
|
|
'bug_system__url_reg_exp': self.bugzilla.url_reg_exp, |
154
|
|
|
'bug_url': self.bugzilla.url_reg_exp % self.bz_bug_2, |
155
|
|
|
}, |
156
|
|
|
{ |
157
|
|
|
'bug_id': self.jira_nitrate_1, |
158
|
|
|
'case_run': self.execution_1.pk, |
159
|
|
|
'bug_system__url_reg_exp': self.jira.url_reg_exp, |
160
|
|
|
'bug_url': self.jira.url_reg_exp % self.jira_nitrate_1, |
161
|
|
|
} |
162
|
|
|
], |
163
|
|
|
self.execution_2.pk: [ |
164
|
|
|
{ |
165
|
|
|
'bug_id': self.jira_nitrate_2, |
166
|
|
|
'case_run': self.execution_2.pk, |
167
|
|
|
'bug_system__url_reg_exp': self.jira.url_reg_exp, |
168
|
|
|
'bug_url': self.jira.url_reg_exp % self.jira_nitrate_2, |
169
|
|
|
} |
170
|
|
|
], |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
for exp_key in expected_result: |
174
|
|
|
for exp_bug in expected_result[exp_key]: |
175
|
|
|
self.assertIn(exp_bug, result[exp_key]) |
176
|
|
|
|
177
|
|
|
|
178
|
|
|
class TestGetExecutionComments(BaseCaseRun): |
179
|
|
|
"""Test TestExecutionDataMixin.get_caseruns_comments |
180
|
|
|
|
181
|
|
|
There are two test runs created already, cls.test_run and cls.test_run_1. |
182
|
|
|
|
183
|
|
|
For this case, comments will be added to cls.test_run_1 in order to ensure |
184
|
|
|
comments could be retrieved correctly. And another one is for ensuring |
185
|
|
|
empty result even if no comment is added. |
186
|
|
|
""" |
187
|
|
|
|
188
|
|
|
@classmethod |
189
|
|
|
def setUpTestData(cls): |
190
|
|
|
super().setUpTestData() |
191
|
|
|
|
192
|
|
|
cls.submit_date = datetime(2017, 7, 7, 7, 7, 7) |
193
|
|
|
|
194
|
|
|
add_comment([cls.execution_4, cls.execution_5], |
195
|
|
|
comments='new comment', |
196
|
|
|
user=cls.tester, |
197
|
|
|
submit_date=cls.submit_date) |
198
|
|
|
add_comment([cls.execution_4], |
199
|
|
|
comments='make better', |
200
|
|
|
user=cls.tester, |
201
|
|
|
submit_date=cls.submit_date) |
202
|
|
|
|
203
|
|
|
def test_get_empty_comments_if_no_comment_there(self): |
204
|
|
|
data = TestExecutionDataMixin() |
205
|
|
|
comments = data.get_execution_comments(self.test_run.pk) |
206
|
|
|
self.assertEqual({}, comments) |
207
|
|
|
|
208
|
|
|
def test_get_comments(self): |
209
|
|
|
data = TestExecutionDataMixin() |
210
|
|
|
comments = data.get_execution_comments(self.test_run_1.pk) |
211
|
|
|
|
212
|
|
|
# note: keys are integer but the values are all string |
213
|
|
|
expected_comments = { |
214
|
|
|
self.execution_4.pk: [ |
215
|
|
|
{ |
216
|
|
|
'case_run_id': str(self.execution_4.pk), |
217
|
|
|
'user_name': self.tester.username, |
218
|
|
|
'submit_date': self.submit_date, |
219
|
|
|
'comment': 'new comment' |
220
|
|
|
}, |
221
|
|
|
{ |
222
|
|
|
'case_run_id': str(self.execution_4.pk), |
223
|
|
|
'user_name': self.tester.username, |
224
|
|
|
'submit_date': self.submit_date, |
225
|
|
|
'comment': 'make better' |
226
|
|
|
} |
227
|
|
|
], |
228
|
|
|
self.execution_5.pk: [ |
229
|
|
|
{ |
230
|
|
|
'case_run_id': str(self.execution_5.pk), |
231
|
|
|
'user_name': self.tester.username, |
232
|
|
|
'submit_date': self.submit_date, |
233
|
|
|
'comment': 'new comment' |
234
|
|
|
} |
235
|
|
|
] |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
for exp_key in expected_comments: |
239
|
|
|
for exp_cmt in expected_comments[exp_key]: |
240
|
|
|
self.assertIn(exp_cmt, comments[exp_key]) |
241
|
|
|
|