note description: "An Eiffel test suite" legal: "See notice at end of class." status: "See notice at end of class." deferred class EW_EIFFEL_TEST_SUITE inherit EW_EIFFEL_TEST_CONSTANTS EW_PREDEFINED_VARIABLES EW_OS_ACCESS EXCEPTIONS EW_SHARED_OBJECTS REFACTORING_HELPER feature -- Creation make (list: LIST [EW_NAMED_EIFFEL_TEST]; dir: READABLE_STRING_32; env: EW_TEST_ENVIRONMENT) -- Create `Current' with list of Eiffel tests `list', -- test suite directory `dir' and intiial -- environment for each test `env'. require test_list_not_void: list /= Void directory_not_void: dir /= Void environment_not_void: env /= Void do test_list := list test_suite_directory := dir test_suite_environment := env end feature -- Execution execute (opts: EW_TEST_SUITE_OPTIONS) -- Execute `Current' as modified by options `opts' -- and display the results -- of each test and pass/fail statistics on all tests. -- Leave the number of tests which passed in -- `pass_count' and the number which failed in -- `fail_count'. require options_not_void: opts /= Void deferred end feature -- Statistics pass_count: INTEGER -- Number of tests which have passed so far fail_count: INTEGER -- Number of tests which have failed so far manual_count: INTEGER -- Number of tests which were not executed because -- they were marked as requiring manual execution skip_count: INTEGER -- Number of tests which were not executed because -- they were marked as "skip" (does not include -- any tests which require manual execution) feature {NONE} -- Implementation test_list: LIST [EW_NAMED_EIFFEL_TEST] -- List of all tests to be performed. test_suite_environment: EW_TEST_ENVIRONMENT -- Common environment shared by all tests in the -- test suite (possibly augmented by other -- definitions before each test is started). feature {EW_EIFFEL_TEST_EXECUTOR} -- Implementation test_suite_directory: READABLE_STRING_32 -- Name of the directory in which test -- suite is to be executed. Each test is -- conducted in a sub-directory of the test -- directory. initial_environment (test: EW_NAMED_EIFFEL_TEST): EW_TEST_ENVIRONMENT -- Initial environment environment in which to -- execute `test'. The result may be safely -- modified by the caller. require test_not_void: test /= Void local test_dir, gen_dir, exec_dir: READABLE_STRING_32 do Result := test_suite_environment.deep_twin test_dir := os.full_directory_name (test_suite_directory, test.last_source_directory_component) associate (Result, Test_dir_name, test_dir) associate (Result, Cluster_dir_name, os.full_directory_name (test_dir, {STRING_32} "clusters")) associate (Result, Output_dir_name, os.full_directory_name (test_dir, {STRING_32} "output")) fixme ("set correct directory depending on used target") gen_dir := os.full_directory_name (test_dir, Eiffel_gen_directory) gen_dir := os.full_directory_name (gen_dir, Default_target_name) exec_dir := os.full_directory_name (gen_dir, Work_c_code_directory) Result.define (Work_execution_dir_name, exec_dir) exec_dir := os.full_directory_name (gen_dir, Final_c_code_directory) Result.define (Final_execution_dir_name, exec_dir) ensure result_not_void: Result /= Void end associate (env: EW_TEST_ENVIRONMENT; var: READABLE_STRING_32; dir: READABLE_STRING_32) -- Define an environment variable `var' in the -- environment `env' to have -- value `dir', which must be a directory name. -- Create the directory `dir' if it does not exist. require environment_not_void: env /= Void var_name_not_void: var /= Void directory_not_void: dir /= Void local d: DIRECTORY do env.define (var, dir) create d.make_with_name (dir) if not d.exists then d.create_dir end end feature {NONE} -- Output announce_start (test: EW_NAMED_EIFFEL_TEST) -- Announce the start of execution of `test' require test_not_void: test /= Void do output.append ("Test ", False) output.append_32 (test.test_name, False) output.append (" (", False) output.append_32 (test.last_source_directory_component, False) output.append (")", False) output.flush end display_results (test: EW_NAMED_EIFFEL_TEST) -- Display the status of execution of `test'. require test_not_void: test /= Void do if attached test.last_test as t and then not t.test_name.same_string_general (test.test_name) then -- Test has different name than named test output.append (" [", False) output.append_32 (t.test_name, False) output.append ("]", False) end output.append (": ", False) if test.manual_execution_required then output.append ("manual", True) elseif test.skip_requested then output.append ("skipped", True) elseif test.last_ok then output.append ("passed", True) else output.append_error ("failed", True) output.append ("%TDescription: ", False) if test.last_test /= Void then output.append_32 (test.last_test.test_description, False) else output.append ("(Not available)", False) end output.append_new_line test.errors.display end output.flush end update_statistics (test: EW_NAMED_EIFFEL_TEST) -- Update cumulative statistics for a test, -- based on the result of `test' if it was executed -- and on its characteristics if it was not executed require test_not_void: test /= Void do if test.manual_execution_required then manual_count := manual_count + 1 elseif test.skip_requested then skip_count := skip_count + 1 elseif test.last_ok then pass_count := pass_count + 1 else fail_count := fail_count + 1 end end display_summary -- Display a summary of results of executing -- all tests in the suite local total: INTEGER do total := pass_count + fail_count + manual_count + skip_count output.append_new_line if total = 0 then output.append ("No tests selected", True) else display_stats_if_nonzero ("Passed", pass_count, total) display_stats_if_nonzero ("Failed", fail_count, total) display_stats_if_nonzero ("Manual", manual_count, total) display_stats_if_nonzero ("Skipped", skip_count, total) end output.append_new_line end display_stats_if_nonzero (status: STRING; num, total: INTEGER) -- Display statistics for tests. `num' tests out -- of a total of `total' tests completed with -- status `status'. do if num > 0 then output.append (status, False) output.append (": ", False) output.append (num.out, False) output.append (" / ", False) output.append (total.out, False) output.append (" (", False) output.append (percent (num, total).out, False) output.append ("%%)", True) end end; percent (num, denom: INTEGER): INTEGER -- Percentage represented by `num' / `denom' do Result := (num.to_real / denom.to_real * 100.0 + .49999).rounded end note date: "$Date$" revision: "$Revision$" copyright: "[ Copyright (c) 1984-2018, University of Southern California, Eiffel Software and contributors. All rights reserved. ]" license: "Your use of this work is governed under the terms of the GNU General Public License version 2" copying: "[ This file is part of the EiffelWeasel Eiffel Regression Tester. The EiffelWeasel Eiffel Regression Tester is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. The EiffelWeasel Eiffel Regression Tester is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License version 2 for more details. You should have received a copy of the GNU General Public License version 2 along with the EiffelWeasel Eiffel Regression Tester if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA ]" end