Tests with several sessions or requests#

The repeat rules count how often something happens. By default they count over the whole test, and a test that makes several independent requests then looks like a loop although nothing loops:

def test_five_requests(client, org):
    for _ in range(5):
        client.get(f"/orgs/{org.id}")   # each request: its own Session, the
                                        # same authentication lookup

Every request opens its own Session, runs the same lookups, and closes it. The statement runs five times in the test and once in each request.

The option#

[tool.pytest.ini_options]
queryguard_repeat_scope = "session"
Value What is counted together
test (default) Everything the test runs, as in 0.3.
session The statements, lazy loads, column loads and writes of one scope. A finding needs one scope to reach the threshold.

It applies to four kinds: repeated-statement (also the small-repeat rule), relationship-load, column-load and write-loop. missing-index and unused-eager-load do not count occurrences and are not affected. The default stays test, so an upgrade changes nothing until you set the option.

With test, a finding whose occurrences come from more than one scope says so:

  the same statement ran 9 times across 8 different Sessions or connection checkouts
  first at app/auth.py:31 in current_user
  kind: repeated-statement  label: SELECT users.id FROM users WHERE users.token = ?
  note: if each belongs to a separate request or unit of work, this is not a
  loop; set queryguard_repeat_scope = session to count each Session on its
  own (QueryLog.assert_no_nplusone: repeat_scope='session')

With session, the message says ran 6 times in one Session or connection checkout, and the count is the largest one scope has. The identity of a finding (kind, label, file and function) and the baseline format do not change.

QueryLog.assert_no_nplusone(repeat_scope="session") does the same for a recorded block; like the thresholds it does not read the ini option.

How the scope is decided#

Limits#

Edit this page on GitHub