npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

frida-test

v0.4.0

Published

frida-test is a small unit framework based on Frida. It is used to unit test Frida code running on actual devices.

Readme

frida-test Documentation

Test frida-test

This is a small test framework which runs on the target. It is used to unit test Frida code running on actual devices. It was originally developed to test the Frida agent code used in frooky.

The following chapters explain how to write and run tests.

Installation

npm install --save-dev frida-test

After the installation, import the type frida-test into your project by adding the following configuration to the tsconfig.json:

{
  "compilerOptions": {
    "types": ["frida-test"]
  }
}

Writing Tests

Tests follow the Behavior-Driven Development (BDD) pattern. They use the describe-it-expect structure to describe the expected behavior.

The basic syntax is:

  • describe(): Defines a test suite or a specific component's behavior.
  • test() or it(): Describes a specific requirement or expected outcome.
  • expect(): Validates that the actual output matches the expected behavior.
describe('Classloader', () => {
  it('should throw an exception if the class is not available.', () => {
    expect(() => {
      ClassLoader.loadSync('badClass')
    }).toThrow(new Error("Class 'badClass' is not available."));
  })
});

Tests can be nested to any depth and can be synchronous or asynchronous.

Matchers

expect(actualValue) returns a Matchers object which we can use to test for the expected value. Use the following functions to do that:

| Matcher | Description | | --- | --- | | .toBe(value) | Strict equality (===) | | .toEqual(value) | Deep equality | | .toBeTruthy() | Value is truthy | | .toBeFalsy() | Value is falsy | | .toBeNull() | Value is strictly null | | .toBeDefined() | Value is not undefined | | .toBeUndefined() | Value is undefined | | .toBeGreaterThan(value) | Numeric value is greater than value | | .toBeLessThan(value) | Numeric value is less than value | | .toContain(value) | Array, Set, or string contains value (array/Set items compared with ===) | | .toContainEqual(value) | Array or Set contains an item deeply equal to value | | .toThrow(errorMatch?) | Function throws; errorMatch can be a substring, a RegExp matched against the message, an Error instance (message equality only), or an Error class (instanceof check) | | .toHaveBeenCalled() | Mock/spy was called at least once | | .toHaveBeenCalledTimes(count) | Mock/spy was called exactly count times | | .toHaveBeenCalledWith(...expected) | Mock/spy was called (at any point) with the expected arguments | | .toHaveBeenLastCalledWith(...expected) | Mock/spy's most recent call had the expected arguments | | .toHaveBeenNthCalledWith(n, ...expected) | Mock/spy's nth call (1-indexed) had the expected arguments |

[!NOTE] frida-test tests itself. So for examples of all matchers and more, have a look at the *.test.ts files located in the test folder.

Modifiers

| Modifier | Description | | --- | --- | | .not | Inverts the assertion result, e.g. expect(2 + 2).not.toBe(5) | | .resolves | Unwraps a resolved promise so a matcher applies to its value; the assertion must be awaited. The received value must actually be a Promise - it fails otherwise | | .rejects | Unwraps a rejected promise so a matcher applies to its reason; the assertion must be awaited. The received value must actually be a Promise - it fails otherwise |

await expect(fetchUser(1)).resolves.toEqual({ id: 1, name: 'Ada' });
await expect(fetchUser(-1)).rejects.toThrow('not found');

// modifiers compose:
await expect(fetchUser(1)).resolves.not.toBeNull();

Mocking

frida-test mocks and spies follow the same API shape as Jest's mock functions.

  • fn(implementation?): creates a standalone mock function, optionally backed by implementation.
  • spyOn(object, methodName): replaces object[methodName] with a mock that calls through to the original method by default, and can be restored later.

Both forms return the same Mock type:

const mock = fridaTest.fn((a: number, b: number) => a + b);
mock(1, 2);

expect(mock).toHaveBeenCalledWith(1, 2);
mock.mock.calls;       // [[1, 2]]
mock.mock.results;     // [{ type: "return", value: 3 }]

mock.mockReturnValue(42);       // set a default return value
mock.mockReturnValueOnce(99);   // ...for just the next call
mock.mockResolvedValue(value);  // wraps value in Promise.resolve()
mock.mockRejectedValue(error);  // wraps error in Promise.reject()
mock.mockImplementation(impl);    // replace the implementation
mock.mockImplementationOnce(impl); // ...for just the next call

mock.mockClear();   // reset calls/results, keep the implementation
mock.mockReset();   // reset calls/results and drop the implementation
mock.mockRestore(); // reset like mockReset(); for spyOn(), also restores the original method
describe('Logger', () => {
  it('should call the underlying console method', () => {
    const spy = fridaTest.spyOn(console, 'log').mockImplementation(() => undefined);
    logMessage('hello');
    expect(spy).toHaveBeenCalledWith('hello');
    spy.mockRestore();
  });
});

Setup and Teardown

Use beforeEach() / afterEach() and beforeAll() / afterAll() to run code before or after tests. They can be declared at the top level of a file or inside a describe() block:

  • beforeEach() / afterEach(): Run before/after every it() in the same and nested describe() blocks.
  • beforeAll() / afterAll(): Run once before/after all tests in the same describe() block (or, at the top level, once before/after the whole file).

Hooks declared in an outer describe() also apply to tests in nested describe() blocks. beforeEach hooks run outer-to-inner; afterEach hooks run inner-to-outer.

describe('ClassLoader', () => {
  let loader: ClassLoader;

  beforeAll(() => {
    loader = new ClassLoader();
  });

  beforeEach(() => {
    loader.reset();
  });

  afterEach(() => {
    loader.clearCache();
  });

  afterAll(() => {
    loader.destroy();
  });

  it('should load a known class', () => {
    expect(loader.load('com.example.Foo')).toBeDefined();
  });
});

Running Tests

frida-test takes one or more directories, collects every *.test.ts file below them, compiles them together with the framework agent, and runs the resulting agent on the target.

frida-test [options] <dir...>

Options

| Option | Description | | --- | --- | | -D, --device <id> | Connect to device with the given ID | | -U, --usb | Connect to USB device | | -R, --remote | Connect to remote frida-server | | -H, --host <host> | Connect to remote frida-server on HOST | | --certificate <cert> | Speak TLS with HOST, expecting CERTIFICATE | | --origin <origin> | Connect to remote server with "Origin" header set to ORIGIN | | --token <token> | Authenticate with HOST using TOKEN | | --keepalive-interval <interval> | Set keepalive interval in seconds, or 0 to disable (defaults to -1) | | -f, --file <target> | Spawn FILE | | -F, --attach-frontmost | Attach to frontmost application | | -n, --attach-name <name> | Attach to NAME | | -N, --attach-identifier <id> | Attach to IDENTIFIER | | -p, --attach-pid <pid> | Attach to PID | | -o, --out <path> | Path of the output file for JSON reporter (default: disabled) | | -t, --timeout <s> | Abort the run after this many seconds (default: 600, 0 disables) | | -d, --delay <s> | Start running the test suites after this many seconds (default: 0) | | -k, --keep | Keep the generated agent in .frida-test/agent.js | | -v, --verbose | Enable verbose logging | | -h, --help | Shows the help message |

frida-test Examples

# Spawn an Android app on a USB device, tests in ./tests/android and ./tests/shared
frida-test -U -f org.owasp.mastestapp ./tests/android ./tests/shared

# Attach to a running process by PID on a USB device
frida-test -U -p 4926 ./tests/android

# Attach to a running iOS app by identifier
frida-test -U -N org.owasp.mastestapp.MASTestApp-iOS ./tests/ios ./tests/shared

# Connect to a remote frida-server on HOST with authentication
frida-test -H 192.168.1.10:27042 --token secret -p 4926 ./tests/shared

Compiling the Agent

frida-test automatically bundles the test suites and compiles them together with the testing framework into a Frida agent.

If you only want to compile this agent, use frida-test-compile:

frida-test-compile [options] <dir...>

| Option | Description | | --- | --- | | -o, --out <path> | Path of the output file for JSON reporter (default: disabled) | | -h, --help | Shows the help message |

frida-test-compile Examples

# Collects all tests in ./tests, compiles the frida-test agent, and prints it to stdout
frida-test-compile ./tests

# Collects all tests in ./tests, compiles the frida-test agent, and stores it in ./frida-test-agent.js
frida-test-compile ./tests -o ./frida-test-agent.js