Splitting test execution into smaller parts

58 views
Skip to first unread message

Magnus Teekivi

unread,
Mar 17, 2021, 5:03:20 PM3/17/21
to GraphWalker
Hello!

I have modelled my System Under Test (SUT) into a multi-model GraphWalker .json file. I have managed to successfully execute test runs on the whole SUT.

Now I'd like to create tests which run on specified narrower parts of the whole SUT. This would allow me to create several test methods in JUnit, each of which would test some certain portion of the SUT. This in turn improves the testing result output (each test will have pass/fail outcome once completed). Also, this splitting helps avoid interruption of the whole testing process if some specific part of the SUT has an error.

What I have come up with is an idea that each of the test methods would start with the same TestExecutor initialized with all the model implementation classes. Each test method would then apply specific generators and stop conditions to these models to ensure that the correct part of the SUT model is entered (e.g. with "a_star(reached_vertex(v_NextViewStartVertex))"), that the execution stays within intended bounds and ends according to the appropriate condition. I could create custom generators and stop conditions where necessary.

The problem I have with implementing the previous approach is that I haven't been able to programmatically set the generator and stop condition for the models in a TestExecutor instance. Here's some (hackish) code to illustrate what I have tried:

TestExecutor executor = new TestExecutor(
        FirstViewTest.class,
        SecondViewTest.class,
        ThirdViewTest.class
);
MachineConfiguration machineConfiguration = executor.getMachineConfiguration();
for (ContextConfiguration conf : machineConfiguration.getContextConfigurations()) {
    if (conf.getTestClassName().equals("FirstViewTest")) {
        conf.setPathGeneratorName("AStarPath");
        conf.setStopConditionName("ReachedVertex");
        conf.setStopConditionValue("v_EnterSecondView");
    } else if (conf.getTestClassName().equals("SecondViewTest")) {
        conf.setPathGeneratorName("AStarPath");
        conf.setStopConditionName("ReachedVertex");
        conf.setStopConditionValue("v_EnterThirdView");
    }
}

The goal of this code would be ensuring that ThirdView is entered as directly as possible. The problem is that this code doesn't work, as the generator and stop condition have no apparent effect. I would also prefer if I could pass the generator (together with a stop condition) as an object.

Could this kind of splitting be somehow achieved? Or should I use some other approach? I'm open to suggestions.

Thanks in advance,
Magnus.

Kristian Karl

unread,
Mar 19, 2021, 8:21:14 AM3/19/21
to GraphWalker
Hi,

What about the code below. Would that work for you?

TestExecutor executor = new TestExecutor(
  new FirstViewTest().setPathGenerator(new AStarPath(new ReachedVertex("v_EnterSecondView"))).setCurrentElement(new Vertex().build()),
  new SecondViewTest().setPathGenerator(new AStarPath(new ReachedVertex("SecondTest"))),
  new ThirdViewTest().setPathGenerator(new AStarPath(new ReachedVertex("ThirdTest")))
);

Magnus Teekivi

unread,
Mar 20, 2021, 3:09:44 PM3/20/21
to GraphWalker
Hello!

Thank you for the response.

Unfortunately, I get an error if I try to run the code you posted. The error looks like this:

Exception in thread "main" org.graphwalker.core.condition.StopConditionException: Context missing a model
at org.graphwalker.core.condition.ReachedStopConditionBase.validate(ReachedStopConditionBase.java:55)
at org.graphwalker.core.condition.ReachedVertex.validate(ReachedVertex.java:63)
at org.graphwalker.core.condition.ReachedStopConditionBase.setContext(ReachedStopConditionBase.java:50)
at org.graphwalker.core.generator.PathGeneratorBase.setContext(PathGeneratorBase.java:50)
at org.graphwalker.core.machine.ExecutionContext.setPathGenerator(ExecutionContext.java:138)
at com.example.runners.GraphWalkerProblemRunner.main(GraphWalkerProblemRunner.java:18)

I've put together a minimal working/problematic example that demonstrates this problem. This one has two models instead of three.
Its GitHub repo is available here:

All the best,
Magnus.

Kristian Karl

unread,
Mar 22, 2021, 4:55:30 AM3/22/21
to GraphWalker
Thanks for the provided example project, that made things a lot easier :-)

I created a PR for a suggested solution.
https://github.com/Teekivi/graphwalker-problem/pull/1

I was was incorrect in my first suggestion. The model never gets loaded by just instantiating the context classes (FirstViewTest and SecondViewTest), thus the runtime exception you saw.

So the new code looks  like this:

public static void main(String[] args) throws IOException {

  TestExecutor executor = new TestExecutor(
    FirstViewTest.class,
    SecondViewTest.class
  );

  for (Context context : executor.getMachine().getContexts()) {
    if (context instanceof FirstViewTest) {
      context.setPathGenerator(new AStarPath(new ReachedVertex("v_SecondView")));
    } else if( context instanceof SecondViewTest) {
      context.setPathGenerator(new RandomPath(new TimeDuration(10, TimeUnit.SECONDS)));
    }
  }
  executor.execute(true);
}


Kristian Karl

unread,
Mar 22, 2021, 5:03:57 AM3/22/21
to GraphWalker
And for completness, I added how to change start element.

for (Context context : executor.getMachine().getContexts()) {
  if (context instanceof FirstViewTest) {
    context.setPathGenerator(new AStarPath(new ReachedVertex("v_SecondView")));
  } else if( context instanceof SecondViewTest) {
    context.setPathGenerator(new RandomPath(new TimeDuration(10, TimeUnit.SECONDS)));
    context.setCurrentElement(context.getModel().findElements("v_SecondViewSubNode").get(0));
  }
}

Magnus Teekivi

unread,
Mar 22, 2021, 3:39:16 PM3/22/21
to GraphWalker
Thank you for the solution! This solves my problem. :)

All the best,
Magnus.
Reply all
Reply to author
Forward
0 new messages