actir 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/actir.rb +17 -1
- data/lib/actir/parallel_tests/cli.rb +16 -7
- data/lib/actir/parallel_tests/report/html_formatter.rb +103 -139
- data/lib/actir/parallel_tests/report/html_reporter.rb +74 -107
- data/lib/actir/parallel_tests/test/runner.rb +41 -0
- data/lib/actir/version.rb +1 -1
- data/lib/actir/webdriver/browser.rb +24 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5668a4b2e06c10f5c22c3c373f9e0dc643f61503
|
4
|
+
data.tar.gz: 4d7324e5b64a929b6a7a9ee7a35b14733d4f030c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae691b3c59724f30e051d72ee487956ec14a3dd68735716f823b349e2bf03ed8ea5d62154472dd4db53513d5bc48978840f384160ddf05ec341d133b57f92192
|
7
|
+
data.tar.gz: 8597c67d810c2074c077490a9c01e241d5364cbc2ab9f814dfd38c9c6e635c4edb9ea0c4aa125a4258575b3137e9e565c31b5e731ffe4a8b17b2ded9feaffe22
|
data/lib/actir.rb
CHANGED
@@ -16,7 +16,23 @@ module Actir
|
|
16
16
|
|
17
17
|
#测试用例基础类,读取配置文件定义常量
|
18
18
|
class TestCase < Test::Unit::TestCase
|
19
|
-
|
19
|
+
class << self
|
20
|
+
# $testsuites = []
|
21
|
+
def startup
|
22
|
+
# 执行用例前,将测试套名字和用例名输出
|
23
|
+
suite_name = self.to_s
|
24
|
+
if (suite_name != "Actir::TestCase" && suite_name != "BaseTest")
|
25
|
+
puts "[suite start]"
|
26
|
+
puts "suitname: #{suite_name}\n"
|
27
|
+
test_methods = instance_methods.grep(/^test_/).map {|case_name|case_name.to_s}
|
28
|
+
test_methods.each do |testcase|
|
29
|
+
puts "testcase: #{testcase}\n"
|
30
|
+
end
|
31
|
+
puts "[suite end]"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
20
36
|
#IP地址的正则表达式
|
21
37
|
num = /\d|[01]?\d\d|2[0-4]\d|25[0-5]/
|
22
38
|
ip = /^(#{num}\.){3}#{num}/
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'optparse'
|
2
2
|
require 'tempfile'
|
3
3
|
require 'actir'
|
4
|
+
require 'actir/parallel_tests/report/html_reporter'
|
4
5
|
|
5
6
|
module Actir
|
6
7
|
module ParallelTests
|
@@ -84,7 +85,7 @@ module Actir
|
|
84
85
|
show_process_serialize(num_processes, options)
|
85
86
|
|
86
87
|
#输出最终的执行结果
|
87
|
-
report_results(test_results)
|
88
|
+
report_results(test_results, options)
|
88
89
|
end
|
89
90
|
|
90
91
|
abort final_fail_message if any_test_failed?(test_results)
|
@@ -107,12 +108,14 @@ module Actir
|
|
107
108
|
lock.flock File::LOCK_UN
|
108
109
|
end
|
109
110
|
|
110
|
-
def report_results(test_results)
|
111
|
+
def report_results(test_results, options)
|
111
112
|
results = @runner.find_results(test_results.map { |result| result[:stdout] }*"")
|
112
113
|
puts division_str
|
113
114
|
puts pre_str + @runner.summarize_results(results)
|
115
|
+
|
116
|
+
#add by shanmao
|
114
117
|
#生成详细报告
|
115
|
-
|
118
|
+
detail_report if (options[:report] == true)
|
116
119
|
#puts pre_str + any_test_failed?(test_results).to_s
|
117
120
|
end
|
118
121
|
|
@@ -188,6 +191,7 @@ module Actir
|
|
188
191
|
opts.on("--nice", "execute test commands with low priority") { options[:nice] = true }
|
189
192
|
opts.on("--verbose", "Print more output") { options[:verbose] = true }
|
190
193
|
opts.on("--log", "record exec result to logfile") { options[:log] = true}
|
194
|
+
opts.on("--report", "make a report to show the test result") { options[:report] = true}
|
191
195
|
opts.on("--remote", "run testcase in remote environment") { options[:mode] = :remote }
|
192
196
|
opts.on("--local", "run testcase in local environment") { options[:mode] = :local }
|
193
197
|
# 填写预发环境,目前只支持bjpre2-4,别的后续再添加
|
@@ -313,10 +317,15 @@ module Actir
|
|
313
317
|
"---------------------------------------------------------------------------------------------\n"
|
314
318
|
end
|
315
319
|
|
316
|
-
#
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
+
# 生成详细报告
|
321
|
+
def detail_report
|
322
|
+
@report_path = File.join($project_path, 'test_report')
|
323
|
+
Dir::mkdir(@report_path) if not File.directory?(@report_path)
|
324
|
+
time = Time.now.strftime('%Y%m%d_%H%M%S')
|
325
|
+
file_path = File.join(@report_path, "REPORT_#{time}.html")
|
326
|
+
file = File.new(file_path,"w")
|
327
|
+
report = HtmlReport.new(file)
|
328
|
+
end
|
320
329
|
|
321
330
|
end
|
322
331
|
end
|
@@ -5,111 +5,71 @@ module Actir
|
|
5
5
|
class HtmlFormatter
|
6
6
|
|
7
7
|
include ERB::Util # For the #h method.
|
8
|
-
def initialize(
|
9
|
-
@
|
8
|
+
def initialize(file)
|
9
|
+
@file = file
|
10
10
|
end
|
11
11
|
|
12
12
|
def print_html_start
|
13
|
-
@
|
14
|
-
@
|
13
|
+
@file.puts HTML_HEADER
|
14
|
+
@file.puts REPORT_HEADER
|
15
15
|
end
|
16
16
|
|
17
|
-
def print_example_group_end
|
18
|
-
@output.puts " </dl>"
|
19
|
-
@output.puts "</div>"
|
20
|
-
end
|
21
17
|
|
22
|
-
def
|
23
|
-
@
|
24
|
-
@
|
25
|
-
@
|
18
|
+
def print_testsuite_start(testsuite_id, testsuite_name)
|
19
|
+
@file.puts "<div id=\"div_testsuite_#{testsuite_id}\" class=\"testsuite passed\">"
|
20
|
+
@file.puts " <dl>"
|
21
|
+
@file.puts " <dt id=\"testsuite_#{testsuite_id}\" class=\"passed\">#{h(testsuite_name)}</dt>"
|
26
22
|
end
|
27
23
|
|
28
|
-
def
|
29
|
-
|
30
|
-
@
|
31
|
-
"<span class=\"passed_spec_name\">#{h(description)}</span>" \
|
32
|
-
"<span class='duration'>#{formatted_run_time}s</span></dd>"
|
24
|
+
def print_testsuite_end
|
25
|
+
@file.puts " </dl>"
|
26
|
+
@file.puts "</div>"
|
33
27
|
end
|
34
28
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
formatted_run_time = "%.5f" % run_time
|
40
|
-
|
41
|
-
@output.puts " <dd class=\"example #{pending_fixed ? 'pending_fixed' : 'failed'}\">"
|
42
|
-
@output.puts " <span class=\"failed_spec_name\">#{h(description)}</span>"
|
43
|
-
@output.puts " <span class=\"duration\">#{formatted_run_time}s</span>"
|
44
|
-
@output.puts " <div class=\"failure\" id=\"failure_#{failure_id}\">"
|
45
|
-
if exception
|
46
|
-
@output.puts " <div class=\"message\"><pre>#{h(exception[:message])}</pre></div>"
|
47
|
-
if escape_backtrace
|
48
|
-
@output.puts " <div class=\"backtrace\"><pre>#{h exception[:backtrace]}</pre></div>"
|
49
|
-
else
|
50
|
-
@output.puts " <div class=\"backtrace\"><pre>#{exception[:backtrace]}</pre></div>"
|
51
|
-
end
|
52
|
-
end
|
53
|
-
@output.puts extra_content if extra_content
|
54
|
-
@output.puts " </div>"
|
55
|
-
@output.puts " </dd>"
|
29
|
+
def print_testcase_passed(testcase_name)
|
30
|
+
@file.puts " <dd class=\"testcase passed\">"
|
31
|
+
@file.puts " <span class=\"passed_spec_name\">#{h(testcase_name)}</span>"
|
32
|
+
@file.puts " </dd>"
|
56
33
|
end
|
57
34
|
|
58
|
-
def
|
59
|
-
@
|
60
|
-
|
61
|
-
|
35
|
+
def print_testcase_failed(testcase_name, backtrace, failure_number)
|
36
|
+
@file.puts " <dd class=\"testcase failed\">"
|
37
|
+
@file.puts " <span class=\"failed_spec_name\">#{h(testcase_name)}</span>"
|
38
|
+
@file.puts " <div id=\"testtab\" style=\"float:right\"><a class=\"expand\" href=\"#\" onClick=\"Effect('failure_#{failure_number}',this.parentNode.id);\" >+</a> </div>"
|
39
|
+
@file.puts " <div class=\"failure\" id=\"failure_#{failure_number}\" style=\"display:none;\">"
|
40
|
+
@file.puts " <div class=\"backtrace\"><pre>#{h(backtrace)}</pre></div>"
|
41
|
+
@file.puts " </div>"
|
42
|
+
@file.puts " </dd>"
|
62
43
|
end
|
63
44
|
|
64
|
-
def print_summary(
|
65
|
-
totals = "#{
|
45
|
+
def print_summary(testcase_count, failure_count)
|
46
|
+
totals = "#{testcase_count} testcase#{'s' unless testcase_count == 1}, "
|
66
47
|
totals << "#{failure_count} failure#{'s' unless failure_count == 1}"
|
67
|
-
totals << ", #{pending_count} pending" if pending_count > 0
|
68
48
|
|
69
|
-
formatted_duration = "%.5f" % duration
|
49
|
+
# formatted_duration = "%.5f" % duration
|
70
50
|
|
71
|
-
@
|
72
|
-
|
73
|
-
|
74
|
-
@
|
51
|
+
# @file.puts "<script type=\"text/javascript\">" \
|
52
|
+
# "document.getElementById('duration').innerHTML = \"Finished in " \
|
53
|
+
# "<strong>#{formatted_duration} seconds</strong>\";</script>"
|
54
|
+
@file.puts "<script type=\"text/javascript\">" \
|
75
55
|
"document.getElementById('totals').innerHTML = \"#{totals}\";</script>"
|
76
|
-
@
|
77
|
-
@
|
78
|
-
@
|
79
|
-
@
|
80
|
-
end
|
81
|
-
|
82
|
-
def flush
|
83
|
-
@output.flush
|
84
|
-
end
|
85
|
-
|
86
|
-
def move_progress(percent_done)
|
87
|
-
@output.puts " <script type=\"text/javascript\">moveProgressBar('#{percent_done}');</script>"
|
88
|
-
@output.flush
|
56
|
+
@file.puts "</div>"
|
57
|
+
@file.puts "</div>"
|
58
|
+
@file.puts "</body>"
|
59
|
+
@file.puts "</html>"
|
89
60
|
end
|
90
61
|
|
91
|
-
def
|
92
|
-
@
|
62
|
+
def make_testsuite_header_red(testsuite_id)
|
63
|
+
@file.puts " <script type=\"text/javascript\">" \
|
64
|
+
"makeRed('div_testsuite_#{testsuite_id}');</script>"
|
65
|
+
@file.puts " <script type=\"text/javascript\">" \
|
66
|
+
"makeRed('testsuite_#{testsuite_id}');</script>"
|
93
67
|
end
|
94
68
|
|
95
|
-
def
|
96
|
-
@
|
97
|
-
end
|
98
|
-
|
99
|
-
def make_example_group_header_red(group_id)
|
100
|
-
@output.puts " <script type=\"text/javascript\">" \
|
101
|
-
"makeRed('div_group_#{group_id}');</script>"
|
102
|
-
@output.puts " <script type=\"text/javascript\">" \
|
103
|
-
"makeRed('example_group_#{group_id}');</script>"
|
104
|
-
end
|
105
|
-
|
106
|
-
def make_example_group_header_yellow(group_id)
|
107
|
-
@output.puts " <script type=\"text/javascript\">" \
|
108
|
-
"makeYellow('div_group_#{group_id}');</script>"
|
109
|
-
@output.puts " <script type=\"text/javascript\">" \
|
110
|
-
"makeYellow('example_group_#{group_id}');</script>"
|
69
|
+
def flush
|
70
|
+
@file.flush
|
111
71
|
end
|
112
|
-
|
72
|
+
|
113
73
|
private
|
114
74
|
|
115
75
|
def indentation_style(number_of_parents)
|
@@ -122,13 +82,12 @@ module Actir
|
|
122
82
|
|
123
83
|
<div id="test-header">
|
124
84
|
<div id="label">
|
125
|
-
<h1>
|
85
|
+
<h1>Test Cases Result</h1>
|
126
86
|
</div>
|
127
87
|
|
128
88
|
<div id="display-filters">
|
129
89
|
<input id="passed_checkbox" name="passed_checkbox" type="checkbox" checked="checked" onchange="apply_filters()" value="1" /> <label for="passed_checkbox">Passed</label>
|
130
90
|
<input id="failed_checkbox" name="failed_checkbox" type="checkbox" checked="checked" onchange="apply_filters()" value="2" /> <label for="failed_checkbox">Failed</label>
|
131
|
-
<input id="pending_checkbox" name="pending_checkbox" type="checkbox" checked="checked" onchange="apply_filters()" value="3" /> <label for="pending_checkbox">Pending</label>
|
132
91
|
</div>
|
133
92
|
|
134
93
|
<div id="summary">
|
@@ -155,38 +114,20 @@ function removeClass(element_id, classname) {
|
|
155
114
|
elem.className = classlist;
|
156
115
|
}
|
157
116
|
|
158
|
-
function moveProgressBar(percentDone) {
|
159
|
-
document.getElementById("test-header").style.width = percentDone +"%";
|
160
|
-
}
|
161
|
-
|
162
117
|
function makeRed(element_id) {
|
163
118
|
removeClass(element_id, 'passed');
|
164
|
-
removeClass(element_id, 'not_implemented');
|
165
119
|
addClass(element_id,'failed');
|
166
120
|
}
|
167
121
|
|
168
|
-
function makeYellow(element_id) {
|
169
|
-
var elem = document.getElementById(element_id);
|
170
|
-
if (elem.className.indexOf("failed") == -1) { // class doesn't includes failed
|
171
|
-
if (elem.className.indexOf("not_implemented") == -1) { // class doesn't include not_implemented
|
172
|
-
removeClass(element_id, 'passed');
|
173
|
-
addClass(element_id,'not_implemented');
|
174
|
-
}
|
175
|
-
}
|
176
|
-
}
|
177
|
-
|
178
122
|
function apply_filters() {
|
179
123
|
var passed_filter = document.getElementById('passed_checkbox').checked;
|
180
124
|
var failed_filter = document.getElementById('failed_checkbox').checked;
|
181
|
-
var pending_filter = document.getElementById('pending_checkbox').checked;
|
182
125
|
|
183
|
-
assign_display_style("
|
184
|
-
assign_display_style("
|
185
|
-
assign_display_style("example not_implemented", pending_filter);
|
126
|
+
assign_display_style("testcase passed", passed_filter);
|
127
|
+
assign_display_style("testcase failed", failed_filter);
|
186
128
|
|
187
|
-
assign_display_style_for_group("
|
188
|
-
assign_display_style_for_group("
|
189
|
-
assign_display_style_for_group("example_group failed", failed_filter, failed_filter || pending_filter || passed_filter);
|
129
|
+
assign_display_style_for_group("testsuite passed", passed_filter);
|
130
|
+
assign_display_style_for_group("testsuite failed", failed_filter, failed_filter || pending_filter || passed_filter);
|
190
131
|
}
|
191
132
|
|
192
133
|
function get_display_style(display_flag) {
|
@@ -218,6 +159,57 @@ function assign_display_style_for_group(classname, display_flag, subgroup_flag)
|
|
218
159
|
}
|
219
160
|
}
|
220
161
|
}
|
162
|
+
|
163
|
+
function $G(Read_Id) { return document.getElementById(Read_Id) }
|
164
|
+
|
165
|
+
function Effect(ObjectId,parentId){
|
166
|
+
var Obj_Display = $G(ObjectId).style.display;
|
167
|
+
if (Obj_Display == 'none'){
|
168
|
+
Start(ObjectId,'Opens');
|
169
|
+
$G(parentId).innerHTML = "<a class=\\"expand\\" href=# onClick=javascript:Effect('"+ObjectId+"','"+parentId+"');>-</a>"
|
170
|
+
}else{
|
171
|
+
Start(ObjectId,'Close');
|
172
|
+
$G(parentId).innerHTML = "<a class=\\"expand\\" href=# onClick=javascript:Effect('"+ObjectId+"','"+parentId+"');>+</a>"
|
173
|
+
}
|
174
|
+
}
|
175
|
+
|
176
|
+
function Start(ObjId,method){
|
177
|
+
var BoxHeight = $G(ObjId).offsetHeight;
|
178
|
+
var MinHeight = 5;
|
179
|
+
var MaxHeight = 130;
|
180
|
+
var BoxAddMax = 1;
|
181
|
+
var Every_Add = 0.15;
|
182
|
+
var Reduce = (BoxAddMax - Every_Add);
|
183
|
+
var Add = (BoxAddMax + Every_Add);
|
184
|
+
|
185
|
+
if (method == "Close"){
|
186
|
+
var Alter_Close = function(){
|
187
|
+
BoxAddMax /= Reduce;
|
188
|
+
BoxHeight -= BoxAddMax;
|
189
|
+
if (BoxHeight <= MinHeight){
|
190
|
+
$G(ObjId).style.display = "none";
|
191
|
+
window.clearInterval(BoxAction);
|
192
|
+
}
|
193
|
+
else $G(ObjId).style.height = BoxHeight;
|
194
|
+
}
|
195
|
+
var BoxAction = window.setInterval(Alter_Close,1);
|
196
|
+
}
|
197
|
+
|
198
|
+
else if (method == "Opens"){
|
199
|
+
var Alter_Opens = function(){
|
200
|
+
BoxAddMax *= Add;
|
201
|
+
BoxHeight += BoxAddMax;
|
202
|
+
if (BoxHeight >= MaxHeight){
|
203
|
+
$G(ObjId).style.height = MaxHeight;
|
204
|
+
window.clearInterval(BoxAction);
|
205
|
+
}else{
|
206
|
+
$G(ObjId).style.display= "block";
|
207
|
+
$G(ObjId).style.height = BoxHeight;
|
208
|
+
}
|
209
|
+
}
|
210
|
+
var BoxAction = window.setInterval(Alter_Opens,1);
|
211
|
+
}
|
212
|
+
}
|
221
213
|
EOF
|
222
214
|
# rubocop:enable LineLength
|
223
215
|
|
@@ -259,11 +251,13 @@ EOF
|
|
259
251
|
font-size: 1.2em;
|
260
252
|
}
|
261
253
|
|
262
|
-
.
|
254
|
+
.testsuite {
|
263
255
|
margin: 0 10px 5px;
|
264
256
|
background: #fff;
|
265
257
|
}
|
266
258
|
|
259
|
+
.expand {text-decoration:none;}
|
260
|
+
|
267
261
|
dl {
|
268
262
|
margin: 0; padding: 0 0 5px;
|
269
263
|
font: normal 11px "Lucida Grande", Helvetica, sans-serif;
|
@@ -288,52 +282,22 @@ dd .duration {
|
|
288
282
|
float:right;
|
289
283
|
}
|
290
284
|
|
291
|
-
dd.
|
285
|
+
dd.testcase.passed {
|
292
286
|
border-left: 5px solid #65C400;
|
293
287
|
border-bottom: 1px solid #65C400;
|
294
288
|
background: #DBFFB4; color: #3D7700;
|
295
289
|
}
|
296
290
|
|
297
|
-
dd.
|
298
|
-
border-left: 5px solid #FAF834;
|
299
|
-
border-bottom: 1px solid #FAF834;
|
300
|
-
background: #FCFB98; color: #131313;
|
301
|
-
}
|
302
|
-
|
303
|
-
dd.example.pending_fixed {
|
304
|
-
border-left: 5px solid #0000C2;
|
305
|
-
border-bottom: 1px solid #0000C2;
|
306
|
-
color: #0000C2; background: #D3FBFF;
|
307
|
-
}
|
308
|
-
|
309
|
-
dd.example.failed {
|
291
|
+
dd.testcase.failed {
|
310
292
|
border-left: 5px solid #C20000;
|
311
293
|
border-bottom: 1px solid #C20000;
|
312
294
|
color: #C20000; background: #FFFBD3;
|
313
295
|
}
|
314
296
|
|
315
|
-
|
316
|
-
dt.not_implemented {
|
317
|
-
color: #000000; background: #FAF834;
|
318
|
-
}
|
319
|
-
|
320
|
-
dt.pending_fixed {
|
321
|
-
color: #FFFFFF; background: #C40D0D;
|
322
|
-
}
|
323
|
-
|
324
297
|
dt.failed {
|
325
298
|
color: #FFFFFF; background: #C40D0D;
|
326
299
|
}
|
327
300
|
|
328
|
-
|
329
|
-
#test-header.not_implemented {
|
330
|
-
color: #000000; background: #FAF834;
|
331
|
-
}
|
332
|
-
|
333
|
-
#test-header.pending_fixed {
|
334
|
-
color: #FFFFFF; background: #C40D0D;
|
335
|
-
}
|
336
|
-
|
337
301
|
#test-header.failed {
|
338
302
|
color: #FFFFFF; background: #C40D0D;
|
339
303
|
}
|
@@ -1,106 +1,81 @@
|
|
1
|
+
require 'actir/parallel_tests/report/html_formatter'
|
2
|
+
|
1
3
|
module Actir
|
2
4
|
module ParallelTests
|
3
5
|
class HtmlReport
|
4
6
|
|
5
|
-
def initialize(
|
6
|
-
|
7
|
-
@
|
8
|
-
@
|
9
|
-
@
|
10
|
-
@
|
11
|
-
@
|
12
|
-
end
|
7
|
+
def initialize(file)
|
8
|
+
@testsuites = $testsuites
|
9
|
+
@testsuite_number = 0
|
10
|
+
@testcase_number = 0
|
11
|
+
@failure_number = 0
|
12
|
+
# @duration = 0
|
13
|
+
@formatter = HtmlFormatter.new(file)
|
13
14
|
|
14
|
-
|
15
|
-
super
|
16
|
-
@printer.print_html_start
|
17
|
-
@printer.flush
|
15
|
+
result_print
|
18
16
|
end
|
19
17
|
|
20
|
-
def
|
21
|
-
|
22
|
-
@
|
23
|
-
|
18
|
+
def result_print
|
19
|
+
# 没有result信息
|
20
|
+
return 0 if @testsuites == nil
|
21
|
+
|
22
|
+
report_start
|
23
|
+
@testsuites.each do |testsuite|
|
24
|
+
testsuite_print(testsuite)
|
25
|
+
end
|
24
26
|
|
25
|
-
@
|
26
|
-
|
27
|
-
notification.group.description,
|
28
|
-
notification.group.parent_groups.size)
|
29
|
-
@printer.flush
|
27
|
+
summary = {:testcase_count => @testcase_number, :failure_count => @failure_number}
|
28
|
+
summary_print(summary)
|
30
29
|
end
|
31
30
|
|
32
|
-
def
|
33
|
-
@
|
34
|
-
@
|
31
|
+
def report_start
|
32
|
+
@formatter.print_html_start
|
33
|
+
@formatter.flush
|
35
34
|
end
|
36
35
|
|
37
|
-
def
|
38
|
-
@
|
36
|
+
def testsuite_print(testsuite)
|
37
|
+
@testsuite_red = false
|
38
|
+
@testsuite_number += 1
|
39
|
+
@formatter.print_testsuite_start(@testsuite_number, testsuite[:testsuite_name])
|
40
|
+
testcases = testsuite[:testcases]
|
41
|
+
testcases.each do |testcase|
|
42
|
+
if(testcase[:succuss] == true)
|
43
|
+
testcase_passed_print(testcase[:testcase_name])
|
44
|
+
else
|
45
|
+
testcase_failed_print(testcase[:testcase_name], testcase[:detail])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
@formatter.print_testsuite_end
|
49
|
+
@formatter.flush
|
39
50
|
end
|
40
51
|
|
41
|
-
def
|
42
|
-
@
|
43
|
-
@
|
44
|
-
@
|
52
|
+
def testcase_passed_print(testcase_name)
|
53
|
+
@testcase_number += 1
|
54
|
+
@formatter.print_testcase_passed(testcase_name)
|
55
|
+
@formatter.flush
|
45
56
|
end
|
46
57
|
|
47
|
-
def
|
48
|
-
@
|
49
|
-
|
50
|
-
@header_red = true
|
51
|
-
@printer.make_header_red
|
52
|
-
end
|
58
|
+
def testcase_failed_print(testcase_name, details)
|
59
|
+
@testcase_number += 1
|
60
|
+
@failure_number += 1
|
53
61
|
|
54
|
-
unless @
|
55
|
-
@
|
56
|
-
@
|
62
|
+
unless @testsuite_red
|
63
|
+
@testsuite_red = true
|
64
|
+
@formatter.make_testsuite_header_red(@testsuite_number)
|
57
65
|
end
|
58
66
|
|
59
|
-
@
|
60
|
-
|
61
|
-
example = failure.example
|
62
|
-
|
63
|
-
exception = failure.exception
|
64
|
-
exception_details = if exception
|
65
|
-
{
|
66
|
-
:message => exception.message,
|
67
|
-
:backtrace => failure.formatted_backtrace.join("\n")
|
68
|
-
}
|
69
|
-
else
|
70
|
-
false
|
71
|
-
end
|
72
|
-
extra = extra_failure_content(failure)
|
73
|
-
|
74
|
-
@printer.print_example_failed(
|
75
|
-
example.execution_result.pending_fixed,
|
76
|
-
example.description,
|
77
|
-
example.execution_result.run_time,
|
78
|
-
@failed_examples.size,
|
79
|
-
exception_details,
|
80
|
-
(extra == "") ? false : extra,
|
81
|
-
true
|
82
|
-
)
|
83
|
-
@printer.flush
|
67
|
+
@formatter.print_testcase_failed(testcase_name, details, @failure_number)
|
68
|
+
@formatter.flush
|
84
69
|
end
|
85
70
|
|
86
|
-
def example_pending(pending)
|
87
|
-
example = pending.example
|
88
|
-
|
89
|
-
@printer.make_header_yellow unless @header_red
|
90
|
-
@printer.make_example_group_header_yellow(example_group_number) unless @example_group_red
|
91
|
-
@printer.move_progress(percent_done)
|
92
|
-
@printer.print_example_pending(example.description, example.execution_result.pending_message)
|
93
|
-
@printer.flush
|
94
|
-
end
|
95
71
|
|
96
|
-
def
|
97
|
-
@
|
98
|
-
summary
|
99
|
-
summary
|
100
|
-
summary
|
101
|
-
summary.pending_count
|
72
|
+
def summary_print(summary)
|
73
|
+
@formatter.print_summary(
|
74
|
+
# summary[:duration],
|
75
|
+
summary[:testcase_count],
|
76
|
+
summary[:failure_count]
|
102
77
|
)
|
103
|
-
@
|
78
|
+
@formatter.flush
|
104
79
|
end
|
105
80
|
|
106
81
|
private
|
@@ -109,37 +84,29 @@ module Actir
|
|
109
84
|
# warning because they are private.
|
110
85
|
# rubocop:disable Style/TrivialAccessors
|
111
86
|
|
112
|
-
# The number of the currently running
|
113
|
-
def
|
114
|
-
|
115
|
-
end
|
87
|
+
# The number of the currently running testsuite.
|
88
|
+
# def testsuite_number
|
89
|
+
# @testsuite_number
|
90
|
+
# end
|
116
91
|
|
117
|
-
# The number of the currently running
|
118
|
-
def
|
119
|
-
|
120
|
-
end
|
92
|
+
# The number of the currently running testcase (a global counter).
|
93
|
+
# def testcase_number
|
94
|
+
# @testcase_number
|
95
|
+
# end
|
121
96
|
# rubocop:enable Style/TrivialAccessors
|
122
97
|
|
123
|
-
|
124
|
-
|
125
|
-
if @example_count > 0
|
126
|
-
result = (((example_number).to_f / @example_count.to_f * 1000).to_i / 10.0).to_f
|
127
|
-
end
|
128
|
-
result
|
129
|
-
end
|
130
|
-
|
131
|
-
# Override this method if you wish to output extra HTML for a failed
|
132
|
-
# spec. For example, you could output links to images or other files
|
98
|
+
# Override this method if you wish to file extra HTML for a failed
|
99
|
+
# spec. For testcase, you could file links to images or other files
|
133
100
|
# produced during the specs.
|
134
|
-
def extra_failure_content(failure)
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
end
|
101
|
+
# def extra_failure_content(failure)
|
102
|
+
# RSpec::Support.require_rspec_core "formatters/snippet_extractor"
|
103
|
+
# backtrace = failure.exception.backtrace.map do |line|
|
104
|
+
# RSpec.configuration.backtrace_formatter.backtrace_line(line)
|
105
|
+
# end
|
106
|
+
# backtrace.compact!
|
107
|
+
# @snippet_extractor ||= SnippetExtractor.new
|
108
|
+
# " <pre class=\"ruby\"><code>#{@snippet_extractor.snippet(backtrace)}</code></pre>"
|
109
|
+
# end
|
143
110
|
end
|
144
111
|
end
|
145
112
|
end
|
@@ -90,6 +90,12 @@ module Actir
|
|
90
90
|
cmd = "#{exports}#{separator}#{cmd}"
|
91
91
|
output = open("|#{cmd}", "r") { |output| capture_output(output, silence) }
|
92
92
|
|
93
|
+
#modify by shanmao
|
94
|
+
#获取执行的测试套详细信息
|
95
|
+
get_testsuite_detail(output)
|
96
|
+
#获取失败的用例的详情
|
97
|
+
get_testfailed_detail(output)
|
98
|
+
|
93
99
|
#modify by Hub
|
94
100
|
#exitstatus = $?.exitstatus
|
95
101
|
#"$?.exitstatus" 返回的值有时有问题,不能明确标示用例执行结果是否成功
|
@@ -132,6 +138,41 @@ module Actir
|
|
132
138
|
"/usr/local/rvm/rubies/ruby-2.0.0-p598/bin/ruby"
|
133
139
|
end
|
134
140
|
end
|
141
|
+
|
142
|
+
#
|
143
|
+
# 通过结果判断测试套的详细信息
|
144
|
+
# 将测试套和测试用例的详细信息写入全局变量$testsuites中
|
145
|
+
#
|
146
|
+
def get_testsuite_detail output
|
147
|
+
$testsuites = [] unless $testsuites
|
148
|
+
output.scan(/^(\[suite start\])([^\.][^E]*)(\[suite end\])$/).each do |suite|
|
149
|
+
suitename = suite[1].scan(/^(suitname:\s*)([\d\w]*)/)[0][1]
|
150
|
+
cases = suite[1].scan(/^(testcase:\s*)([\d\w]*)/).inject([]) do |cases,testcase|
|
151
|
+
cases << {:testcase_name => testcase[1], :succuss => true, :detail => nil}
|
152
|
+
end
|
153
|
+
# 如果testsuites中已存在此用例的信息,说明这个用例执行了rerun,就不再次添加了
|
154
|
+
is_case_exist = $testsuites.inject(false) do |is_case_exist, testsuite|
|
155
|
+
if testsuite.has_value?(suitename)
|
156
|
+
is_case_exist = true
|
157
|
+
break
|
158
|
+
end
|
159
|
+
is_case_exist
|
160
|
+
end
|
161
|
+
if(is_case_exist == false)
|
162
|
+
testsuite = {:testsuite_name => suitename, :testcases =>cases}
|
163
|
+
$testsuites << testsuite
|
164
|
+
end
|
165
|
+
end
|
166
|
+
# p $testsuites
|
167
|
+
end
|
168
|
+
|
169
|
+
#
|
170
|
+
# 通过结果判断失败用例,获取失败用例的详细信息
|
171
|
+
# 将测试套和测试用例的详细信息写入全局变量$testsuites中
|
172
|
+
#
|
173
|
+
def get_testfailed_detail output
|
174
|
+
|
175
|
+
end
|
135
176
|
|
136
177
|
#
|
137
178
|
# 通过结果判断是否有用例失败
|
data/lib/actir/version.rb
CHANGED
@@ -53,6 +53,30 @@ class Browser
|
|
53
53
|
define_page_method
|
54
54
|
end
|
55
55
|
|
56
|
+
def goto(uri)
|
57
|
+
hasLoaded = 0
|
58
|
+
for i in 1..3
|
59
|
+
begin
|
60
|
+
Timeout::timeout(10) do
|
61
|
+
puts "Time #{i}"
|
62
|
+
super(uri)
|
63
|
+
|
64
|
+
if self.execute_script("return document.readyState;") == "complete"
|
65
|
+
puts "has completed"
|
66
|
+
hasLoaded = 1
|
67
|
+
break
|
68
|
+
end
|
69
|
+
end
|
70
|
+
rescue Timeout::Error => e
|
71
|
+
puts "Page load timed out: #{e}"
|
72
|
+
end
|
73
|
+
|
74
|
+
if hasLoaded == 1
|
75
|
+
break
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
56
80
|
# 初始化入参
|
57
81
|
def init_args(args = {})
|
58
82
|
unless args.has_key?(:mode)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: actir
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- hub
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: test-unit
|