actir 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +4 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +11 -0
- data/README.md +56 -0
- data/Rakefile +70 -0
- data/actir.gemspec +31 -0
- data/bin/actir +9 -0
- data/bin/ants +9 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/actir.rb +41 -0
- data/lib/actir/basic_page.rb +49 -0
- data/lib/actir/config.rb +192 -0
- data/lib/actir/initializer.rb +70 -0
- data/lib/actir/parallel_tests/cli.rb +323 -0
- data/lib/actir/parallel_tests/grouper.rb +44 -0
- data/lib/actir/parallel_tests/parallel_tests.rb +77 -0
- data/lib/actir/parallel_tests/report/html_formatter.rb +417 -0
- data/lib/actir/parallel_tests/report/html_reporter.rb +145 -0
- data/lib/actir/parallel_tests/test/logger.rb +74 -0
- data/lib/actir/parallel_tests/test/re_run.rb +153 -0
- data/lib/actir/parallel_tests/test/runner.rb +224 -0
- data/lib/actir/remote.rb +80 -0
- data/lib/actir/script/cookies_baidu.rb +143 -0
- data/lib/actir/version.rb +3 -0
- data/lib/actir/webdriver/browser.rb +201 -0
- data/lib/actir/webdriver/browser_options.rb +54 -0
- data/lib/actir/webdriver/config/devices.yaml +40 -0
- data/lib/actir/webdriver/devices.rb +31 -0
- data/lib/actir/webdriver/driver.rb +42 -0
- metadata +175 -0
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
module Actir
|
4
|
+
class Initializer
|
5
|
+
|
6
|
+
#config content
|
7
|
+
attr_accessor :config
|
8
|
+
|
9
|
+
def initialize project_path
|
10
|
+
$project_path ||= project_path
|
11
|
+
$:.unshift($project_path)
|
12
|
+
$config = load_config
|
13
|
+
load_elements
|
14
|
+
end
|
15
|
+
|
16
|
+
def load_elements
|
17
|
+
@elements_path = File.join($project_path, 'elements')
|
18
|
+
load_item
|
19
|
+
load_components
|
20
|
+
load_user
|
21
|
+
load_pages
|
22
|
+
end
|
23
|
+
|
24
|
+
def load_config
|
25
|
+
@config_path = File.join($project_path, 'config')
|
26
|
+
@config = {}
|
27
|
+
Dir.glob(File.join @config_path, '**', '*.yaml').select{ |c| c =~ /\.yaml$/ }.each do |config|
|
28
|
+
puts "#{config}" if $debug
|
29
|
+
#获取配置文件名字
|
30
|
+
config =~ /config\/(.*)\.yaml/
|
31
|
+
config_name = $1
|
32
|
+
@config.store(config_name, Actir::Config.get_content(config))
|
33
|
+
end
|
34
|
+
@config
|
35
|
+
end
|
36
|
+
|
37
|
+
def load_item
|
38
|
+
@item_path = File.join(@elements_path, 'item')
|
39
|
+
Dir.glob(File.join @item_path, '**', '*.rb').select {|p| p =~ /\.rb$/}.each do |i|
|
40
|
+
puts i if $debug
|
41
|
+
require "#{i}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def load_user
|
46
|
+
@user_path = File.join(@elements_path, 'user')
|
47
|
+
Dir.glob(File.join @user_path, '**', '*.rb').select {|p| p =~ /\.rb$/}.each do |u|
|
48
|
+
puts u if $debug
|
49
|
+
require "#{u}"
|
50
|
+
end #each
|
51
|
+
end
|
52
|
+
|
53
|
+
def load_components
|
54
|
+
@components_path = File.join(@elements_path, 'components')
|
55
|
+
Dir.glob(File.join @components_path, '**', '*.rb').select {|p| p =~ /\.rb$/}.each do |c|
|
56
|
+
puts c if $debug
|
57
|
+
require "#{c}"
|
58
|
+
end #each
|
59
|
+
end
|
60
|
+
|
61
|
+
def load_pages
|
62
|
+
@pages_path = File.join(@elements_path, 'pages')
|
63
|
+
Dir.glob(File.join @pages_path, '**', '*.rb').select { |p| p =~ /\.rb$/ }.each do |page|
|
64
|
+
puts "#{page}"if $debug
|
65
|
+
require "#{page}"
|
66
|
+
end #each
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,323 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'actir'
|
4
|
+
|
5
|
+
module Actir
|
6
|
+
module ParallelTests
|
7
|
+
|
8
|
+
class CLI
|
9
|
+
def run(argv)
|
10
|
+
$env = "online"
|
11
|
+
options = parse_options!(argv)
|
12
|
+
num_processes = Actir::ParallelTests.determine_number_of_processes(options[:count])
|
13
|
+
$mode = Actir::ParallelTests.determine_run_env(options[:mode])
|
14
|
+
if options[:execute]
|
15
|
+
execute_shell_command_in_parallel(options[:execute], num_processes, options)
|
16
|
+
else
|
17
|
+
run_tests_in_parallel(num_processes, options)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def execute_in_parallel(items, num_processes, options)
|
24
|
+
Tempfile.open 'parallel_tests-lock' do |lock|
|
25
|
+
return Parallel.map(items, :in_threads => num_processes) do |item|
|
26
|
+
result = yield(item)
|
27
|
+
report_output(result, lock) if options[:serialize_stdout]
|
28
|
+
result
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def run_tests_in_parallel(num_processes, options)
|
34
|
+
test_results = nil
|
35
|
+
|
36
|
+
#修改全局变量$env至对应的预发布环境的名字
|
37
|
+
if options[:pre_name]
|
38
|
+
# 不等于当前的预发环境
|
39
|
+
if options[:pre_name] != $env
|
40
|
+
$env = options[:pre_name]
|
41
|
+
end
|
42
|
+
else
|
43
|
+
if options[:pre_name] != $env
|
44
|
+
$env = "online"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
report_time_taken do
|
49
|
+
groups = @runner.tests_in_groups(options[:files], num_processes, options)
|
50
|
+
|
51
|
+
# @modify by Hub
|
52
|
+
# @Date : 2015.3.9
|
53
|
+
# 远程执行模式下获取服务器IP和端口号
|
54
|
+
address = []
|
55
|
+
if $mode == :remote
|
56
|
+
address = Actir::Remote.get_remote_address(num_processes)
|
57
|
+
num_processes = address.size
|
58
|
+
end
|
59
|
+
|
60
|
+
#更新百度支付-百付宝的cookies
|
61
|
+
if options[:update]
|
62
|
+
Actir::CookiesBaidu.update_all
|
63
|
+
end
|
64
|
+
|
65
|
+
#计算重跑次数
|
66
|
+
re_run_times = Actir::ParallelTests.determine_times_of_rerun(options[:rerun])
|
67
|
+
#报用例数
|
68
|
+
report_number_of_tests(groups)
|
69
|
+
#报执行环境
|
70
|
+
report_address_of_env(address)
|
71
|
+
#并发执行不同group中的测试用例
|
72
|
+
test_results = execute_in_parallel(groups, groups.size, options) do |group|
|
73
|
+
p_num = groups.index(group)
|
74
|
+
#执行用例脚本
|
75
|
+
result = run_tests(group, p_num, num_processes, options, address[p_num])
|
76
|
+
#从结果中取出失败用例重跑
|
77
|
+
if ( result[:exit_status] != 0 ) && ( re_run_times > 0 )
|
78
|
+
result = Actir::ParallelTests::Test::Rerun.re_run_tests(result, p_num, num_processes, options, address[p_num], re_run_times)
|
79
|
+
end
|
80
|
+
result
|
81
|
+
end
|
82
|
+
|
83
|
+
#顺序输出并发执行过程
|
84
|
+
show_process_serialize(num_processes, options)
|
85
|
+
|
86
|
+
#输出最终的执行结果
|
87
|
+
report_results(test_results)
|
88
|
+
end
|
89
|
+
|
90
|
+
abort final_fail_message if any_test_failed?(test_results)
|
91
|
+
end
|
92
|
+
|
93
|
+
def run_tests(group, process_number, num_processes, options, address)
|
94
|
+
if group.empty?
|
95
|
+
{:stdout => '', :exit_status => 0}
|
96
|
+
else
|
97
|
+
#puts pre_str + "ready to exec #{group}"
|
98
|
+
@runner.run_tests(group, process_number, num_processes, options, address)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def report_output(result, lock)
|
103
|
+
lock.flock File::LOCK_EX
|
104
|
+
$stdout.puts result[:stdout]
|
105
|
+
$stdout.flush
|
106
|
+
ensure
|
107
|
+
lock.flock File::LOCK_UN
|
108
|
+
end
|
109
|
+
|
110
|
+
def report_results(test_results)
|
111
|
+
results = @runner.find_results(test_results.map { |result| result[:stdout] }*"")
|
112
|
+
puts division_str
|
113
|
+
puts pre_str + @runner.summarize_results(results)
|
114
|
+
#生成详细报告
|
115
|
+
#detail_report(@runner.summarize_results(results),file_path)
|
116
|
+
#puts pre_str + any_test_failed?(test_results).to_s
|
117
|
+
end
|
118
|
+
|
119
|
+
def report_number_of_tests(groups)
|
120
|
+
name = @runner.test_file_name
|
121
|
+
num_processes = groups.size
|
122
|
+
num_tests = groups.map(&:size).inject(:+)
|
123
|
+
puts division_str
|
124
|
+
puts pre_str + "#{num_processes} processes for #{num_tests} #{name}s, ~ #{num_tests / groups.size} #{name}s per process"
|
125
|
+
#puts division_str
|
126
|
+
end
|
127
|
+
|
128
|
+
# add by Hub
|
129
|
+
# show test env address
|
130
|
+
def report_address_of_env(address)
|
131
|
+
if $mode == :remote
|
132
|
+
node_name = Actir::Config.get("config.test_mode.docker.name")
|
133
|
+
address.each_with_index do |ip, i|
|
134
|
+
puts " " + $env + node_name + (i+1).to_s + " : " + ip
|
135
|
+
end
|
136
|
+
else
|
137
|
+
puts " " + "local"
|
138
|
+
end
|
139
|
+
puts division_str
|
140
|
+
end
|
141
|
+
|
142
|
+
#add by Hub
|
143
|
+
#show result of every process exec testcases
|
144
|
+
#this func will last for a while due to the big logfile
|
145
|
+
def show_process_serialize(num_processes, options)
|
146
|
+
if options[:log]
|
147
|
+
puts "\n" + division_str + pre_str + "SHOW_PROCESS_LOG--START\n" + division_str
|
148
|
+
for i in 0..(num_processes-1)
|
149
|
+
Actir::ParallelTests::Test::Logger.show_log(i)
|
150
|
+
puts division_str
|
151
|
+
end
|
152
|
+
puts division_str + pre_str + "SHOW_PROCESS_LOG--END\n" + division_str
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
#exit with correct status code so rake parallel:test && echo 123 works
|
157
|
+
def any_test_failed?(test_results)
|
158
|
+
test_results.any? { |result| result[:exit_status] != 0 }
|
159
|
+
end
|
160
|
+
|
161
|
+
def parse_options!(argv)
|
162
|
+
options = {}
|
163
|
+
@runner = load_runner("test")
|
164
|
+
OptionParser.new do |opts|
|
165
|
+
opts.banner = <<-BANNER.gsub(/^ /, '')
|
166
|
+
Run all tests in parallel
|
167
|
+
Usage: ruby [switches] [--] [files & folders]
|
168
|
+
Options are:
|
169
|
+
BANNER
|
170
|
+
opts.on("-n [PROCESSES]", Integer, "How many processes to use, default: 1") { |n| options[:count] = n }
|
171
|
+
opts.on("--group-by [TYPE]", <<-TEXT.gsub(/^ /, '')
|
172
|
+
group tests by:
|
173
|
+
found - order of finding files
|
174
|
+
filesize - by size of the file
|
175
|
+
default - filesize
|
176
|
+
TEXT
|
177
|
+
) { |type| options[:group_by] = type.to_sym }
|
178
|
+
opts.on("-r [TIMES]", "--rerun [TIMES]", Integer, "rerun times for failure&error testcase, default: 0") { |n| options[:rerun] = n }
|
179
|
+
#opts.on("-m [FLOAT]", "--multiply-processes [FLOAT]", Float, "use given number as a multiplier of processes to run") { |multiply| options[:multiply] = multiply }
|
180
|
+
opts.on("-i", "--isolate",
|
181
|
+
"Do not run any other tests in the group used by --single(-s)") do |pattern|
|
182
|
+
options[:isolate] = true
|
183
|
+
end
|
184
|
+
opts.on("-e", "--exec [COMMAND]", "execute this code parallel") { |path| options[:execute] = path }
|
185
|
+
opts.on("--serialize-stdout", "Serialize stdout output, nothing will be written until everything is done") { options[:serialize_stdout] = true }
|
186
|
+
opts.on("--combine-stderr", "Combine stderr into stdout, useful in conjunction with --serialize-stdout") { options[:combine_stderr] = true }
|
187
|
+
opts.on("--non-parallel", "execute same commands but do not in parallel, needs --exec") { options[:non_parallel] = true }
|
188
|
+
opts.on("--nice", "execute test commands with low priority") { options[:nice] = true }
|
189
|
+
opts.on("--verbose", "Print more output") { options[:verbose] = true }
|
190
|
+
opts.on("--log", "record exec result to logfile") { options[:log] = true}
|
191
|
+
opts.on("--remote", "run testcase in remote environment") { options[:mode] = :remote }
|
192
|
+
opts.on("--local", "run testcase in local environment") { options[:mode] = :local }
|
193
|
+
# 填写预发环境,目前只支持bjpre2-4,别的后续再添加
|
194
|
+
opts.on("-p", "--pre [PRE]", <<-TEXT.gsub(/^ /, '')
|
195
|
+
set pre environment to run testcase:
|
196
|
+
bjpre2
|
197
|
+
bjpre3
|
198
|
+
bjpre4
|
199
|
+
TEXT
|
200
|
+
) { |pre| pre = "online" if ( pre != "bjpre2" && pre != "bjpre3" && pre != "bjpre4"); options[:pre_name] = pre }
|
201
|
+
#add by Hub
|
202
|
+
#-u commnd, update baifubao's cookies
|
203
|
+
opts.on("-u", "--update", "Update Baifubao's cookies") { options[:update] = true }
|
204
|
+
#add by Hub
|
205
|
+
#-s commnd, show test mode,and remote env ipaddress
|
206
|
+
opts.on("-s", "--show [PATH]", "Show Test Mode") do |path|
|
207
|
+
abort "Please input project directory path!" if path == nil
|
208
|
+
$project_path = File.join(Dir.pwd, path)
|
209
|
+
puts division_str
|
210
|
+
if Actir::Config.get("config.test_mode.env") == :local
|
211
|
+
puts "mode : Local"
|
212
|
+
else
|
213
|
+
puts "mode : Remote"
|
214
|
+
node_name = Actir::Config.get("config.test_mode.docker.name")
|
215
|
+
address = Actir::Remote.get_remote_address
|
216
|
+
puts "node_num : " + address.size.to_s
|
217
|
+
address.each_with_index do |address, i|
|
218
|
+
puts $env + node_name + (i+1).to_s + " : " + address
|
219
|
+
end
|
220
|
+
end
|
221
|
+
puts division_str
|
222
|
+
exit
|
223
|
+
end
|
224
|
+
opts.on("-h", "--help", "Show this.") { puts opts; exit }
|
225
|
+
end.parse!(argv)
|
226
|
+
|
227
|
+
if options[:count] == 0
|
228
|
+
options.delete(:count)
|
229
|
+
options[:non_parallel] = true
|
230
|
+
end
|
231
|
+
|
232
|
+
abort "Pass files or folders to run" if argv.empty? && !options[:execute]
|
233
|
+
|
234
|
+
#如果argv为空,则默认执行所有测试文件
|
235
|
+
#遍历testcode下所有文件,组成字符串
|
236
|
+
options[:files] = argv
|
237
|
+
get_project_path(argv)
|
238
|
+
|
239
|
+
options
|
240
|
+
end
|
241
|
+
|
242
|
+
#根据传入的测试文件/文件夹的路径,获取测试工程的路径
|
243
|
+
def get_project_path(argv)
|
244
|
+
testcode_path = ""
|
245
|
+
(argv || []).map do |file_or_folder|
|
246
|
+
test_path = File.join(Dir.pwd , file_or_folder)
|
247
|
+
#获取testcode文件夹的path
|
248
|
+
if test_path =~ /(\/.*\/testcode)/
|
249
|
+
testcode_path = $1
|
250
|
+
break
|
251
|
+
end
|
252
|
+
end
|
253
|
+
#根据testcode path 拿到project的path
|
254
|
+
#要求testcode必须是project的下一级/testcode必须是config的平级
|
255
|
+
$project_path = File.join(testcode_path, "../")
|
256
|
+
end
|
257
|
+
|
258
|
+
def load_runner(type)
|
259
|
+
require "actir/parallel_tests/#{type}/runner"
|
260
|
+
require "actir/parallel_tests/#{type}/re_run"
|
261
|
+
require "actir/parallel_tests/test/logger"
|
262
|
+
runner_classname = type.split("_").map(&:capitalize).join.sub("Rspec", "RSpec")
|
263
|
+
klass_name = "Actir::ParallelTests::#{runner_classname}::Runner"
|
264
|
+
klass_name.split('::').inject(Object) { |x, y| x.const_get(y) }
|
265
|
+
end
|
266
|
+
|
267
|
+
def execute_shell_command_in_parallel(command, num_processes, options)
|
268
|
+
runs = (0...num_processes).to_a
|
269
|
+
results = if options[:non_parallel]
|
270
|
+
runs.map do |i|
|
271
|
+
Actir::ParallelTests::Test::Runner.execute_command(command, i, num_processes, options)
|
272
|
+
end
|
273
|
+
else
|
274
|
+
execute_in_parallel(runs, num_processes, options) do |i|
|
275
|
+
Actir::ParallelTests::Test::Runner.execute_command(command, i, num_processes, options)
|
276
|
+
end
|
277
|
+
end.flatten
|
278
|
+
|
279
|
+
abort if results.any? { |r| r[:exit_status] != 0 }
|
280
|
+
end
|
281
|
+
|
282
|
+
def report_time_taken
|
283
|
+
seconds = Actir::ParallelTests.delta { yield }.to_i
|
284
|
+
puts "\n" + pre_str + "Cost #{seconds} seconds#{detailed_duration(seconds)}\n"
|
285
|
+
puts division_str
|
286
|
+
end
|
287
|
+
|
288
|
+
def detailed_duration(seconds)
|
289
|
+
parts = [ seconds / 3600, seconds % 3600 / 60, seconds % 60 ].drop_while(&:zero?)
|
290
|
+
return if parts.size < 2
|
291
|
+
parts = parts.map { |i| "%02d" % i }.join(':').sub(/^0/, '')
|
292
|
+
" (#{parts})"
|
293
|
+
end
|
294
|
+
|
295
|
+
def final_fail_message
|
296
|
+
fail_message = "#{@runner.name}s Failed\n"
|
297
|
+
fail_message = "\e[31m#{fail_message}\e[0m" if use_colors?
|
298
|
+
|
299
|
+
division_str + pre_str + fail_message + division_str
|
300
|
+
end
|
301
|
+
|
302
|
+
def use_colors?
|
303
|
+
$stdout.tty?
|
304
|
+
end
|
305
|
+
|
306
|
+
def pre_str
|
307
|
+
" Actir : "
|
308
|
+
end
|
309
|
+
|
310
|
+
# add by Hub
|
311
|
+
# division for Actir report
|
312
|
+
def division_str
|
313
|
+
"---------------------------------------------------------------------------------------------\n"
|
314
|
+
end
|
315
|
+
|
316
|
+
# def detail_report(output)
|
317
|
+
|
318
|
+
# HtmlPrinter.new(file)
|
319
|
+
# end
|
320
|
+
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Actir
|
2
|
+
module ParallelTests
|
3
|
+
class Grouper
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def in_even_groups_by_size(items, num_groups, options= {})
|
7
|
+
groups = Array.new(num_groups) { {:items => [], :size => 0} }
|
8
|
+
|
9
|
+
groups_to_fill = (options[:isolate] ? groups[1..-1] : groups)
|
10
|
+
group_features_by_size(items_to_group(items), groups_to_fill)
|
11
|
+
|
12
|
+
groups.map!{|g| g[:items].sort }
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def largest_first(files)
|
18
|
+
files.sort_by{|item, size| size }.reverse
|
19
|
+
end
|
20
|
+
|
21
|
+
def smallest_group(groups)
|
22
|
+
groups.min_by{|g| g[:size] }
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_to_group(group, item, size)
|
26
|
+
group[:items] << item
|
27
|
+
group[:size] += size
|
28
|
+
end
|
29
|
+
|
30
|
+
def group_features_by_size(items, groups_to_fill)
|
31
|
+
items.each do |item, size|
|
32
|
+
size ||= 1
|
33
|
+
smallest = smallest_group(groups_to_fill)
|
34
|
+
add_to_group(smallest, item, size)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def items_to_group(items)
|
39
|
+
items.first && items.first.size == 2 ? largest_first(items) : items
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require "parallel"
|
2
|
+
require 'actir/parallel_tests/cli'
|
3
|
+
require 'actir/parallel_tests/grouper'
|
4
|
+
|
5
|
+
module Actir
|
6
|
+
module ParallelTests
|
7
|
+
|
8
|
+
autoload :CLI, "cli"
|
9
|
+
autoload :Grouper, "grouper"
|
10
|
+
|
11
|
+
# 一些通用类方法
|
12
|
+
class << self
|
13
|
+
#判断执行的进程数
|
14
|
+
def determine_number_of_processes(count)
|
15
|
+
[
|
16
|
+
count,
|
17
|
+
#ENV["PARALLEL_TEST_PROCESSORS"],
|
18
|
+
#核数
|
19
|
+
#Parallel.processor_count
|
20
|
+
#count数不填模式为1
|
21
|
+
1
|
22
|
+
].detect{|c| not c.to_s.strip.empty? }.to_i
|
23
|
+
end
|
24
|
+
|
25
|
+
#判断失败用例重新执行的次数
|
26
|
+
def determine_times_of_rerun(times)
|
27
|
+
[
|
28
|
+
times,
|
29
|
+
0
|
30
|
+
#Actir::Config.get("config.test_mode.re_run")
|
31
|
+
].detect{|c| not c.to_s.strip.empty? }.to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
#判断用例执行的环境是local还是remote
|
35
|
+
def determine_run_env(mode)
|
36
|
+
env_mode = :local
|
37
|
+
#判断是否存在config.yaml配置文件,如果不存在,则test_mode给默认值
|
38
|
+
if File.exist?(File.join($project_path, "config", "config.yaml"))
|
39
|
+
#刷新配置文件中的env配置项为remote模式,以防止本地调试代码改写上传后导致CI失败
|
40
|
+
if mode
|
41
|
+
unless mode == /#{Actir::Config.get("config.test_mode.env")}/
|
42
|
+
#同步修改配置文件,需要先将Symbol转换成String
|
43
|
+
mode_str = ":" + mode.to_s
|
44
|
+
Actir::Config.set("config.test_mode.env", mode_str)
|
45
|
+
end
|
46
|
+
env_mode = mode
|
47
|
+
else
|
48
|
+
env_mode = Actir::Config.get("config.test_mode.env")
|
49
|
+
end
|
50
|
+
else
|
51
|
+
if mode
|
52
|
+
env_mode = mode
|
53
|
+
end
|
54
|
+
end
|
55
|
+
ENV["mode"] = env_mode.to_s
|
56
|
+
env_mode
|
57
|
+
end
|
58
|
+
|
59
|
+
# real time even if someone messed with timecop in tests
|
60
|
+
def now
|
61
|
+
if Time.respond_to?(:now_without_mock_time) # Timecop
|
62
|
+
Time.now_without_mock_time
|
63
|
+
else
|
64
|
+
Time.now
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def delta
|
69
|
+
before = now.to_f
|
70
|
+
yield
|
71
|
+
now.to_f - before
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|