RandomPolicy
The RandomPolicy class is the core class for random event generation strategies. It is mainly responsible for generating random events based on the current application state. This class provides a complete event generation process for the random event generation strategy. The main methods included in RandomPolicy are:
Generate a random event based on the current state.
Restart or reinstall the application based on the configuration.
Decide whether to check properties based on randomness if preconditions are met.
Introduction to the Random Event Generation Strategy
The random event generation strategy is a simple and effective strategy that can explore the application’s state space without a clear guiding path. Specifically, this strategy randomly generates events based on the current state of the application, aiming to reach unexplored states or trigger certain properties within the application. This strategy is particularly suitable for scenarios that lack explicit testing paths or require broad coverage of application states.
Flowchart of the Random Exploration Strategy
The specific execution steps are as follows:
Step 1: Check if the conditions for generating an event are met, namely whether the event count is the first event generated or whether the previous event was an application reinstall event.
Step 2: If the conditions are met, run the initializer and obtain the current state of the device.
Step 3: Determine if the current state is empty; if it is, wait for 5 seconds and return a key event named “BACK.”
Step 4: Check whether the event count is a multiple of the number of restart application events. If it is, decide based on the configuration whether to clear and reinstall the application or merely restart the application.
Step 5: Retrieve all rules that meet the preconditions. If such rules exist, log the current time and decide whether to check properties based on randomness.
Step 6: If it is decided to check properties, perform the property check. If the application needs to be restarted after the check, log the event and return an application kill process event; otherwise, do not restart the application.
Step 7: If it is decided not to check properties due to randomness, log the event and continue.
Step 8: Generate a random event based on the current application state. This includes bringing the application to the foreground (if needed), retrieving possible input events for the current state, and adding back key and rotate device events.
Step 9: Randomly select an event from the list of possible events. If the selected event is a rotate device event, select an opposing rotate event based on the direction of the last rotate event.
Step 10: Return the generated random event, which will be used for interaction with the application.
Pseudocode for the Random Event Generation Strategy
\(\textbf{Algorithm:} Random Event Generation\)
\(\textbf{Input:} None\)
\(\textbf{Output:} Generated Event\)
1Function generate_event()
2 current_state ← get_current_state()
3 if current_state is None:
4 wait(5 seconds)
5 return KeyEvent(name="BACK")
6 if event_count % number_of_events_that_restart_app == 0:
7 if clear_and_reinstall_app:
8 return ReInstallAppEvent(app)
9 else:
10 return KillAndRestartAppEvent(app)
11 rules_to_check ← get_rules_whose_preconditions_are_satisfied()
12 if len(rules_to_check) > 0:
13 if random() < 0.5:
14 check_property()
15 if restart_app_after_check_property:
16 return KillAppEvent(app)
17 return None
18 event ← generate_random_event_based_on_current_state()
19 return event
Data Structures in the RandomPolicy Class
event_count
event_count is an integer that records the number of events that have been generated.
number_of_events_that_restart_app
number_of_events_that_restart_app is an integer that records the number of events that need to be generated before restarting the application.
clear_and_reinstall_app
clear_and_reinstall_app is a boolean indicating whether to clear and reinstall the application before restarting it.
restart_app_after_check_property
restart_app_after_check_property is a boolean indicating whether to restart the application after checking properties.
Member Methods in the RandomPolicy Class
Method for Generating Random Events
generate_event
The generate_event method is used to generate a random event.
- Parameters:
None
- Returns:
The generated event object.
- Core Process:
Check whether it is necessary to run the initializer and obtain the current application state.
Decide whether to restart the application or clear and reinstall the application based on event count and settings.
Check whether there are rules that meet the preconditions, and decide whether to check properties based on randomness.
Generate a random event based on the current state.
def generate_event(self): current_state = self.from_state if current_state is None: time.sleep(5) return KeyEvent(name="BACK") if self.event_count % self.number_of_events_that_restart_app == 0: if self.clear_and_reinstall_app: return ReInstallAppEvent(self.app) return KillAndRestartAppEvent(self.app) rules_to_check = self.kea.get_rules_whose_preconditions_are_satisfied() if len(rules_to_check) > 0: if random.random() < 0.5: self.check_rule_whose_precondition_are_satisfied() if self.restart_app_after_check_property: return KillAppEvent(self.app) return None event = self.generate_random_event_based_on_current_state() return event
Member Methods for Generating Random Events
generate_random_event_based_on_current_state
The generate_random_event_based_on_current_state method is used to generate a random event based on the current state.
- Parameters:
None
- Returns:
The generated event object.
- Core Process:
Obtain the current application state.
If necessary, bring the application to the foreground.
Retrieve possible input events for the current state.
Generate an event based on a random selection.
def generate_random_event_based_on_current_state(self): current_state = self.from_state event = self.move_the_app_to_foreground_if_needed(current_state) if event is not None: return event possible_events = current_state.get_possible_input() possible_events.append(KeyEvent(name="BACK")) possible_events.append(RotateDevice()) self._event_trace += EVENT_FLAG_EXPLORE event = random.choice(possible_events) return event