Tests Structure#

To run tests using AltWalker you need a models and tests implementing the models.

Usually your project will look like this:

test-project/
├── models/
│   └── ...
└── tests/
    └── ...

Inside the models directory you will keep your models, and inside the tests directory you will have a test package containing the implementation of the models.

Now AltWalker supports two languages: Python and C#/.NET.

Structure#

AltWalker requires a python package (usually named tests) and inside a python module named test.py.

test-project/
├── models/
│   └── ...
└── tests/
    ├── __init__.py
    └── test.py

Inside test.py each model is implemented in a class, and each vertex/edge in a method inside the class.

# tests/test.py

class ModelA:
    """The implementation of the model named ModelA."""

    def vertex_a(self):
        """The implementation of the vertex named vertex_a form ModelA."""

    def edge_a(self):
        """The implementation of the edge named edge_a form ModelA."""


class ModelB:
    """The implementation of the model named ModelB."""

    def vertex_b(self):
        """The implementation of the vertex named vertex_b form ModelB."""

    def edge_b(self):
        """The implementation of the edge named edge_b form ModelB."""

AltWalker requires a C# console application that depends on AltWalker.Executor from NuGet and runs the ExecutorService.

test-project/
├── models/
│   └── ...
└── tests/
    ├── Program.cs
    └── test-project.csproj
/// Program.cs
using Altom.AltWalker;

namespace Test.Project
{
    /// The implementation of the model named ModelA.
    public class ModelA
    {
        /// The implementation of the vertex named vertex_a.
        public void vertex_a() {}

        /// The implementation of the edge named edge_a
        public void edge_a() {}
    }

    /// The implementation of the model named ModelB.
    public class ModelB
    {
        /// The implementation of the vertex named vertex_b.
        public void vertex_b() {}

        /// The implementation of the edge named edge_b
        public void edge_b() {}
    }

    public class Program
    {
        public static void Main (string[] args)
        {
            ExecutorService service = new ExecutorService();

            service.RegisterModel<ModelA>();
            service.RegisterModel<ModelB>();

            service.Start(args);
        }
    }
}

The AltWalker.Executor targets .netstandard 2.0.

Fixtures#

AltWalker implements four test fixtures inspired by JUnit and the python unittest module:

  • setUpRun: Will be executed first, before anything else.

  • tearDownRun: Will be executed last.

  • beforeStep: Will be executed before every step.

  • afterStep: Will be executed after every step.

  • setUpModel: Will be executed before executing any step from this model.

  • tearDownModel: Will be executed after executing all steps from this model.

All fixtures are optional.

When you define the beforeStep and afterStep fixtures within a model class, these fixtures will specifically apply to that particular model. In other words, they will only affect the steps executed within that model’s context. This provides a way to encapsulate and customize individual models, allowing you to fine-tune the behavior of these fixtures for each model independently.

# tests/test.py

def setUpRun():
    """Will be executed first, before anything else."""

def tearDownRun():
    """Will be executed last, after anything else."""

def beforeStep():
    """Will be executed before every step."""

def afterStep():
    """Will be executed after every step."""


class ModelA:

    def setUpModel(self):
        """Will be executed once before executing any step from this model."""

    def tearDownModel(self):
        """Will be executed once after executing all steps from this model."""

    def beforeStep():
        """Will be executed before every step from this model."""

    def afterStep():
        """Will be executed after every step from this model."""

    def vertex_a(self):
        pass

    def edge_a(self):
        pass

Define setUpRun, tearDownRun, beforeStep and afterStep inside a Setup class, and register it inside the executor service: ExecutorService.RegisterSetup<T>();

Define setUpModel, tearDownModel, beforeStep and afterStep inside the model class.

/// Program.cs
using Altom.AltWalker;

namespace Test.Project
{
    public class Setup
    {
        /// Will be executed first, before anything else.
        public void setUpRun() {}

        /// Will be executed last, after anything else.
        public void tearDownRun() {}

        /// Will be executed before every step.
        public void beforeStep() {}

        /// Will be executed after every step.
        public void afterStep() {}
    }

    /// The implementation of the model named ModelA.
    public class ModelA
    {
        /// Will be executed once before executing any steps from this model
        public void setUpModel() {}

        /// Will be executed once after executing all steps from this model
        public void tearDownModel() {}

        /// Will be executed before every step from this model.
        public void beforeStep() {}

        /// Will be executed after every step from this model.
        public void afterStep() {}
    }

    public class Program
    {
        public static void Main (string[] args)
        {
            ExecutorService service = new ExecutorService();

            service.RegisterSetup<Setup>();
            service.RegisterModel<ModelA>();

            service.Start(args);
        }
    }
}

Read/Update Graph Data#

If you are using the online command your test code has direct access to the graphs execution context provided by GraphWalker.

In order to read/update the graph data from your tests, you need to define the method with a parameter, and AltWalker will pass the graph data to your method. This method is a way of executing actions from you test code.

Updating the graph data can affect the path generation so this feature in not available in Offline Mode.

The second parameter will be a dict object, that object allows you to read and update the graph data.

def element_method(self, data):
    """A simple example of a method for a vertex/edge inside a model.

    Args:
        data: AltWalker will pass a ``dict`` object.
    """

    # to get the value for a single key
    value = data["key"]

    # to set a new value for a key
    data["strVariable"] = "new_value"
    data["intVariable"] = 1
    data["boolVariable"] = True

The second parameter will be a IDictionary<string, dynamic> object, that object allows you to read and update the graph data.

/// A simple example of a method for a vertex/edge inside a model.
public void element_method(IDictionary<string, dynamic> data)
{
    // to get the value for a single key
    string value = data["key"]

    // to set a new value for a key
    data["strVariable"] = "new_value"
    data["intVariable"] = 1
    data["boolVariable"] = true
}

Warning

Note that you can set keys to string, integer or boolean values, but GraphWalker will always return strings.

So you have to convert your values back to there type.

  • for integers

value = int(data["integer"])
int value = int.Parse(data["integer"]);
  • for boolean

value = data["boolean"] == "true"
bool value = data["boolean"] == "true";

Verify your code#

You can use the verify command to check your code against the models for issues.

$ altwalker verify tests -l python -m models/model-name.json
$ altwalker verify tests -l dotnet -m models/model-name.json