For Users of NYRA framework

Standalone Testing of Extensions

The NYRA framework offers a standalone extension testing mechanism that lets you test an extension in isolation. This is especially helpful when you need to verify an extension’s behavior without running the entire NYRA app or dealing with other extensions or graphs.

Key Principles

  1. Works with any native testing framework for the target language

    • For instance, if your NYRA extension is written in C++, you can pair the NYRA standalone testing mechanism with Google Test (gtest/gmock) to test your extension independently.

  2. No code changes to the extension under test

    • The exact same extension code you use at runtime can be tested by the standalone testing framework without modification.

The standalone testing process is designed to be language-agnostic, meaning the approach for C++, Go, Python, etc., is fundamentally the same. Once you learn it in one language, you can easily adapt it to others.

Main Concepts

  • extension_tester Acts like a “test driver,” organizing and running the test flow.

  • nyra_env_tester Behaves like a typical NYRA “nyra_env” instance in a real runtime scenario, but specifically for tests. You can use it to send messages to the extension under test and receive messages from it.

Although extension_tester and nyra_env_tester are conceptually similar to the real extension and nyra_env, they’re purely for testing. This separation prevents test-only APIs from cluttering the production runtime APIs.

Internal Mechanics

Under the hood, the NYRA standalone testing framework:

  1. Starts a hidden “test app.”

  2. Loads the extension add-on that you want to test.

  3. Automatically creates a tiny graph containing:

    • Extension A: The extension under test.

    • Extension B: A special “testing” extension that proxies all input/output messages to and from Extension A.

Thus, Extension B acts as a middleman, letting you feed messages to Extension A and observe the results without a full NYRA environment running.

Basic Testing Process

  1. Create an extension_tester to manage the standalone test flow.

  2. Tell the testing framework where your extension’s folder is located.

  3. Set a testing mode (e.g., single-extension test).

  4. Run the test.


C++ Example (Using Google Test)

#include <gtest/gtest.h>
#include "nyra/extension_tester.hpp"
#include "nyra/nyra_env_tester.hpp"
// ... other includes as needed ...

class extension_tester_basic : public nyra::extension_tester_t {
 public:
  void on_start(nyra::nyra_env_tester_t &nyra_env) override {
    auto new_cmd = nyra::cmd_t::create("hello_world");
    nyra_env.send_cmd(std::move(new_cmd),
                      [](nyra::nyra_env_tester_t &nyra_env,
                         std::unique_ptr<nyra::cmd_result_t> result) {
                        if (result->get_status_code() == NYRA_STATUS_CODE_OK) {
                          nyra_env.stop_test();
                        }
                      });
  }
};

TEST(Test, Basic) {
  // 1. Create an extension tester to manage the entire standalone testing process.
  auto *tester = new extension_tester_basic();

  // 2. Inform the standalone testing framework of the folder containing the extension to be tested.
  nyra_string_t *path = nyra_path_get_executable_path();
  nyra_path_join_c_str(path, "../nyra_packages/extension/default_extension_cpp/");
  tester->add_addon_base_dir(nyra_string_get_raw_str(path));
  nyra_string_destroy(path);

  // 3. Set a testing mode, such as a mode for testing a single extension.
  tester->set_test_mode_single("default_extension_cpp");

  // 4. Start the testing.
  tester->run();

  delete tester;
}

Golang Example

TODO: To be added.


Python Example

from nyra.extension_tester import ExtensionTester
from nyra.nyra_env_tester import NyraEnvTester
from nyra.cmd import Cmd, CmdResult, StatusCode
from pathlib import Path

class ExtensionTesterBasic(ExtensionTester):
    def check_hello(self, nyra_env: NyraEnvTester, result: CmdResult):
        status_code = result.get_status_code()
        print("received hello_world, status:", status_code)

        if status_code == StatusCode.OK:
            nyra_env.stop_test()

    def on_start(self, nyra_env: NyraEnvTester) -> None:
        new_cmd = Cmd.create("hello_world")

        print("send hello_world")
        nyra_env.send_cmd(
            new_cmd,
            lambda nyra_env, result: self.check_hello(nyra_env, result),
        )

        print("tester on_start_done")
        nyra_env.on_start_done()


def test_basic():
    # 1. Create an extension tester to manage the entire standalone testing process.
    tester = ExtensionTesterBasic()

    # 2. Inform the standalone testing framework of the folder containing the extension to be tested.
    tester.add_addon_base_dir(str(Path(__file__).resolve().parent.parent))

    # 3. Set a testing mode, such as a mode for testing a single extension.
    tester.set_test_mode_single("default_extension_python")

    # 4. Start the testing.
    tester.run()

With this standalone testing framework, you can quickly verify an extension’s functionality in isolation, using your language’s favorite testing tools, without starting an entire NYRA app or manually orchestrating other extensions.

Last updated