bucky-core 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +66 -0
- data/.codeclimate.yml +48 -0
- data/.dockerignore +11 -0
- data/.gitignore +40 -0
- data/.rspec +3 -0
- data/.rubocop.yml +76 -0
- data/.rubocop_todo.yml +51 -0
- data/Dockerfile +38 -0
- data/Dockerfile.system-test +44 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +115 -0
- data/LICENSE +201 -0
- data/README.md +246 -0
- data/Rakefile +8 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/bucky-core.gemspec +47 -0
- data/docker-compose.dev-with-bm.yml +28 -0
- data/docker-compose.dev.yml +18 -0
- data/docker-compose.system-test.yml +21 -0
- data/docker/nginx/Dockerfile +7 -0
- data/docker/nginx/nginx.conf +22 -0
- data/docker/nginx/public/index.html +19 -0
- data/docker/nginx/public/test_page.html +12 -0
- data/exe/bucky +214 -0
- data/lib/bucky.rb +3 -0
- data/lib/bucky/core/database/db_connector.rb +29 -0
- data/lib/bucky/core/database/test_data_operator.rb +195 -0
- data/lib/bucky/core/exception/bucky_exception.rb +39 -0
- data/lib/bucky/core/report/screen_shot_generator.rb +24 -0
- data/lib/bucky/core/test_core/test_case_loader.rb +162 -0
- data/lib/bucky/core/test_core/test_class_generator.rb +129 -0
- data/lib/bucky/core/test_core/test_manager.rb +70 -0
- data/lib/bucky/core/test_core/test_result.rb +92 -0
- data/lib/bucky/test_equipment/evidence/evidence_generator.rb +36 -0
- data/lib/bucky/test_equipment/pageobject/base_pageobject.rb +55 -0
- data/lib/bucky/test_equipment/pageobject/pages.rb +61 -0
- data/lib/bucky/test_equipment/selenium_handler/webdriver_handler.rb +66 -0
- data/lib/bucky/test_equipment/test_case/abst_test_case.rb +49 -0
- data/lib/bucky/test_equipment/test_case/e2e_test_case.rb +70 -0
- data/lib/bucky/test_equipment/test_case/linkstatus_test_case.rb +28 -0
- data/lib/bucky/test_equipment/user_operation/user_operation_helper.rb +97 -0
- data/lib/bucky/test_equipment/user_operation/user_operation_logger.rb +15 -0
- data/lib/bucky/test_equipment/user_operation/user_operator.rb +61 -0
- data/lib/bucky/test_equipment/verifications/abst_verification.rb +13 -0
- data/lib/bucky/test_equipment/verifications/e2e_verification.rb +106 -0
- data/lib/bucky/test_equipment/verifications/js_error_checker.rb +23 -0
- data/lib/bucky/test_equipment/verifications/service_verifications.rb +62 -0
- data/lib/bucky/test_equipment/verifications/status_checker.rb +180 -0
- data/lib/bucky/tools/lint.rb +69 -0
- data/lib/bucky/utils/bucky_logger.rb +25 -0
- data/lib/bucky/utils/bucky_output.rb +23 -0
- data/lib/bucky/utils/config.rb +55 -0
- data/lib/bucky/utils/requests.rb +33 -0
- data/lib/bucky/utils/yaml_load.rb +24 -0
- data/lib/bucky/version.rb +7 -0
- data/system_testing/test_bucky_project/.bucky_home +2 -0
- data/system_testing/test_bucky_project/config/bucky_config.yml +6 -0
- data/system_testing/test_bucky_project/config/e2e_config.yml +15 -0
- data/system_testing/test_bucky_project/config/linkstatus_config.yml +3 -0
- data/system_testing/test_bucky_project/config/test_db_config.yml +8 -0
- data/system_testing/test_bucky_project/services/README.md +1 -0
- data/system_testing/test_bucky_project/services/service_a/pc/pageobject/index.rb +13 -0
- data/system_testing/test_bucky_project/services/service_a/pc/parts/index.yml +6 -0
- data/system_testing/test_bucky_project/services/service_a/pc/scenarios/e2e/pc_e2e.yml +68 -0
- data/system_testing/test_bucky_project/services/service_a/pc/scenarios/e2e/setup_each_pc_e2e.yml +20 -0
- data/system_testing/test_bucky_project/services/service_a/pc/scenarios/e2e/setup_teardown_each_pc_e2e.yml +35 -0
- data/system_testing/test_bucky_project/services/service_a/pc/scenarios/e2e/teardown_each_pc_e2e.yml +20 -0
- data/system_testing/test_bucky_project/services/service_a/pc/scenarios/linkstatus/pc_link.yml +10 -0
- data/system_testing/test_bucky_project/services/service_a/sp/pageobject/index.rb +14 -0
- data/system_testing/test_bucky_project/services/service_a/sp/parts/index.yml +6 -0
- data/system_testing/test_bucky_project/services/service_a/sp/scenarios/e2e/sp_e2e_test.yml +26 -0
- data/system_testing/test_bucky_project/services/service_a/sp/scenarios/linkstatus/sp_link.yml +10 -0
- data/system_testing/test_bucky_project/services/service_a/tablet/pageobject/index.rb +14 -0
- data/system_testing/test_bucky_project/services/service_a/tablet/parts/index.yml +6 -0
- data/system_testing/test_bucky_project/services/service_a/tablet/scenarios/e2e/tablet_e2e_test.yml +26 -0
- data/system_testing/test_bucky_project/system/evidences/README.md +1 -0
- data/system_testing/test_bucky_project/system/evidences/screen_shots/README.md +1 -0
- data/system_testing/test_bucky_project/system/logs/README.md +1 -0
- data/system_testing/test_specification.md +38 -0
- data/system_testing/testing_code/command.bats +42 -0
- data/system_testing/testing_code/e2e.bats +75 -0
- data/system_testing/testing_code/linkstatus.bats +24 -0
- data/template/make_page/pc/pageobject/sample_page.rb +23 -0
- data/template/make_page/pc/parts/sample_page.yml +9 -0
- data/template/make_page/sp/pageobject/sample_page.rb +24 -0
- data/template/make_page/sp/parts/sample_page.yml +9 -0
- data/template/make_page/tablet/pageobject/sample_page.rb +24 -0
- data/template/make_page/tablet/parts/sample_page.yml +9 -0
- data/template/new/.bucky_home +2 -0
- data/template/new/config/bucky_config.yml +6 -0
- data/template/new/config/e2e_config.yml +15 -0
- data/template/new/config/linkstatus_config.yml +3 -0
- data/template/new/config/test_db_config.yml +8 -0
- data/template/new/services/README.md +1 -0
- data/template/new/system/evidences/README.md +1 -0
- data/template/new/system/evidences/screen_shots/README.md +1 -0
- data/template/new/system/logs/README.md +1 -0
- metadata +415 -0
@@ -0,0 +1,195 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './db_connector'
|
4
|
+
require_relative '../../utils/config'
|
5
|
+
|
6
|
+
module Bucky
|
7
|
+
module Core
|
8
|
+
module Database
|
9
|
+
class TestDataOperator
|
10
|
+
def initialize
|
11
|
+
@connector = DbConnector.new
|
12
|
+
@connector.connect
|
13
|
+
@config = Bucky::Utils::Config.instance
|
14
|
+
end
|
15
|
+
|
16
|
+
# Save job data and return job id
|
17
|
+
# @param [Time] start_time
|
18
|
+
# @return [Fixnum] job_id
|
19
|
+
def save_job_record_and_get_job_id(start_time, command_and_option)
|
20
|
+
return 0 if $debug
|
21
|
+
|
22
|
+
job_id = @connector.con[:jobs].insert(start_time: start_time, command_and_option: command_and_option)
|
23
|
+
@connector.disconnect
|
24
|
+
job_id
|
25
|
+
end
|
26
|
+
|
27
|
+
# Save test result
|
28
|
+
# @param [Hash] test_suite_result test data for Sequel
|
29
|
+
def save_test_result(test_suite_result)
|
30
|
+
@connector.con[:test_case_results].import(test_suite_result[:column], test_suite_result[:data_set])
|
31
|
+
@connector.disconnect
|
32
|
+
end
|
33
|
+
|
34
|
+
# Add test_suites.id to loaded suite data
|
35
|
+
# @return [Array] test_suite_data
|
36
|
+
def add_suite_id_to_loaded_suite_data(test_suite_data)
|
37
|
+
return test_suite_data if $debug
|
38
|
+
|
39
|
+
test_suite_data.each_with_index do |test_data, i|
|
40
|
+
suite = get_test_suite_from_test_data(test_data)
|
41
|
+
test_suite_data[i][:test_suite_id] = suite[:id]
|
42
|
+
end
|
43
|
+
@connector.disconnect
|
44
|
+
test_suite_data
|
45
|
+
end
|
46
|
+
|
47
|
+
# Save test suite data
|
48
|
+
def update_test_suites_data(test_suite_data)
|
49
|
+
return if $debug
|
50
|
+
|
51
|
+
test_suite_data.each do |test_data|
|
52
|
+
saved_test_suite = get_test_suite_from_test_data(test_data)
|
53
|
+
suite_id = get_suite_id_from_saved_test_suite(saved_test_suite, test_data)
|
54
|
+
test_data[:suite][:cases].each do |test_case|
|
55
|
+
labels = get_labels_from_suite_and_case(test_data[:suite][:labels], test_case[:labels])
|
56
|
+
label_ids = insert_and_return_label_ids(labels)
|
57
|
+
update_test_case_and_test_case_label(suite_id, test_case, label_ids)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
@connector.disconnect
|
61
|
+
end
|
62
|
+
|
63
|
+
# Return file path and CaseName that failed at last time.
|
64
|
+
# @return [Hash] re_test_cond
|
65
|
+
def get_ng_test_cases_at_last_execution(cond)
|
66
|
+
re_test_cond = {}
|
67
|
+
return {} if $debug
|
68
|
+
|
69
|
+
cases = @connector.con[:test_case_results].filter(cond).select(:test_case_id).all.map { |row| row[:test_case_id] }
|
70
|
+
Sequel.split_symbols = true # To use test_cases__id
|
71
|
+
suites_and_cases = @connector.con[:test_cases]
|
72
|
+
.left_join(:test_suites, id: Sequel.qualify('test_cases', 'test_suite_id'))
|
73
|
+
.where(test_cases__id: cases).all
|
74
|
+
# Created data
|
75
|
+
# {
|
76
|
+
# 1 => {file_path: "/hoge/fuga.yml", cases_names: ["hogehoge_hoge_1", "hogehoge_hoge_2"]},
|
77
|
+
# 2 => {file_path: "/gefu/hugo.yml", cases_names: ["hogehoge_hoge_1", "hogehoge_hoge_2"]},
|
78
|
+
# }
|
79
|
+
suites_and_cases.each do |suite_case|
|
80
|
+
suite_id = suite_case[:test_suite_id]
|
81
|
+
if re_test_cond.key? suite_id
|
82
|
+
re_test_cond[suite_id][:case_names].push suite_case[:case_name]
|
83
|
+
else
|
84
|
+
re_test_cond[suite_id] = {
|
85
|
+
file_path: suite_case[:file_path],
|
86
|
+
case_names: [suite_case[:case_name]]
|
87
|
+
}
|
88
|
+
end
|
89
|
+
end
|
90
|
+
re_test_cond
|
91
|
+
end
|
92
|
+
|
93
|
+
def get_test_case_id(test_suite_id, case_name)
|
94
|
+
return nil if $debug
|
95
|
+
|
96
|
+
test_case = @connector.con[:test_cases].filter(test_suite_id: test_suite_id, case_name: case_name).first
|
97
|
+
@connector.disconnect
|
98
|
+
raise "Cannot get test_case id. test_suite_id: #{test_suite_id}, case_name: #{case_name}" if test_case.nil?
|
99
|
+
|
100
|
+
test_case[:id]
|
101
|
+
end
|
102
|
+
|
103
|
+
# Return last round
|
104
|
+
# @param [Int] job_id
|
105
|
+
# @return [Int] round
|
106
|
+
def get_last_round_from_job_id(job_id)
|
107
|
+
round = @connector.con[:test_case_results].where(job_id: job_id).max(:round)
|
108
|
+
@connector.disconnect
|
109
|
+
round
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
|
114
|
+
# Common method for getting suite
|
115
|
+
def get_test_suite_from_test_data(test_data)
|
116
|
+
@connector.con[:test_suites].filter(
|
117
|
+
test_category: test_data[:test_category],
|
118
|
+
service: test_data[:suite][:service],
|
119
|
+
device: test_data[:suite][:device],
|
120
|
+
test_suite_name: test_data[:test_suite_name]
|
121
|
+
).first
|
122
|
+
end
|
123
|
+
|
124
|
+
def get_suite_id_from_saved_test_suite(saved_test_suite, test_data)
|
125
|
+
file_path = "services/#{test_data[:suite][:service]}/#{test_data[:suite][:device]}/scenarios/#{test_data[:test_category]}/#{test_data[:test_suite_name]}.yml"
|
126
|
+
if saved_test_suite
|
127
|
+
@connector.con[:test_suites].where(id: saved_test_suite[:id]).update(
|
128
|
+
priority: test_data[:suite][:priority].to_s,
|
129
|
+
test_suite_name: test_data[:test_suite_name],
|
130
|
+
suite_description: test_data[:suite][:desc],
|
131
|
+
github_url: @config[:test_code_repo],
|
132
|
+
file_path: file_path
|
133
|
+
)
|
134
|
+
saved_test_suite[:id]
|
135
|
+
else # If there is no test_suite, save new record and return suite_id.
|
136
|
+
@connector.con[:test_suites].insert(
|
137
|
+
test_category: test_data[:test_category],
|
138
|
+
service: test_data[:suite][:service],
|
139
|
+
device: test_data[:suite][:device],
|
140
|
+
priority: test_data[:suite][:priority].to_s,
|
141
|
+
test_suite_name: test_data[:test_suite_name],
|
142
|
+
suite_description: test_data[:suite][:desc],
|
143
|
+
github_url: @config[:test_code_repo],
|
144
|
+
file_path: file_path
|
145
|
+
)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# Return array contains suite and case
|
150
|
+
def get_labels_from_suite_and_case(suite_labels, case_labels)
|
151
|
+
[suite_labels, case_labels].flatten.compact.uniq
|
152
|
+
end
|
153
|
+
|
154
|
+
# Return label ids if case has labels, else return nil
|
155
|
+
def insert_and_return_label_ids(labels)
|
156
|
+
label_ids = []
|
157
|
+
return nil if labels.empty?
|
158
|
+
|
159
|
+
labels.each do |label_name|
|
160
|
+
label = @connector.con[:labels].filter(label_name: label_name).first
|
161
|
+
label_ids << if label
|
162
|
+
label[:id]
|
163
|
+
else
|
164
|
+
@connector.con[:labels].insert(label_name: label_name)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
label_ids
|
168
|
+
end
|
169
|
+
|
170
|
+
def update_test_case_and_test_case_label(suite_id, test_case, label_ids)
|
171
|
+
saved_test_case = @connector.con[:test_cases].filter(test_suite_id: suite_id, case_name: test_case[:case_name]).first
|
172
|
+
if saved_test_case
|
173
|
+
# Update case data
|
174
|
+
@connector.con[:test_cases].where(id: saved_test_case[:id]).update(case_name: test_case[:case_name], case_description: test_case[:desc])
|
175
|
+
# Update label of case
|
176
|
+
# At first, delete case connection
|
177
|
+
@connector.con[:test_case_labels].filter(test_case_id: saved_test_case[:id]).delete
|
178
|
+
# Create new connection
|
179
|
+
# If there is no labels, return nil
|
180
|
+
label_ids&.each do |label_id|
|
181
|
+
@connector.con[:test_case_labels].insert(test_case_id: saved_test_case[:id], label_id: label_id)
|
182
|
+
end
|
183
|
+
else
|
184
|
+
# Add case data
|
185
|
+
test_case_id = @connector.con[:test_cases].insert(test_suite_id: suite_id, case_name: test_case[:case_name], case_description: test_case[:desc])
|
186
|
+
# If there is no labels, return nil
|
187
|
+
label_ids&.each do |label_id|
|
188
|
+
@connector.con[:test_case_labels].insert(test_case_id: test_case_id, label_id: label_id)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../utils/bucky_logger'
|
4
|
+
require_relative '../../utils/config'
|
5
|
+
|
6
|
+
module Bucky
|
7
|
+
module Core
|
8
|
+
module Exception
|
9
|
+
class BuckyException
|
10
|
+
include Bucky::Utils::BuckyLogger
|
11
|
+
class << self
|
12
|
+
# Error handling on bucky framework
|
13
|
+
# @param [Object] err exception object
|
14
|
+
def handle(err)
|
15
|
+
Bucky::Utils::BuckyLogger.write(Bucky::Utils::Config.instance[:bucky_error], err)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class DbConnectorException < Bucky::Core::Exception::BuckyException
|
21
|
+
class << self
|
22
|
+
def handle(err)
|
23
|
+
super
|
24
|
+
raise err
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class WebdriverException < Bucky::Core::Exception::BuckyException
|
30
|
+
class << self
|
31
|
+
def handle(err)
|
32
|
+
super
|
33
|
+
raise err
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../utils/config'
|
4
|
+
require_relative '../exception/bucky_exception'
|
5
|
+
|
6
|
+
module Bucky
|
7
|
+
module Core
|
8
|
+
module Report
|
9
|
+
module ScreenShotGenerator
|
10
|
+
# Save screen shot
|
11
|
+
# @param [Webdriver] driver
|
12
|
+
# @param [String] test_case e.g.) test_sample_app_pc_e2e_1_1
|
13
|
+
def generate_screen_shot(driver, test_case)
|
14
|
+
timestamp = Time.now.strftime('%Y%m%d_%H%M%S')
|
15
|
+
driver.save_screenshot(
|
16
|
+
Bucky::Utils::Config.instance[:screen_shot_path] + test_case << "_#{timestamp}.png"
|
17
|
+
)
|
18
|
+
rescue StandardError => e
|
19
|
+
Bucky::Core::Exception::BuckyException.handle(e)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../database/test_data_operator'
|
4
|
+
require_relative '../../utils/yaml_load'
|
5
|
+
|
6
|
+
class Hash
|
7
|
+
def deep_symbolize_keys!
|
8
|
+
deep_transform_keys! do |key|
|
9
|
+
key unless key.respond_to? :to_sym
|
10
|
+
key.to_sym
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def deep_transform_keys!(&block)
|
15
|
+
keys.each do |key|
|
16
|
+
value = delete(key)
|
17
|
+
self[yield(key)] = value.is_a?(Hash) ? value.deep_transform_keys!(&block) : value
|
18
|
+
end
|
19
|
+
self
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module Bucky
|
24
|
+
module Core
|
25
|
+
module TestCore
|
26
|
+
class TestCaseLoader
|
27
|
+
class << self
|
28
|
+
include Bucky::Utils::YamlLoad
|
29
|
+
# Load test code files and return test suite data.
|
30
|
+
# @return [Array] test suite
|
31
|
+
def load_testcode(test_cond)
|
32
|
+
return load_re_test_testcode(test_cond[:re_test_cond]) if test_cond.key? :re_test_cond
|
33
|
+
|
34
|
+
testcodes = []
|
35
|
+
service = (test_cond[:service] || ['*']).first
|
36
|
+
device = (test_cond[:device] || ['*']).first
|
37
|
+
category = (test_cond[:test_category] || ['*']).first
|
38
|
+
|
39
|
+
Dir.glob("#{$bucky_home_dir}/services/#{service}/#{device}/scenarios/#{category}/*.yml").each do |testcode_file|
|
40
|
+
testcodes << load_testcode_in_file(testcode_file, test_cond)
|
41
|
+
end
|
42
|
+
# Delete nil element
|
43
|
+
testcodes.compact
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def load_testcode_in_file(testcode_file, test_cond)
|
49
|
+
testcode_info = testcode_file.split(%r{/|\.}).reverse
|
50
|
+
test_suite_name, test_category = testcode_info[1..3]
|
51
|
+
test_class_name = test_suite_name.split('_').map(&:capitalize).join
|
52
|
+
test_suite = load_suite_file(testcode_file)
|
53
|
+
return nil unless target_in_suite_options?(test_suite, test_cond, test_suite_name)
|
54
|
+
|
55
|
+
test_suite = set_suite_option_to_case(test_suite)
|
56
|
+
refined_suite = refine_case_with_option(test_cond, test_suite)
|
57
|
+
return nil if refined_suite[:cases].empty?
|
58
|
+
|
59
|
+
{ test_class_name: test_class_name, test_suite_name: test_suite_name, test_category: test_category, suite: refined_suite }
|
60
|
+
end
|
61
|
+
|
62
|
+
def load_re_test_testcode(re_test_cond)
|
63
|
+
testcodes = []
|
64
|
+
re_test_cond.each_value do |cond|
|
65
|
+
testcode_info = cond[:file_path].split(%r{/|\.}).reverse
|
66
|
+
test_suite_name, test_category = testcode_info[1..3]
|
67
|
+
test_class_name = test_suite_name.split('_').map(&:capitalize).join
|
68
|
+
test_suite = load_suite_file(cond[:file_path])
|
69
|
+
test_suite[:cases].delete_if { |c| !cond[:case_names].include? c[:case_name] }
|
70
|
+
testcodes << { test_class_name: test_class_name, test_suite_name: test_suite_name, test_category: test_category, suite: test_suite }
|
71
|
+
end
|
72
|
+
testcodes
|
73
|
+
end
|
74
|
+
|
75
|
+
def load_suite_file(file)
|
76
|
+
test_suite = load_yaml(file)
|
77
|
+
test_suite.deep_symbolize_keys!
|
78
|
+
test_suite[:setup_each][:procs].each(&:deep_symbolize_keys!) if test_suite[:setup_each]
|
79
|
+
test_suite[:teardown_each][:procs].each(&:deep_symbolize_keys!) if test_suite[:teardown_each]
|
80
|
+
test_suite[:cases].each do |c|
|
81
|
+
c.deep_symbolize_keys!
|
82
|
+
next unless c.key? :procs
|
83
|
+
|
84
|
+
c[:procs].each do |p|
|
85
|
+
c[:procs].delete(p) unless when_match?(p)
|
86
|
+
p.deep_symbolize_keys!
|
87
|
+
end
|
88
|
+
end
|
89
|
+
test_suite
|
90
|
+
rescue StandardError => ex
|
91
|
+
raise ex, "loading #{file}, #{ex.message}"
|
92
|
+
end
|
93
|
+
|
94
|
+
def when_match?(proc)
|
95
|
+
return true unless proc.key?('when')
|
96
|
+
raise StandardError, 'Please input correct condition' unless [true, false].include?(proc['when'])
|
97
|
+
|
98
|
+
proc['when']
|
99
|
+
end
|
100
|
+
|
101
|
+
# Return true if match suite condition
|
102
|
+
# Only priority and suite name
|
103
|
+
def target_in_suite_options?(test_suite, test_cond, test_suite_name)
|
104
|
+
# priority
|
105
|
+
return false unless check_option_include_target?(test_cond[:priority], test_suite[:priority])
|
106
|
+
# suite_name
|
107
|
+
return false unless check_option_include_target?(test_cond[:suite_name], test_suite_name)
|
108
|
+
|
109
|
+
true
|
110
|
+
end
|
111
|
+
|
112
|
+
# Return true, if target includes specified option
|
113
|
+
def check_option_include_target?(option, target)
|
114
|
+
# If there is no option, return nil.
|
115
|
+
if option.nil?
|
116
|
+
nil
|
117
|
+
else
|
118
|
+
return false unless option.include?(target)
|
119
|
+
end
|
120
|
+
true
|
121
|
+
end
|
122
|
+
|
123
|
+
# set suite option to case e.g.) suite's labels are inherited by test cases
|
124
|
+
# only label
|
125
|
+
def set_suite_option_to_case(test_suite)
|
126
|
+
return test_suite unless test_suite.key?(:labels)
|
127
|
+
|
128
|
+
# Pattern of value is different depending on how to write (string/array)
|
129
|
+
# change to array on all pattern
|
130
|
+
test_suite[:labels] = [test_suite[:labels]].flatten
|
131
|
+
test_suite[:cases].each do |c|
|
132
|
+
c[:labels] = if c.key?(:labels)
|
133
|
+
[c[:labels]].flatten | test_suite[:labels]
|
134
|
+
else
|
135
|
+
test_suite[:labels]
|
136
|
+
end
|
137
|
+
end
|
138
|
+
test_suite
|
139
|
+
end
|
140
|
+
|
141
|
+
# Filter with option
|
142
|
+
def refine_case_with_option(test_cond, suite)
|
143
|
+
# Filtering by label
|
144
|
+
if test_cond.key? :label
|
145
|
+
# Delete test case that have no label
|
146
|
+
# Pattern of value is different depending on how to write (string/array)
|
147
|
+
# Change to array on all pattern
|
148
|
+
suite[:cases].delete_if { |c| c[:labels].nil? }
|
149
|
+
suite[:cases].delete_if { |c| !(test_cond[:label].sort - [c[:labels]].flatten.sort).empty? }
|
150
|
+
end
|
151
|
+
# If there is no option, do nothing.
|
152
|
+
return suite unless test_cond.key? :case
|
153
|
+
|
154
|
+
# Delete test case doesn't match
|
155
|
+
suite[:cases].delete_if { |c| !test_cond[:case].include? c[:case_name] }
|
156
|
+
suite
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../test_equipment/test_case/e2e_test_case'
|
4
|
+
require_relative '../../test_equipment/test_case/linkstatus_test_case'
|
5
|
+
|
6
|
+
module Bucky
|
7
|
+
module Core
|
8
|
+
module TestCore
|
9
|
+
# For creating class dynamically.
|
10
|
+
class TestClasses
|
11
|
+
end
|
12
|
+
|
13
|
+
module TestClassGeneratorHelper
|
14
|
+
private
|
15
|
+
|
16
|
+
def add_test_procedure(procedures)
|
17
|
+
procedures.each.with_index(1) do |procedure, index|
|
18
|
+
puts " #{index}:#{procedure[:proc]}" if procedure.key?(:proc)
|
19
|
+
method = procedure[:exec].key?(:operate) ? :operate : :verify
|
20
|
+
send(method, procedure[:exec])
|
21
|
+
check_js_error
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def make_test_method_name(data, test_case, index)
|
26
|
+
if test_case[:case_name].nil?
|
27
|
+
return [
|
28
|
+
'test',
|
29
|
+
data[:suite][:service],
|
30
|
+
data[:suite][:device],
|
31
|
+
data[:test_category],
|
32
|
+
data[:test_suite_name],
|
33
|
+
index.to_s
|
34
|
+
].join('_')
|
35
|
+
end
|
36
|
+
"test_#{test_case[:case_name]}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class TestClassGenerator
|
41
|
+
attr_accessor :test_classes
|
42
|
+
|
43
|
+
def initialize(test_cond)
|
44
|
+
@test_classes = TestClasses
|
45
|
+
@test_cond = test_cond
|
46
|
+
end
|
47
|
+
|
48
|
+
# Genrate test class by test suite and test case data
|
49
|
+
def generate_test_class(data, link_status_url_log)
|
50
|
+
test_cond = @test_cond
|
51
|
+
# Common proccessing
|
52
|
+
# e.g.) TestSampleAppPcE2e1, TestSampleAppPcHttpstatus1
|
53
|
+
test_class_name = make_test_class_name(data)
|
54
|
+
# Select super class by test category
|
55
|
+
super_suite_class = eval format('Bucky::TestEquipment::TestCase::%<test_category>sTestCase', test_category: data[:test_category].capitalize)
|
56
|
+
# Define test suite class
|
57
|
+
test_classes.const_set(test_class_name.to_sym, Class.new(super_suite_class) do |_klass|
|
58
|
+
extend TestClassGeneratorHelper
|
59
|
+
include TestClassGeneratorHelper
|
60
|
+
define_method(:suite_data, proc { data[:suite] })
|
61
|
+
define_method(:suite_id, proc { data[:test_suite_id] })
|
62
|
+
define_method(:simple_test_class_name) do |original_name|
|
63
|
+
match_obj = /\Atest_(.+)\(.+::(Test.+)\)\z/.match(original_name)
|
64
|
+
"#{match_obj[1]}(#{match_obj[2]})"
|
65
|
+
end
|
66
|
+
|
67
|
+
# Class structure is different for each test category
|
68
|
+
case data[:test_category]
|
69
|
+
when 'linkstatus' then
|
70
|
+
data[:suite][:cases].each_with_index do |t_case, i|
|
71
|
+
method_name = make_test_method_name(data, t_case, i)
|
72
|
+
description(
|
73
|
+
t_case[:case_name],
|
74
|
+
define_method(method_name) do
|
75
|
+
puts "\n#{simple_test_class_name(name)}"
|
76
|
+
t_case[:urls].each do |url|
|
77
|
+
link_status_check_args = { url: url, device: data[:suite][:device], exclude_urls: data[:suite][:exclude_urls], link_check_max_times: test_cond[:link_check_max_times], url_log: link_status_url_log }
|
78
|
+
link_status_check(link_status_check_args)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
when 'e2e' then
|
85
|
+
if data[:suite][:setup_each]
|
86
|
+
def setup
|
87
|
+
super
|
88
|
+
puts "[setup]#{simple_test_class_name(name)}"
|
89
|
+
add_test_procedure(suite_data[:setup_each][:procs])
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
if data[:suite][:teardown_each]
|
94
|
+
def teardown
|
95
|
+
puts "[teardown]#{simple_test_class_name(name)}"
|
96
|
+
add_test_procedure(suite_data[:teardown_each][:procs])
|
97
|
+
super
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Generate test case method
|
102
|
+
data[:suite][:cases].each_with_index do |t_case, i|
|
103
|
+
# e.g.) test_sample_app_pc_e2e_1_2
|
104
|
+
method_name = make_test_method_name(data, t_case, i)
|
105
|
+
method_obj = proc do
|
106
|
+
puts "\n#{simple_test_class_name(name)}\n #{t_case[:desc]} ...."
|
107
|
+
add_test_procedure(t_case[:procs])
|
108
|
+
end
|
109
|
+
description(t_case[:case_name], define_method(method_name, method_obj))
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end)
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def make_test_class_name(data)
|
118
|
+
[
|
119
|
+
'Test',
|
120
|
+
data[:suite][:service].split(/_|-/).map(&:capitalize).join.to_s,
|
121
|
+
data[:suite][:device].capitalize.to_s,
|
122
|
+
data[:test_category].to_s.capitalize.to_s,
|
123
|
+
(data[:test_class_name]).to_s
|
124
|
+
].join
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|