Class: DecisionAgent::Dmn::DmnTester
- Inherits:
-
Object
- Object
- DecisionAgent::Dmn::DmnTester
- Defined in:
- lib/decision_agent/dmn/testing.rb
Overview
DMN Testing Framework Provides testing capabilities for DMN models
Instance Attribute Summary collapse
-
#model ⇒ Object
readonly
Returns the value of attribute model.
-
#test_results ⇒ Object
readonly
Returns the value of attribute test_results.
-
#test_scenarios ⇒ Object
readonly
Returns the value of attribute test_scenarios.
Instance Method Summary collapse
-
#add_scenario(decision_id:, inputs:, expected_output:, description: nil) ⇒ Object
Add a test scenario.
-
#clear_scenarios ⇒ Object
Clear all test scenarios.
-
#export_scenarios_to_csv(file_path) ⇒ Object
Export test scenarios to CSV.
-
#generate_coverage_report ⇒ Object
Generate test coverage report.
-
#import_scenarios_from_csv(file_path) ⇒ Object
Import test scenarios from CSV.
-
#initialize(model) ⇒ DmnTester
constructor
A new instance of DmnTester.
-
#run_all_tests ⇒ Object
Run all test scenarios.
-
#run_test(scenario, index = nil) ⇒ Object
Run a single test scenario.
Constructor Details
#initialize(model) ⇒ DmnTester
14 15 16 17 18 |
# File 'lib/decision_agent/dmn/testing.rb', line 14 def initialize(model) @model = model @test_scenarios = [] @test_results = [] end |
Instance Attribute Details
#model ⇒ Object (readonly)
Returns the value of attribute model.
12 13 14 |
# File 'lib/decision_agent/dmn/testing.rb', line 12 def model @model end |
#test_results ⇒ Object (readonly)
Returns the value of attribute test_results.
12 13 14 |
# File 'lib/decision_agent/dmn/testing.rb', line 12 def test_results @test_results end |
#test_scenarios ⇒ Object (readonly)
Returns the value of attribute test_scenarios.
12 13 14 |
# File 'lib/decision_agent/dmn/testing.rb', line 12 def test_scenarios @test_scenarios end |
Instance Method Details
#add_scenario(decision_id:, inputs:, expected_output:, description: nil) ⇒ Object
Add a test scenario
21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/decision_agent/dmn/testing.rb', line 21 def add_scenario(decision_id:, inputs:, expected_output:, description: nil) scenario = { decision_id: decision_id, inputs: inputs, expected_output: expected_output, description: description || "Test #{@test_scenarios.size + 1}" } @test_scenarios << scenario scenario end |
#clear_scenarios ⇒ Object
Clear all test scenarios
188 189 190 191 |
# File 'lib/decision_agent/dmn/testing.rb', line 188 def clear_scenarios @test_scenarios = [] @test_results = [] end |
#export_scenarios_to_csv(file_path) ⇒ Object
Export test scenarios to CSV
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/decision_agent/dmn/testing.rb', line 161 def export_scenarios_to_csv(file_path) require "csv" return if @test_scenarios.empty? # Collect all unique input keys input_keys = @test_scenarios.flat_map { |s| s[:inputs].keys }.uniq.sort CSV.open(file_path, "w") do |csv| # Write headers headers = ["decision_id"] + input_keys + %w[expected_output description] csv << headers # Write scenarios @test_scenarios.each do |scenario| row = [scenario[:decision_id]] input_keys.each { |key| row << scenario[:inputs][key] } row << scenario[:expected_output] row << scenario[:description] csv << row end end @test_scenarios.size end |
#generate_coverage_report ⇒ Object
Generate test coverage report
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/decision_agent/dmn/testing.rb', line 97 def generate_coverage_report coverage = { total_decisions: @model.decisions.size, tested_decisions: Set.new, untested_decisions: [], decision_coverage: {} } # Track which decisions are tested @test_scenarios.each do |scenario| coverage[:tested_decisions].add(scenario[:decision_id]) end # Find untested decisions @model.decisions.each do |decision| coverage[:untested_decisions] << decision.id unless coverage[:tested_decisions].include?(decision.id) # Calculate coverage for each decision decision_tests = @test_scenarios.select { |s| s[:decision_id] == decision.id } coverage[:decision_coverage][decision.id] = { test_count: decision_tests.size, tested: !decision_tests.empty? } # For decision tables, calculate rule coverage if decision.decision_table rule_coverage = calculate_rule_coverage(decision, decision_tests) coverage[:decision_coverage][decision.id][:rule_coverage] = rule_coverage end end coverage[:coverage_percentage] = if coverage[:total_decisions].positive? (coverage[:tested_decisions].size.to_f / coverage[:total_decisions] * 100).round(2) else 0 end coverage end |
#import_scenarios_from_csv(file_path) ⇒ Object
Import test scenarios from CSV
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/decision_agent/dmn/testing.rb', line 138 def import_scenarios_from_csv(file_path) require "csv" CSV.foreach(file_path, headers: true) do |row| inputs = {} row.headers.each do |header| next if %w[decision_id expected_output description].include?(header) inputs[header] = parse_value(row[header]) end add_scenario( decision_id: row["decision_id"], inputs: inputs, expected_output: parse_value(row["expected_output"]), description: row["description"] ) end @test_scenarios.size end |
#run_all_tests ⇒ Object
Run all test scenarios
34 35 36 37 38 39 40 41 42 43 |
# File 'lib/decision_agent/dmn/testing.rb', line 34 def run_all_tests @test_results = [] @test_scenarios.each_with_index do |scenario, idx| result = run_test(scenario, idx) @test_results << result end generate_test_report end |
#run_test(scenario, index = nil) ⇒ Object
Run a single test scenario
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/decision_agent/dmn/testing.rb', line 46 def run_test(scenario, index = nil) decision = @model.find_decision(scenario[:decision_id]) unless decision return { index: index, scenario: scenario, status: :error, error: "Decision '#{scenario[:decision_id]}' not found", passed: false } end begin # Create evaluator for this decision evaluator = Evaluators::DmnEvaluator.new( dmn_model: @model, decision_id: scenario[:decision_id] ) # Evaluate with test inputs context = Context.new(scenario[:inputs]) result = evaluator.evaluate(context: context) # Compare result with expected output actual_output = result.decision expected_output = scenario[:expected_output] passed = outputs_match?(actual_output, expected_output) { index: index, scenario: scenario, status: :completed, actual_output: actual_output, expected_output: expected_output, passed: passed, result: result } rescue StandardError => e { index: index, scenario: scenario, status: :error, error: e., passed: false } end end |