Skip to content

Commit

Permalink
append
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeSchulze committed Sep 5, 2024
1 parent ce58d68 commit b48d127
Show file tree
Hide file tree
Showing 12 changed files with 304 additions and 150 deletions.
9 changes: 9 additions & 0 deletions addons/gdUnit4/src/core/event/GdUnitEvent.gd
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ enum {
TESTSUITE_AFTER,
TESTCASE_BEFORE,
TESTCASE_AFTER,
TESTCASE_STATISTICS,
DISCOVER_START,
DISCOVER_END,
DISCOVER_SUITE_ADDED,
Expand Down Expand Up @@ -73,6 +74,14 @@ func test_after(p_resource_path :String, p_suite_name :String, p_test_name :Stri
return self


func test_statistics(p_suite_name :String, p_test_name :String, p_statistics :Dictionary = {}) -> GdUnitEvent:
_event_type = TESTCASE_STATISTICS
_suite_name = p_suite_name
_test_name = p_test_name
_statistics = p_statistics
return self


func type() -> int:
return _event_type

Expand Down
109 changes: 86 additions & 23 deletions addons/gdUnit4/src/core/execution/GdUnitExecutionContext.gd
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@ func reports() -> Array[GdUnitReport]:
return _report_collector.reports()


func collect_reports() -> Array[GdUnitReport]:
func collect_reports(recursive: bool) -> Array[GdUnitReport]:
if not recursive:
return reports()
var current_reports := reports()
# we combine the reports of test_before(), test_after() and test() to be reported by `fire_test_ended`
for sub_context in _sub_context:
Expand Down Expand Up @@ -172,57 +174,98 @@ func add_orphan_report_teststage(p_reports :Array[GdUnitReport]) -> int:
var calculated := false
var _is_success: bool
var _is_flaky: bool
var _has_warnings: bool
var _has_failures: bool
var _has_errors: bool
var _failure_count := 0
var _orphan_count := 0
var _error_count := 0



func build_statistics() -> void:
func build_reports(recursive := true) -> Array[GdUnitReport]:
var collected_reports: Array[GdUnitReport] = collect_reports(recursive)
if recursive:
_orphan_count = collect_orphans(collected_reports)
else:
_orphan_count = count_orphans()
if _orphan_count > 0:
collected_reports.push_front(GdUnitReport.new() \
.create(GdUnitReport.WARN, 1, GdAssertMessages.orphan_detected_on_suite_setup(_orphan_count)))
_is_success = is_success()
_is_flaky = is_flaky()
_has_warnings = has_warnings()
_has_errors = has_errors()
#var has_warnings := has_warnings()
#prints(_test_case_name, "success" if _is_success else "failed", " flaky:", _is_flaky, " retries:", _test_execution_iteration, "_has_errors", _has_errors)
#prints()
_error_count = count_errors(recursive)
if !_is_success:
_has_failures = has_failures()
_failure_count = count_failures(recursive)
return collected_reports


func evaluate_test_retry_status() -> bool:
# get last test retry status
var last_test_status :GdUnitExecutionContext = _sub_context.back()
_is_success = last_test_status.is_success()
# if we have more than one sub contexts the test was rerurn and marked as flaky
_is_flaky = _sub_context.size() > 1
_has_warnings = last_test_status.has_warnings()
_has_errors = last_test_status.has_errors()
_error_count = last_test_status.count_errors(false)
# we not report failures on success tests (could contain failures from retry tests before)
if !_is_success:
_has_failures = last_test_status.has_failures()
_failure_count = last_test_status.count_failures(false)
_orphan_count = last_test_status.collect_orphans(collect_reports(false))
calculated = true
# finally cleanup the retry sub executions
_sub_context.clear()
return _is_success


# Evaluates the actual test case status by validate the sub context contains a success state
# If more than one state available the test case is executed multipe times and marked as flaky
func evaluate_test_case_status() -> bool:
if calculated:
return _is_success
_is_success = (
!has_failures() if _sub_context.is_empty() else _sub_context.any(func (context: GdUnitExecutionContext) -> bool:
return context.evaluate_test_case_status()
)
)

_is_success = is_success()
_is_flaky = is_flaky()
_has_warnings = has_warnings()
_has_errors = has_errors()
#prints(_test_case_name, "success" if _is_success else "failed", " flaky:", _is_flaky, " retries:", _test_execution_iteration, "_has_errors", _has_errors)
_sub_context.clear()
_error_count = count_errors(true)
if !_is_success:
_has_failures = has_failures()
_failure_count = count_failures(true)
_orphan_count = collect_orphans(collect_reports(false))
calculated = true

#prints(_test_case_name, "success" if _is_success else "failed", " flaky:", _is_flaky, " retries:", _test_execution_iteration, "_has_errors", _has_errors)
#_sub_context.clear()
return _is_success



func build_report_statistics(orphans :int, recursive := true) -> Dictionary:
func build_report_statistics(recursive := true) -> Dictionary:

return {
GdUnitEvent.RETRY_COUNT: _test_execution_iteration,
GdUnitEvent.ORPHAN_NODES: orphans,
GdUnitEvent.ORPHAN_NODES: _orphan_count,
GdUnitEvent.ELAPSED_TIME: _timer.elapsed_since_ms(),
GdUnitEvent.FAILED: !_is_success,
GdUnitEvent.ERRORS: has_errors(),
GdUnitEvent.WARNINGS: has_warnings(),
GdUnitEvent.ERRORS: _has_errors,
GdUnitEvent.WARNINGS: _has_warnings,
GdUnitEvent.FLAKY: _is_flaky,
GdUnitEvent.SKIPPED: has_skipped(),
GdUnitEvent.FAILED_COUNT: 0 if _is_success else count_failures(recursive),
GdUnitEvent.ERROR_COUNT: count_errors(recursive),
GdUnitEvent.FAILED_COUNT: _failure_count,
GdUnitEvent.ERROR_COUNT: _error_count,
GdUnitEvent.SKIPPED_COUNT: count_skipped(recursive)
}


func has_failures() -> bool:
return (
_sub_context.any(func(c :GdUnitExecutionContext) -> bool: return c.has_failures())
_sub_context.any(func(c :GdUnitExecutionContext) -> bool:
return c._has_failures if c.calculated else c.has_failures())
or _report_collector.has_failures()
)

Expand Down Expand Up @@ -251,13 +294,33 @@ func is_flaky() -> bool:


func is_success() -> bool:
if not calculated:
_is_success = evaluate_is_success()
_is_flaky = is_flaky()
_has_errors = has_errors()
_has_failures = has_failures()
calculated = true
return _is_success


func is_skipped() -> bool:
if test_case != null:
return test_case.is_skipped()
return false


func is_interupted() -> bool:
if test_case != null:
return test_case.is_interupted()
return false


func evaluate_is_success() -> bool:
if _sub_context.is_empty():
return not has_failures()# and not has_errors()

var failed_context := _sub_context.filter(func(c :GdUnitExecutionContext) -> bool:
return !c._is_success if c.calculated else !c.is_success())
#var sub_context_has_faild := failed_context.is_empty() or failed_context.size() < _test_execution_iteration
calculated = true
return !c.is_success())
return failed_context.is_empty() and not has_failures()# and not has_errors()


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ func _init(call_stage := true) -> void:

func _execute(context :GdUnitExecutionContext) -> void:
var test_suite := context.test_suite
var test_case := context.test_case

if _call_stage:
@warning_ignore("redundant_await")
Expand All @@ -23,16 +22,13 @@ func _execute(context :GdUnitExecutionContext) -> void:
await context.gc()
await context.error_monitor_stop()

var reports := context.build_reports()

context.build_statistics()

if context.test_case.is_skipped():
if context.is_skipped():
fire_test_skipped(context)
else:
var reports := context.collect_reports()
var orphans := context.collect_orphans(reports)
fire_event(GdUnitEvent.new()\
.test_after(test_suite.get_script().resource_path, context.get_test_suite_name(), context.get_test_case_name(), context.build_report_statistics(orphans), reports))
.test_after(test_suite.get_script().resource_path, context.get_test_suite_name(), context.get_test_case_name(), context.build_report_statistics(), reports))


func fire_test_skipped(context :GdUnitExecutionContext) -> void:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ func _execute(context :GdUnitExecutionContext) -> void:

await context.gc()
await context.error_monitor_stop()
context.evaluate_test_case_status()

# finally fire test statistics report
fire_event(GdUnitEvent.new().test_statistics(context.get_test_suite_name(), context.get_test_case_name(), context.build_report_statistics(0)))

# finally free the test instance
if is_instance_valid(context.test_case):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,9 @@ func _execute(context :GdUnitExecutionContext) -> void:
# unreference last used assert form the test to prevent memory leaks
GdUnitThreadManager.get_current_context().set_assert(null)
await context.gc()
context.build_statistics()
var reports := context.build_reports(false)

var reports := context.reports()
var orphans := context.count_orphans()
if orphans > 0:
reports.push_front(GdUnitReport.new() \
.create(GdUnitReport.WARN, 1, GdAssertMessages.orphan_detected_on_suite_setup(orphans)))

var s := context.build_report_statistics(orphans, false)
var s := context.build_report_statistics(false)
fire_event(GdUnitEvent.new().suite_after(test_suite.get_script().resource_path, test_suite.get_name(), s, reports))

GdUnitFileAccess.clear_tmp()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ func _execute(context :GdUnitExecutionContext) -> void:
if not context.test_case.is_skipped():
await _stage_test.execute(GdUnitExecutionContext.of(test_context))
await _stage_after.execute(test_context)
if test_context.is_success() or test_context.test_case.is_skipped():
if test_context.is_success() or test_context.is_skipped() or test_context.is_interupted():
break
context.evaluate_test_case_status()
context.evaluate_test_retry_status()


func set_debug_mode(debug_mode :bool = false) -> void:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,15 @@ func _execute(context: GdUnitExecutionContext) -> void:
await _stage_test.execute(GdUnitExecutionContext.of_parameterized_test(retry_test_context, current_test_case_name, test_case_parameter_set))
await _stage_after.execute(retry_test_context)
has_errors = retry_test_context.has_errors()
if retry_test_context.is_success() or retry_test_context.test_case.is_skipped() or retry_test_context.test_case.is_interupted():
if retry_test_context.is_success() or retry_test_context.is_skipped() or retry_test_context.is_interupted():
break

var is_success := test_context.evaluate_test_case_status()
var is_success := test_context.evaluate_test_retry_status()
report_test_failure(context, !is_success, has_errors, parameter_set_index)

if test_case.is_interupted():
break
context.evaluate_test_case_status()

await context.gc()


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ func _execute(context :GdUnitExecutionContext) -> void:
if not test_context.test_case.is_skipped():
await _stage_test.execute(GdUnitExecutionContext.of(test_context))
await _stage_after.execute(test_context)
if test_context.is_success() or test_context.test_case.is_skipped() or test_context.test_case.is_interupted():
if test_context.is_success() or test_context.is_skipped() or test_context.is_interupted():
break
context.evaluate_test_retry_status()


func set_debug_mode(debug_mode :bool = false) -> void:
Expand Down
7 changes: 2 additions & 5 deletions addons/gdUnit4/src/ui/parts/InspectorProgressBar.gd
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,8 @@ func _on_gdunit_event(event: GdUnitEvent) -> void:
GdUnitEvent.DISCOVER_END:
progress_init(event.total_count())

GdUnitEvent.TESTCASE_AFTER:
# we only count when the test is finished (excluding parameterized test iterrations)
# test_name:<number> indicates a parameterized test run
if event.test_name().find(":") == -1:
progress_update(1, event.is_failed() or event.is_error())
GdUnitEvent.TESTCASE_STATISTICS:
progress_update(1, event.is_failed() or event.is_error())

GdUnitEvent.TESTSUITE_AFTER:
progress_update(0, event.is_failed() or event.is_error())
3 changes: 2 additions & 1 deletion addons/gdUnit4/src/ui/parts/InspectorStatusBar.gd
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ signal failure_next()
signal failure_prevous()
signal request_discover_tests()

@warning_ignore("unused_signal")
signal tree_view_mode_changed(flat :bool)

@onready var _errors := %error_value
Expand Down Expand Up @@ -119,7 +120,7 @@ func _on_gdunit_event(event: GdUnitEvent) -> void:
status_changed(0, 0)
GdUnitEvent.TESTCASE_BEFORE:
pass
GdUnitEvent.TESTCASE_AFTER:
GdUnitEvent.TESTCASE_STATISTICS:
if event.is_error():
status_changed(event.error_count(), 0)
else:
Expand Down
Loading

0 comments on commit b48d127

Please sign in to comment.