diff --git a/src/main/scala/de/retest/guistatemachine/api/GuiStateMachine.scala b/src/main/scala/de/retest/guistatemachine/api/GuiStateMachine.scala index f973407..a6bd521 100644 --- a/src/main/scala/de/retest/guistatemachine/api/GuiStateMachine.scala +++ b/src/main/scala/de/retest/guistatemachine/api/GuiStateMachine.scala @@ -14,14 +14,12 @@ import de.retest.ui.descriptors.SutState trait GuiStateMachine { /** - * Gets a state identified by descriptors and with its initial never explored actions. + * Gets a state identified by the corresponding SUT state. * * @param sutState The SUT state which identifies the state. - * @param neverExploredActions All actions which have never been explored from the state. * @return The state identified by the descriptors. If there has not been any state yet, it will be added. */ - def getState(sutState: SutState, neverExploredActions: Set[Action]): State - def getState(sutState: SutState): State = getState(sutState, Set()) + def getState(sutState: SutState): State /** * Executes an action from a state leading to the current state described by descriptors. @@ -32,25 +30,11 @@ trait GuiStateMachine { * @return The current state which the transition of a leads to. */ def executeAction(from: State, a: Action, to: State): State - def executeAction(fromSutState: SutState, - fromNeverExploredActions: Set[Action], - a: Action, - toSutState: SutState, - toNeverExploredActions: Set[Action]): State = - executeAction(getState(fromSutState, fromNeverExploredActions), a, getState(toSutState, toNeverExploredActions)) - def executeAction(fromSutState: SutState, a: Action, toSutState: SutState): State = - executeAction(fromSutState, Set(), a, toSutState, Set()) + executeAction(fromSutState, a, toSutState) def getAllStates: Map[SutState, State] - /** - * Can be used by the GA to generate new test cases. - * - * @return All actions which have not been explored yet. - */ - def getAllNeverExploredActions: Set[Action] - /** * In the legacy code this was only used to show the number of actions which have been explored by Monkey Testing. * @@ -59,7 +43,7 @@ trait GuiStateMachine { def getAllExploredActions: Set[Action] /** - * In the legacy code this was only used to calculate [[getAllNeverExploredActions]]. + * In the legacy code this was only used to calculate all never explored actions. * It could be used for the visualization of the NFA to see how often actions are executed. * * @return The number of times every explored action has been executed in the NFA. Never explored actions are not part of it. diff --git a/src/main/scala/de/retest/guistatemachine/api/State.scala b/src/main/scala/de/retest/guistatemachine/api/State.scala index 289fb32..c1c7947 100644 --- a/src/main/scala/de/retest/guistatemachine/api/State.scala +++ b/src/main/scala/de/retest/guistatemachine/api/State.scala @@ -16,11 +16,6 @@ trait State { */ def getSutState: SutState - /** - * @return All actions which have not already been explored/executed from this state. - */ - def getNeverExploredActions: Set[Action] - /** * NFA states can lead to different states by consuming the same symbol. * Hence, we have a set of states per action. @@ -28,19 +23,6 @@ trait State { */ def getTransitions: Map[Action, ActionTransitions] - /** - * This was used in the legacy code for Monkey testing. - * - * @return Returns a random action or an empty value if there are none left. - */ - def getRandomAction(): Option[Action] = { - val r = getAllActions().toVector - if (r.isEmpty) { None } else { - val rnd = new Random() - Some(r(rnd.nextInt(r.size))) - } - } - /** * Overriding this method is required to allow the usage of a set of states. * Comparing the descriptors should check for the equality of all root elements which compares the identifying attributes and the contained components @@ -57,7 +39,7 @@ trait State { override def hashCode(): Int = this.getSutState.hashCode() - override def toString: String = s"sutState=$getSutState,neverExploredActions=$getNeverExploredActions,transitions=$getTransitions" + override def toString: String = s"sutState=$getSutState,transitions=$getTransitions" /** * Adds a new transition to the state which is only allowed by calling the methods of [[GuiStateMachine]]. @@ -67,11 +49,4 @@ trait State { * @return The number of times the action has been executed from this state. The target state does not matter for this number. */ private[api] def addTransition(a: Action, to: State): Int - - /** - * This was named `getRandomActions` in the legacy code but actually returned all actions. - * - * @return All actions (explored + unexplored). - */ - private def getAllActions(): Set[Action] = getNeverExploredActions ++ getTransitions.keySet } diff --git a/src/main/scala/de/retest/guistatemachine/api/impl/GuiStateMachineImpl.scala b/src/main/scala/de/retest/guistatemachine/api/impl/GuiStateMachineImpl.scala index 5f55ea8..51253c9 100644 --- a/src/main/scala/de/retest/guistatemachine/api/impl/GuiStateMachineImpl.scala +++ b/src/main/scala/de/retest/guistatemachine/api/impl/GuiStateMachineImpl.scala @@ -17,12 +17,6 @@ class GuiStateMachineImpl extends GuiStateMachine with Serializable { // Make it accessible from the impl package for unit tests. private var states = new HashMap[SutState, State] - /** - * In the legacy code we had `getAllNeverExploredActions` which had to collect them from all states and make sure they were never executed. - * Storing them directly in a set improves efficiency. - */ - var allNeverExploredActions = new HashSet[Action] - /** * The legacy code stored execution counters for every action. */ @@ -34,13 +28,12 @@ class GuiStateMachineImpl extends GuiStateMachine with Serializable { */ var actionExecutionTimes = new HashMap[Action, Int] - override def getState(sutState: SutState, neverExploredActions: Set[Action]): State = { + override def getState(sutState: SutState): State = { if (states.contains(sutState)) { states(sutState) } else { - allNeverExploredActions = allNeverExploredActions ++ (neverExploredActions -- allExploredActions) logger.info(s"Create new state from SUT state with hash code ${sutState.hashCode()}") - val s = new StateImpl(sutState, neverExploredActions) + val s = new StateImpl(sutState) states = states + (sutState -> s) s } @@ -48,7 +41,6 @@ class GuiStateMachineImpl extends GuiStateMachine with Serializable { override def executeAction(from: State, a: Action, to: State): State = { allExploredActions = allExploredActions + a - allNeverExploredActions = allNeverExploredActions - a val old = actionExecutionTimes.get(a) old match { case Some(o) => actionExecutionTimes = actionExecutionTimes + (a -> (o + 1)) @@ -60,15 +52,12 @@ class GuiStateMachineImpl extends GuiStateMachine with Serializable { override def getAllStates: Map[SutState, State] = states - override def getAllNeverExploredActions: Set[Action] = allNeverExploredActions - override def getAllExploredActions: Set[Action] = allExploredActions override def getActionExecutionTimes: Map[Action, Int] = actionExecutionTimes override def clear(): Unit = { states = HashMap[SutState, State]() - allNeverExploredActions = HashSet[Action]() allExploredActions = HashSet[Action]() actionExecutionTimes = HashMap[Action, Int]() } @@ -85,7 +74,6 @@ class GuiStateMachineImpl extends GuiStateMachine with Serializable { val readStateMachine = ois.readObject.asInstanceOf[GuiStateMachineImpl] ois.close() this.states = readStateMachine.states - this.allNeverExploredActions = readStateMachine.allNeverExploredActions this.allExploredActions = readStateMachine.allExploredActions this.actionExecutionTimes = readStateMachine.actionExecutionTimes } diff --git a/src/main/scala/de/retest/guistatemachine/api/impl/StateImpl.scala b/src/main/scala/de/retest/guistatemachine/api/impl/StateImpl.scala index d78e940..ec4c55a 100644 --- a/src/main/scala/de/retest/guistatemachine/api/impl/StateImpl.scala +++ b/src/main/scala/de/retest/guistatemachine/api/impl/StateImpl.scala @@ -7,7 +7,7 @@ import de.retest.ui.descriptors.SutState import scala.collection.immutable.HashMap @SerialVersionUID(1L) -class StateImpl(sutState: SutState, var neverExploredActions: Set[Action]) extends State with Serializable { +class StateImpl(sutState: SutState) extends State with Serializable { /** * TODO #4 Currently, there is no MultiMap trait for immutable maps in the Scala standard library. @@ -16,7 +16,6 @@ class StateImpl(sutState: SutState, var neverExploredActions: Set[Action]) exten var transitions = new HashMap[Action, ActionTransitions] override def getSutState: SutState = sutState - override def getNeverExploredActions: Set[Action] = neverExploredActions override def getTransitions: Map[Action, ActionTransitions] = transitions private[api] override def addTransition(a: Action, to: State): Int = { @@ -29,8 +28,6 @@ class StateImpl(sutState: SutState, var neverExploredActions: Set[Action]) exten case None => transitions += (a -> ActionTransitions(Set(to), 1)) - // In the legacy code this is done in `increaseTimesExecuted`. - neverExploredActions = neverExploredActions - a 1 } } diff --git a/src/test/scala/de/retest/guistatemachine/api/impl/GuiStateMachineApiImplSpec.scala b/src/test/scala/de/retest/guistatemachine/api/impl/GuiStateMachineApiImplSpec.scala index 749d8fc..0f85b96 100644 --- a/src/test/scala/de/retest/guistatemachine/api/impl/GuiStateMachineApiImplSpec.scala +++ b/src/test/scala/de/retest/guistatemachine/api/impl/GuiStateMachineApiImplSpec.scala @@ -4,7 +4,7 @@ import java.io.File import java.util.Arrays import de.retest.guistatemachine.api.{AbstractApiSpec, Id} -import de.retest.surili.model.actions.{Action, NavigateToAction} +import de.retest.surili.model.actions.NavigateToAction import de.retest.ui.descriptors.SutState class GuiStateMachineApiImplSpec extends AbstractApiSpec { @@ -21,7 +21,6 @@ class GuiStateMachineApiImplSpec extends AbstractApiSpec { val fsm = stateMachine.get fsm.getActionExecutionTimes.size shouldEqual 0 fsm.getAllExploredActions.size shouldEqual 0 - fsm.getAllNeverExploredActions.size shouldEqual 0 sut.removeStateMachine(stateMachineId) shouldBe true } @@ -47,16 +46,14 @@ class GuiStateMachineApiImplSpec extends AbstractApiSpec { val action1 = new NavigateToAction("http://wikipedia.org") val initialSutState = new SutState(Arrays.asList(rootElementA, rootElementB, rootElementC)) - val initialNeverExploredActions = Set[Action](action0, action1) val finalSutState = new SutState(Arrays.asList(rootElementC)) - val finalNeverExploredActions = Set[Action](action0, action1) // Create the whole state machine: sut.clear() stateMachineId = sut.createStateMachine() val stateMachine = sut.getStateMachine(stateMachineId).get - val initialState = stateMachine.getState(initialSutState, initialNeverExploredActions) - val finalState = stateMachine.getState(finalSutState, finalNeverExploredActions) + val initialState = stateMachine.getState(initialSutState) + val finalState = stateMachine.getState(finalSutState) stateMachine.executeAction(initialState, action0, finalState) // Save all state machines: @@ -75,7 +72,6 @@ class GuiStateMachineApiImplSpec extends AbstractApiSpec { val loadedStateMachine = loadedStateMachineOp.get.asInstanceOf[GuiStateMachineImpl] loadedStateMachine.getAllExploredActions.size shouldEqual 1 - loadedStateMachine.getAllNeverExploredActions.size shouldEqual 1 loadedStateMachine.getActionExecutionTimes(action0) shouldEqual 1 loadedStateMachine.getActionExecutionTimes.contains(action1) shouldEqual false loadedStateMachine.getAllStates.size shouldEqual 2 @@ -84,14 +80,12 @@ class GuiStateMachineApiImplSpec extends AbstractApiSpec { loadedInitialState.getSutState shouldEqual initialSutState loadedInitialState.getTransitions.size shouldEqual 1 loadedInitialState.getTransitions.contains(action0) shouldEqual true - loadedInitialState.getNeverExploredActions.size shouldEqual 1 val loadedTransition = loadedInitialState.getTransitions(action0) loadedTransition.executionCounter shouldEqual 1 loadedTransition.to.size shouldEqual 1 loadedTransition.to.head shouldEqual loadedFinalState loadedFinalState.getSutState shouldEqual finalSutState loadedFinalState.getTransitions.isEmpty shouldEqual true - loadedFinalState.getNeverExploredActions shouldEqual finalNeverExploredActions } } } diff --git a/src/test/scala/de/retest/guistatemachine/api/impl/GuiStateMachineImplSpec.scala b/src/test/scala/de/retest/guistatemachine/api/impl/GuiStateMachineImplSpec.scala index 1e78180..9815be7 100644 --- a/src/test/scala/de/retest/guistatemachine/api/impl/GuiStateMachineImplSpec.scala +++ b/src/test/scala/de/retest/guistatemachine/api/impl/GuiStateMachineImplSpec.scala @@ -40,67 +40,56 @@ class GuiStateMachineImplSpec extends AbstractApiSpec with BeforeAndAfterEach { "add two transitions to two new states for the same action and one transition to another state for another action" in { val initialSutState = getSutState - val initial = sut.getState(initialSutState, getNeverExploredActions) + val initial = sut.getState(initialSutState) sut.getAllExploredActions.size shouldEqual 0 - sut.getAllNeverExploredActions.size shouldEqual 2 sut.getActionExecutionTimes.size shouldEqual 0 // execute action0 for the first time val s0SutState = new SutState(Arrays.asList(rootElementA)) - val s0 = sut.getState(s0SutState, getNeverExploredActions) + val s0 = sut.getState(s0SutState) sut.executeAction(initial, action0, s0) - initial.getNeverExploredActions.size shouldEqual 1 initial.getTransitions.size shouldEqual 1 initial.getTransitions(action0).to.size shouldEqual 1 initial.getTransitions(action0).executionCounter shouldEqual 1 - s0.getNeverExploredActions.size shouldEqual 2 s0.getTransitions.size shouldEqual 0 sut.getAllExploredActions.size shouldEqual 1 - sut.getAllNeverExploredActions.size shouldEqual 1 sut.getActionExecutionTimes.get(action0).isDefined shouldEqual true sut.getActionExecutionTimes(action0) shouldEqual 1 // execute action0 for the second time val s1SutState = new SutState(Arrays.asList(rootElementB)) - val s1 = sut.getState(s1SutState, getNeverExploredActions) + val s1 = sut.getState(s1SutState) sut.executeAction(initial, action0, s1) - initial.getNeverExploredActions.size shouldEqual 1 initial.getTransitions.size shouldEqual 1 initial.getTransitions(action0).to.size shouldEqual 2 initial.getTransitions(action0).executionCounter shouldEqual 2 - s1.getNeverExploredActions.size shouldEqual 2 s1.getTransitions.size shouldEqual 0 sut.getAllExploredActions.size shouldEqual 1 - sut.getAllNeverExploredActions.size shouldEqual 1 sut.getActionExecutionTimes.get(action0).isDefined shouldEqual true sut.getActionExecutionTimes(action0) shouldEqual 2 // execute action1 for the first time val s2SutState = new SutState(Arrays.asList(rootElementC)) - val s2 = sut.getState(s2SutState, getNeverExploredActions) + val s2 = sut.getState(s2SutState) sut.executeAction(initial, action1, s2) - initial.getNeverExploredActions.size shouldEqual 0 initial.getTransitions.size shouldEqual 2 initial.getTransitions(action1).to.size shouldEqual 1 initial.getTransitions(action1).executionCounter shouldEqual 1 - s2.getNeverExploredActions.size shouldEqual 2 s2.getTransitions.size shouldEqual 0 sut.getAllExploredActions.size shouldEqual 2 - sut.getAllNeverExploredActions.size shouldEqual 0 sut.getActionExecutionTimes.get(action1).isDefined shouldEqual true sut.getActionExecutionTimes(action1) shouldEqual 1 } "store a state for the second access" in { val initialSutState = getSutState - val initialFromAccess0 = sut.getState(initialSutState, getNeverExploredActions) - val initialFromAccess1 = sut.getState(initialSutState, getNeverExploredActions) + val initialFromAccess0 = sut.getState(initialSutState) + val initialFromAccess1 = sut.getState(initialSutState) initialFromAccess0 shouldEqual initialFromAccess1 } "clear the state machine" in { sut.clear() - sut.getAllNeverExploredActions.isEmpty shouldEqual true sut.getAllExploredActions.isEmpty shouldEqual true sut.actionExecutionTimes.isEmpty shouldEqual true sut.getAllStates.isEmpty shouldEqual true @@ -119,13 +108,11 @@ class GuiStateMachineImplSpec extends AbstractApiSpec with BeforeAndAfterEach { val action1 = new NavigateToAction("http://wikipedia.org") val initialSutState = new SutState(Arrays.asList(rootElementA, rootElementB, rootElementC)) - val initialNeverExploredActions = Set[Action](action0, action1) val finalSutState = new SutState(Arrays.asList(rootElementC)) - val finalNeverExploredActions = Set[Action](action0, action1) // Create the whole state machine: - val initialState = sut.getState(initialSutState, initialNeverExploredActions) - val finalState = sut.getState(finalSutState, finalNeverExploredActions) + val initialState = sut.getState(initialSutState) + val finalState = sut.getState(finalSutState) sut.executeAction(initialState, action0, finalState) // Save the state machine: @@ -140,7 +127,6 @@ class GuiStateMachineImplSpec extends AbstractApiSpec with BeforeAndAfterEach { // Verify the loaded state machine: sut.getAllExploredActions.size shouldEqual 1 - sut.getAllNeverExploredActions.size shouldEqual 1 sut.getActionExecutionTimes(action0) shouldEqual 1 sut.getActionExecutionTimes.contains(action1) shouldEqual false sut.getAllStates.size shouldEqual 2 @@ -149,14 +135,12 @@ class GuiStateMachineImplSpec extends AbstractApiSpec with BeforeAndAfterEach { loadedInitialState.getSutState shouldEqual initialSutState loadedInitialState.getTransitions.size shouldEqual 1 loadedInitialState.getTransitions.contains(action0) shouldEqual true - loadedInitialState.getNeverExploredActions.size shouldEqual 1 val loadedTransition = loadedInitialState.getTransitions(action0) loadedTransition.executionCounter shouldEqual 1 loadedTransition.to.size shouldEqual 1 loadedTransition.to.head shouldEqual loadedFinalState loadedFinalState.getSutState shouldEqual finalSutState loadedFinalState.getTransitions.isEmpty shouldEqual true - loadedFinalState.getNeverExploredActions shouldEqual finalNeverExploredActions } "save GML " in { @@ -167,22 +151,18 @@ class GuiStateMachineImplSpec extends AbstractApiSpec with BeforeAndAfterEach { val action1 = new NavigateToAction("http://wikipedia.org") val initialSutState = new SutState(Arrays.asList(rootElementA, rootElementB, rootElementC)) - val initialNeverExploredActions = Set[Action](action0, action1) val finalSutState = new SutState(Arrays.asList(rootElementC)) - val finalNeverExploredActions = Set[Action](action0, action1) // Create the whole state machine: sut.clear() - val initialState = sut.getState(initialSutState, initialNeverExploredActions) - val finalState = sut.getState(finalSutState, finalNeverExploredActions) + val initialState = sut.getState(initialSutState) + val finalState = sut.getState(finalSutState) sut.executeAction(initialState, action0, finalState) sut.executeAction(initialState, action1, finalState) sut.executeAction(finalState, action0, initialState) sut.executeAction(finalState, action1, initialState) - initialState.getNeverExploredActions.size shouldEqual 0 initialState.getTransitions.size shouldEqual 2 - finalState.getNeverExploredActions.size shouldEqual 0 finalState.getTransitions.size shouldEqual 2 val filePath = "./target/test_state_machine.gml" diff --git a/src/test/scala/de/retest/guistatemachine/api/impl/StateImplSpec.scala b/src/test/scala/de/retest/guistatemachine/api/impl/StateImplSpec.scala index 2220ab4..474db9b 100644 --- a/src/test/scala/de/retest/guistatemachine/api/impl/StateImplSpec.scala +++ b/src/test/scala/de/retest/guistatemachine/api/impl/StateImplSpec.scala @@ -3,7 +3,7 @@ package de.retest.guistatemachine.api.impl import java.util.Arrays import de.retest.guistatemachine.api.AbstractApiSpec -import de.retest.surili.model.actions.{Action, NavigateToAction} +import de.retest.surili.model.actions.NavigateToAction import de.retest.ui.descriptors.SutState class StateImplSpec extends AbstractApiSpec { @@ -16,33 +16,23 @@ class StateImplSpec extends AbstractApiSpec { "StateImpl" should { "not equal" in { - val s0 = new StateImpl(sutStateA, Set[Action](action0)) - val s1 = new StateImpl(sutStateB, Set[Action](action1)) + val s0 = new StateImpl(sutStateA) + val s1 = new StateImpl(sutStateB) s0.equals(s1) shouldEqual false s0.equals(10) shouldEqual false s0.hashCode() should not equal s1.hashCode() } "equal" in { - val s0 = new StateImpl(sutStateA, Set[Action](action0)) - val s1 = new StateImpl(sutStateA, Set[Action](action1)) + val s0 = new StateImpl(sutStateA) + val s1 = new StateImpl(sutStateA) s0.equals(s1) shouldEqual true s0.hashCode() shouldEqual s1.hashCode() } "be converted into a string" in { - val s0 = new StateImpl(sutStateA, Set[Action](action0)) - s0.toString shouldEqual "sutState=State[descriptor=[]],neverExploredActions=Set(NavigateToAction(url=http://google.com)),transitions=Map()" - } - - "have a random action" in { - val s0 = new StateImpl(sutStateA, Set[Action](action0)) - s0.getRandomAction().isDefined shouldEqual true - } - - "have no random action" in { - val s0 = new StateImpl(sutStateA, Set()) - s0.getRandomAction().isEmpty shouldEqual true + val s0 = new StateImpl(sutStateA) + s0.toString shouldEqual "sutState=State[descriptor=[]],transitions=Map()" } } }