mongo/jstests
Evan Bergeron 005ea9599c SERVER-127007 Add server status metric for path arrayness invalidation (#54071)
GitOrigin-RevId: 4ffd1618d653049063090c7f61bc2e9763a9ae65
2026-05-26 23:35:24 +00:00
..
aggregation SERVER-124332 Populate sampling information into explain (#54416) 2026-05-26 16:15:33 +00:00
auth SERVER-127233 Introduce stub recipient fetch final collection stats command (#54169) 2026-05-26 18:32:59 +00:00
change_stream_fsm SERVER-125560 rename coordinator white box testing (#52682) 2026-05-04 16:27:55 +00:00
change_streams SERVER-111075 Enable passing disagg suites to run with TSAN on the waterfall (#53525) 2026-05-20 16:45:06 +00:00
client_encrypt SERVER-110991 Rename query-integration-extensions to query-integration-features (#41505) 2025-09-19 14:16:28 +00:00
concurrency SERVER-127519: Temporarily exclude additional test in multiversion setup (#54423) 2026-05-26 14:41:59 +00:00
core SERVER-127233 Introduce stub recipient fetch final collection stats command (#54169) 2026-05-26 18:32:59 +00:00
core_sharding SERVER-121178 Implement split as a coordinator (#51941) 2026-05-11 15:16:44 +00:00
core_standalone SERVER-109432: Autofix JS var usage to favor let (#40637) 2025-08-28 19:21:01 +00:00
decimal SERVER-109432: Autofix JS var usage to favor let (#40637) 2025-08-28 19:21:01 +00:00
disk SERVER-123900 Block running failing MozJS tests against a WASM-enabled server (#52296) 2026-04-28 18:50:33 +00:00
extensions SERVER-127113: Add bazel targets for extension resmoke suites (#54033) 2026-05-20 18:20:34 +00:00
fail_point SERVER-109432: Autofix JS var usage to favor let (#40637) 2025-08-28 19:21:01 +00:00
fle2 SERVER-124174 Replace FLE2 prefix/suffix preview types with GA types in jstests and unit tests (#52170) 2026-04-21 22:04:54 +00:00
hooks SERVER-125120 Remove unused connecting to random secondaries in testing (#52421) 2026-04-23 08:03:33 +00:00
httpinterface SERVER-109432: Autofix JS var usage to favor let (#40637) 2025-08-28 19:21:01 +00:00
libs SERVER-127233 Introduce stub recipient fetch final collection stats command (#54169) 2026-05-26 18:32:59 +00:00
libunwind SERVER-108478 JS formatted by prettier and remove clang-format (#39656) 2025-08-21 17:27:09 +00:00
multiVersion SERVER-125888 Gossip lastStableRecoveryTimestamp between repl members. (#53168) 2026-05-20 15:40:45 +00:00
noPassthrough SERVER-127007 Add server status metric for path arrayness invalidation (#54071) 2026-05-26 23:35:24 +00:00
noPassthroughWithMongod SERVER-124332 Populate sampling information into explain (#54416) 2026-05-26 16:15:33 +00:00
ocsp SERVER-120035 Add bazel targets for release-critical, security resmoke suites (#50060) 2026-03-24 21:56:11 +00:00
product_limits SERVER-122257 Revert number of lookup-unwind stages in product limits test (#52586) 2026-04-28 18:47:38 +00:00
query_golden SERVER-127282: Handle open-ended date IXSCAN bounds in plan_stability reconstruction (#54145) 2026-05-22 18:03:37 +00:00
query_golden_sharding SERVER-73120 Remove recordRemoteOpWaitTime from IDL (#53913) 2026-05-19 07:24:08 +00:00
readonly SERVER-93383 Test readOnly parameter on $listClusterCatalog (#50384) 2026-03-27 08:31:39 +00:00
replsets SERVER-127233 Introduce stub recipient fetch final collection stats command (#54169) 2026-05-26 18:32:59 +00:00
resmoke_selftest SERVER-124481: Team Rename: DevProd Test Infrastructure (#52100) 2026-04-28 20:09:30 +00:00
selinux SERVER-118537 Always apply SELinux policy before installing mongodb package on SELinux tests (#47304) 2026-02-02 17:25:16 +00:00
serial_run SERVER-123900 Block running failing MozJS tests against a WASM-enabled server (#52296) 2026-04-28 18:50:33 +00:00
serverless SERVER-109700 Deprecate replication.serverless config (#41363) 2025-09-24 17:49:52 +00:00
sharding SERVER-126219 Add timeseries variant of resharding retryable writes test (#54056) 2026-05-26 22:11:46 +00:00
slow1 SERVER-104487 Exclude slow1 suite from macos variants (#44291) 2025-12-03 22:16:14 +00:00
ssl SERVER-125887 Add support for encrypted PEM files for gRPC egress (#53238) 2026-05-07 20:21:29 +00:00
ssl_linear SERVER-121821 Load test certs separately for macOS on ssl_modes_not_disabled_ingress.js (#49788) 2026-03-17 21:04:42 +00:00
ssl_x509 SERVER-121258 Fix mechanism map initialization for egress (#50311) 2026-04-01 18:37:37 +00:00
sslSpecial SERVER-79980 Windows TLS 1.3 support (#52302) 2026-04-29 17:09:15 +00:00
suites SERVER-127361: Add bazel targets for replication resmoke suites (#54144) 2026-05-22 14:56:40 +00:00
third_party SERVER-121339: Vendor fast-check@4.6.0 (#49338) 2026-03-12 21:31:06 +00:00
watchdog SERVER-109432: Autofix JS var usage to favor let (#40637) 2025-08-28 19:21:01 +00:00
with_mongot SERVER-127113: Add bazel targets for extension resmoke suites (#54033) 2026-05-20 18:20:34 +00:00
write_path SERVER-123693 Extend mixed schema PBT to more comprehensive rollover PBT (#51603) 2026-04-14 19:46:14 +00:00
AGENTS.md SERVER-125920 Introduce jstests-local CLAUDE.md (#53103) 2026-05-13 15:28:11 +00:00
CLAUDE.md SERVER-125920 Introduce jstests-local CLAUDE.md (#53103) 2026-05-13 15:28:11 +00:00
global.d.ts SERVER-121775: prettier-format .d.ts files (#49701) 2026-03-17 22:41:27 +00:00
OWNERS.yml SERVER-125920 Introduce jstests-local CLAUDE.md (#53103) 2026-05-13 15:28:11 +00:00
README.md SERVER-124136 Format markdown via prettier: wrap lines and use width of 100 (#52231) 2026-04-21 19:20:11 +00:00
tags.md SERVER-124136 Format markdown via prettier: wrap lines and use width of 100 (#52231) 2026-04-21 19:20:11 +00:00

Javascript Test Guide

At MongoDB we write integration tests in JavaScript. These are tests written to exercise some behavior of a running MongoDB server, replica set, or sharded cluster. This guide aims to provide some general guidelines and best practices on how to write good tests.

Principles

Minimize the test case as much as possible while still exercising and testing the desired behavior.

  • For example, if you are testing that document deletion works correctly, it may be entirely sufficient to insert just a single document and then delete that document. Inserting multiple documents would be unnecessary. A guiding principle on this is to ask yourself how easy it would be for a new person coming to this test to quickly understand it. If there are multiple documents being inserted into a collection, in a test that only tests document deletion, a newcomer might ask the question: “is it important that the test uses multiple documents, or incidental?”. It is best if you can remove these kinds of questions from a persons mind, by keeping only the absolute essential parts of a test.
  • We should always strive for unittesting when possible, so if the functionality you want to test can be covered by a unit test, we should write a unit test instead.

Add a block comment at the top of the JavaScript test file giving a clear and concise overview of what a test is trying to verify.

  • For tests that are more complicated, a brief description of the test steps might be useful as well.

Keep debuggability in mind.

  • Assertion error messages should contain all information relevant to debugging the test. This means the servers response from the failed command should almost always be included in the assertion error message. It can also be helpful to include parameters that vary during the test to avoid requiring the investigator to use the logs/backtrace to determine what the test was attempting to do.
  • Think about how easy it would be to debug your test if something failed and a newcomer only had the logs of the test to look at. This can help guide your decision on what log messages to include and to what level of detail. The jsTestLog function is useful for this, as it is good at visually demarcating different phases of a test. As a tip, run your test a few times and just study the log messages, imagining you are an engineer debugging the test with only these logs to look at. Think about how understandable the logs would be to a newcomer. It is easy to add log messages to a test but then forget to see how they would actually appear.
  • Never insert identical documents unless necessary. It is very useful in debugging to be able to figure out where a given piece of data came from.
  • If a test does the same thing multiple times, consider factoring it out into a library. Shorter running tests are easier to debug and code duplication is always bad.

Do not hardcode collection or database names, especially if they are used multiple times throughout a test.

It is best to use variable names that attempt to describe what a value is used for. For example, naming a variable that stores a collection named collectionToDrop is much better than just naming the variable collName.

Make every effort to make your test as deterministic as possible.

  • Non-deterministic tests add noise to our build system and, in general, make it harder for yourself and other engineers to determine if the system really is working correctly or not. Flaky integration tests should be considered bugs, and we should not allow them to be committed to the server codebase. One way to make jstests more deterministic is to use failpoints to force the events happening in expected order. However, if we have to use failpoints to make this test deterministic, we should consider write a unit test instead.
  • Note that our fuzzer and concurrency test suites are often an exception to this rule. In those cases we sometimes give up some level of determinism in order to trigger a wider class of rare edge cases. For targeted JavaScript integration tests, however, highly deterministic tests should be the goal.

Think hard about all the assumptions that the test relies on.

  • For example, if a certain phase of the test ran much slower or much faster, would it cause your test to fail for the wrong reason?
  • If your test includes hard-coded timeouts, make sure they are set appropriately. If a test is waiting for a certain condition to be true, and the test should not proceed until that condition is met, it is often correct to just wait “indefinitely”, instead of adding some arbitrary timeout value, like 30 seconds. In practice this usually means setting some reasonable upper limit, for example, 10 minutes.
  • Also, for replication tests, make sure data exists on the right nodes at the right time. For example, if you a do a write and dont explicitly wait for it to replicate, it might not reach a secondary node before you try to do the next step of the test.
  • Does your test require data to be stored persistently? Remember that we have test variants that run on in-memory/ephemeral storage engines
  • There are timeouts in the test suites and we aim to make all tests in the same suite finish before timeout. That says we should always make the test run quickly to keep the test short in terms of duration.

Make tests fail as early as possible.

  • If something goes wrong early in the test, its much harder to diagnose when that error becomes visible much later.
  • Wrap every command in assert.commandWorked, or assert.commandFailedWithCode. There is also assert.commandFailed that won't check the return error code, but we should always try to use assert.commandFailedWithCode to make sure the test won't pass on an unexpected error.

Be aware of all the configurations and variants that your test might run under.

  • Make sure that your test still works correctly if is run in a different configuration or on a different platform than the one you might have tested on.
  • Varying storage engines and suites can often affect a tests behavior. For example, maybe your test fails unexpectedly if it runs with authentication turned on with an in-memory storage engine. You dont have to run a new test on every possible platform before committing it, but you should be confident that your test doesnt break in an unexpected configuration.

Avoid assertions that verify properties indirectly.

All assertions in a test should attempt to verify the most specific property possible. For example, if you are trying to test that a certain collection exists, it is better to assert that the collections exact name exists in the list of collections, as opposed to verifying that the collection count is equal to 1. The desired collections existence is sufficient for the collection count to be 1, but not necessary (a different collection could exist in its place). Be wary of adding these kind of indirect assertions in a test.

Test Isolation

Your JS test will likely be running with many other files before and after it. It's important to start from a known state, and to restore that state (to a reasonable extent) at the end of your test content.

  • Before: If there are critical assumptions about the environment that your test needs, assert for it explicitly before proceeding to the real test content (instead of debugging side effects of that not being the case)
    • If you have a precondition on the environment, use @tags instead of just an early-return. This will avoid the test being scheduled in the first place if the environment is not supported.
  • After: If you are modifying the fixture, do everything possible to safely restore those changes at the end of your test content, even after a test failure. Resmokes' --continueOnFailure flag is used in CI, so the fixture is shared across many test files, and is only torn down at the end.
    • Note, a fixture can immediately "abort" after a test failure, only if archiving is configured, but that shouldn't be assumed because that is a per-suite configuration (and your test can run in many passthrough suite combinations).
    • One easy approach to restoring your state is to use the Mocha-style after hooks in your test content.

Modern JS: Modules in Practice

We have fully migrated to the modularized JavaScript world so any new test should use modules and adapt the new style.

Only import/export what you need.

It's always important to keep the test context clean so we should only import/export what we need.

  • The unused import is against no-unused-vars rule in ESLint though we haven't enforced it.
  • We don't have a linter to check export since it's hard to tell the necessity, but we should only export the modules that are imported by other tests or will be needed in the future.

Declare variables in proper scope.

In the past, we have seen tests referring some "undeclared" or "redeclared" variables, which are actually introduced through load(). Now with modules, the scope is more clear. We can use global variables properly to setup the test and don't need to worry about polluting other tests.

Name variables properly when exporting.

To avoid naming conflicts, we should not make the name of exported variables too general which could easily conflict with another variable from the test which import your module. For example, in the following case, the module exported a variable named alphabet and it will lead to a re-declaration error.

import {alphabet} from "/matts/module.js";
const alphabet = "xyz"; // ERROR

Prefer let/const over var

let/const should be preferred over var since these can help detect double declaration at the first place. Like, in the naming conflict example, if the second line is using var, it could easily mess up without throwing an error.

Export in ES6 style

Due to legacy, we have a lot of code that is using the old style to do export, like the following.

const MyModule = (function() {
  function myFeature() {}
  function myOtherFeature() {}

  return {myFeature, myOtherFeature};
})();

Instead, we should use the ES6 way to do export, as follows.

export function myFeature() {}
export function myOtherFeature() {}

// When import from test
import * as MyModule from "/path/to/my_module.js";

This can help the language server to discover the methods and provide code navigation for it.

Use Mocha-style Constructs

The mochalite.js library ports over a subset of MochaJS functionality for the shell, including:

  • it test contruction
  • describe suite structures
  • it.only and describe.only to run only those suites and tests
  • it.skip and describe.skip to skip those suites and tests
  • before and after hooks, to run once around all it tests
  • beforeEach and afterEach hooks, to run around each it test
  • The above (excluding describe variants) also support async functions
  • Resmoke test filtering using the --mochagrep flag, which mirrors the grep flag from MochaJS

Example using several APIs:

import {after, afterEach, before, beforeEach, describe, it} from "jstests/libs/mochalite.js";

describe("simple inserts and finds", () => {
  before(() => {
    this.fixtureDB = startupNewDB();
  });
  beforeEach(() => {
    this.fixtureDB.seed();
  });
  afterEach(async () => {
    await this.fixtureDB.clear();
  });
  after(() => {
    this.fixtureDB.shutdown();
  });
  it("should do something", () => {
    this.fixtureDB.insert({name: "test"});
    assert.eq(this.fixtureDB.find({name: "test"}).count(), 1);
  });
  it("should error on invalid data", () => {
    const e = assert.throws(() => this.fixtureDB.insert({notafield: undefined}));
    assert.eq(e.message, "Field 'notafield' not found");
  });
});

Use it.only to run just the one test (eg. during debugging):

it.only("should do something", () => {
  this.fixtureDB.insert({name: "test"});
  assert.eq(this.fixtureDB.find({name: "test"}).count(), 1);
});

or use the filter from resmoke to avoid any file edits:

buildscripts/resmoke.py run --suites=no_passthrough --mochagrep "do something" jstests/noPassthrough/mytest.js

Test Tags

JS Test files can leverage "tags" that suites can key off of to include and/or exclude as necessary. Not scheduling a test to run is much faster than the test doing an early-return when preconditions are not met.

The simplest use case is having something like the following at the top of your js test file:

/**
 * Tests for the XYZ feature
 * @tags: [requires_fcv_81]
 */

See tags.md for more details.