Skip to content

Migrating from dpytest

dpytest started this approach — faking the HTTP layer and injecting gateway events. simcord covers the modern surface dpytest never did (slash commands, components, modals, autocomplete, permissions with real error codes) and replaces its module-global API with explicit objects.

Concept mapping

dpytest simcord
dpytest.configure(bot) async with simcord.run(bot) as env: (or the simcord_env fixture)
dpytest.message("!ping") await alice.send(channel, "!ping")
dpytest.verify().message().content("Pong!") assert channel.last_message.content == "Pong!"
dpytest.get_config().guilds[0] env.guild / env.create_guild()
dpytest.member_join() guild.add_member(env.create_user("alice"))
dpytest.empty_queue() not needed — actors settle automatically
— (unsupported) alice.slash(...), alice.click(...), alice.submit_modal(...), …

Key differences

  • No global state. Everything hangs off the Env returned by simcord.run; multiple environments can coexist.
  • Explicit actors. Messages are sent by someone, from somewhere — which is what makes permission-sensitive bugs testable.
  • Assertions are plain Python against real discord.Message objects and backend state, with pytest's normal introspection — no verification builder DSL.
  • Strictness. Unsynced slash commands, disabled buttons, hidden channels and oversized payloads fail your tests, because they fail on Discord.

Next

  • Quickstart — wire SimCord into your project.
  • Core concepts — the builders/actors/queries model that replaces dpytest's globals.
  • Recipes — patterns for the tests you're porting.