bucky-core 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +66 -0
  3. data/.codeclimate.yml +48 -0
  4. data/.dockerignore +11 -0
  5. data/.gitignore +40 -0
  6. data/.rspec +3 -0
  7. data/.rubocop.yml +76 -0
  8. data/.rubocop_todo.yml +51 -0
  9. data/Dockerfile +38 -0
  10. data/Dockerfile.system-test +44 -0
  11. data/Gemfile +4 -0
  12. data/Gemfile.lock +115 -0
  13. data/LICENSE +201 -0
  14. data/README.md +246 -0
  15. data/Rakefile +8 -0
  16. data/bin/console +15 -0
  17. data/bin/setup +8 -0
  18. data/bucky-core.gemspec +47 -0
  19. data/docker-compose.dev-with-bm.yml +28 -0
  20. data/docker-compose.dev.yml +18 -0
  21. data/docker-compose.system-test.yml +21 -0
  22. data/docker/nginx/Dockerfile +7 -0
  23. data/docker/nginx/nginx.conf +22 -0
  24. data/docker/nginx/public/index.html +19 -0
  25. data/docker/nginx/public/test_page.html +12 -0
  26. data/exe/bucky +214 -0
  27. data/lib/bucky.rb +3 -0
  28. data/lib/bucky/core/database/db_connector.rb +29 -0
  29. data/lib/bucky/core/database/test_data_operator.rb +195 -0
  30. data/lib/bucky/core/exception/bucky_exception.rb +39 -0
  31. data/lib/bucky/core/report/screen_shot_generator.rb +24 -0
  32. data/lib/bucky/core/test_core/test_case_loader.rb +162 -0
  33. data/lib/bucky/core/test_core/test_class_generator.rb +129 -0
  34. data/lib/bucky/core/test_core/test_manager.rb +70 -0
  35. data/lib/bucky/core/test_core/test_result.rb +92 -0
  36. data/lib/bucky/test_equipment/evidence/evidence_generator.rb +36 -0
  37. data/lib/bucky/test_equipment/pageobject/base_pageobject.rb +55 -0
  38. data/lib/bucky/test_equipment/pageobject/pages.rb +61 -0
  39. data/lib/bucky/test_equipment/selenium_handler/webdriver_handler.rb +66 -0
  40. data/lib/bucky/test_equipment/test_case/abst_test_case.rb +49 -0
  41. data/lib/bucky/test_equipment/test_case/e2e_test_case.rb +70 -0
  42. data/lib/bucky/test_equipment/test_case/linkstatus_test_case.rb +28 -0
  43. data/lib/bucky/test_equipment/user_operation/user_operation_helper.rb +97 -0
  44. data/lib/bucky/test_equipment/user_operation/user_operation_logger.rb +15 -0
  45. data/lib/bucky/test_equipment/user_operation/user_operator.rb +61 -0
  46. data/lib/bucky/test_equipment/verifications/abst_verification.rb +13 -0
  47. data/lib/bucky/test_equipment/verifications/e2e_verification.rb +106 -0
  48. data/lib/bucky/test_equipment/verifications/js_error_checker.rb +23 -0
  49. data/lib/bucky/test_equipment/verifications/service_verifications.rb +62 -0
  50. data/lib/bucky/test_equipment/verifications/status_checker.rb +180 -0
  51. data/lib/bucky/tools/lint.rb +69 -0
  52. data/lib/bucky/utils/bucky_logger.rb +25 -0
  53. data/lib/bucky/utils/bucky_output.rb +23 -0
  54. data/lib/bucky/utils/config.rb +55 -0
  55. data/lib/bucky/utils/requests.rb +33 -0
  56. data/lib/bucky/utils/yaml_load.rb +24 -0
  57. data/lib/bucky/version.rb +7 -0
  58. data/system_testing/test_bucky_project/.bucky_home +2 -0
  59. data/system_testing/test_bucky_project/config/bucky_config.yml +6 -0
  60. data/system_testing/test_bucky_project/config/e2e_config.yml +15 -0
  61. data/system_testing/test_bucky_project/config/linkstatus_config.yml +3 -0
  62. data/system_testing/test_bucky_project/config/test_db_config.yml +8 -0
  63. data/system_testing/test_bucky_project/services/README.md +1 -0
  64. data/system_testing/test_bucky_project/services/service_a/pc/pageobject/index.rb +13 -0
  65. data/system_testing/test_bucky_project/services/service_a/pc/parts/index.yml +6 -0
  66. data/system_testing/test_bucky_project/services/service_a/pc/scenarios/e2e/pc_e2e.yml +68 -0
  67. data/system_testing/test_bucky_project/services/service_a/pc/scenarios/e2e/setup_each_pc_e2e.yml +20 -0
  68. data/system_testing/test_bucky_project/services/service_a/pc/scenarios/e2e/setup_teardown_each_pc_e2e.yml +35 -0
  69. data/system_testing/test_bucky_project/services/service_a/pc/scenarios/e2e/teardown_each_pc_e2e.yml +20 -0
  70. data/system_testing/test_bucky_project/services/service_a/pc/scenarios/linkstatus/pc_link.yml +10 -0
  71. data/system_testing/test_bucky_project/services/service_a/sp/pageobject/index.rb +14 -0
  72. data/system_testing/test_bucky_project/services/service_a/sp/parts/index.yml +6 -0
  73. data/system_testing/test_bucky_project/services/service_a/sp/scenarios/e2e/sp_e2e_test.yml +26 -0
  74. data/system_testing/test_bucky_project/services/service_a/sp/scenarios/linkstatus/sp_link.yml +10 -0
  75. data/system_testing/test_bucky_project/services/service_a/tablet/pageobject/index.rb +14 -0
  76. data/system_testing/test_bucky_project/services/service_a/tablet/parts/index.yml +6 -0
  77. data/system_testing/test_bucky_project/services/service_a/tablet/scenarios/e2e/tablet_e2e_test.yml +26 -0
  78. data/system_testing/test_bucky_project/system/evidences/README.md +1 -0
  79. data/system_testing/test_bucky_project/system/evidences/screen_shots/README.md +1 -0
  80. data/system_testing/test_bucky_project/system/logs/README.md +1 -0
  81. data/system_testing/test_specification.md +38 -0
  82. data/system_testing/testing_code/command.bats +42 -0
  83. data/system_testing/testing_code/e2e.bats +75 -0
  84. data/system_testing/testing_code/linkstatus.bats +24 -0
  85. data/template/make_page/pc/pageobject/sample_page.rb +23 -0
  86. data/template/make_page/pc/parts/sample_page.yml +9 -0
  87. data/template/make_page/sp/pageobject/sample_page.rb +24 -0
  88. data/template/make_page/sp/parts/sample_page.yml +9 -0
  89. data/template/make_page/tablet/pageobject/sample_page.rb +24 -0
  90. data/template/make_page/tablet/parts/sample_page.yml +9 -0
  91. data/template/new/.bucky_home +2 -0
  92. data/template/new/config/bucky_config.yml +6 -0
  93. data/template/new/config/e2e_config.yml +15 -0
  94. data/template/new/config/linkstatus_config.yml +3 -0
  95. data/template/new/config/test_db_config.yml +8 -0
  96. data/template/new/services/README.md +1 -0
  97. data/template/new/system/evidences/README.md +1 -0
  98. data/template/new/system/evidences/screen_shots/README.md +1 -0
  99. data/template/new/system/logs/README.md +1 -0
  100. 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