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.

../../_images/random_flowchart.png

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

  1. event_count

    event_count is an integer that records the number of events that have been generated.

  2. 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.

  3. clear_and_reinstall_app

    clear_and_reinstall_app is a boolean indicating whether to clear and reinstall the application before restarting it.

  4. 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:
  1. Check whether it is necessary to run the initializer and obtain the current application state.

  2. Decide whether to restart the application or clear and reinstall the application based on event count and settings.

  3. Check whether there are rules that meet the preconditions, and decide whether to check properties based on randomness.

  4. 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:
  1. Obtain the current application state.

  2. If necessary, bring the application to the foreground.

  3. Retrieve possible input events for the current state.

  4. 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