actir 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|