DEV Community

Mickey Streicher
Mickey Streicher

Posted on • Edited on

Vedro Hooks

Vedro offers powerful extensibility through its plugin system, allowing you to create robust, reusable solutions that can be shared across different projects and teams. But what if you're just experimenting with your codebase, prototyping a concept, or adding a small tweak? Writing a full plugin might feel like overkill. That’s where vedro-hooks comes in.

vedro-hooks is a lightweight library that lets you attach custom hooks to various Vedro events. Whether you're starting a mock server before tests run, launching a browser for end-to-end testing or setting up custom logging, vedro-hooks enables you to inject functionality with minimal boilerplate.

A Practical Example

Suppose you want to identify slow tests in your suite — let's define "slow" as any test that takes longer than 1 second to run. Traditionally, you’d need to create a custom plugin for this. Here’s how that might look:

from vedro.core import Dispatcher, Plugin, PluginConfig
from vedro.events import ScenarioFailedEvent, ScenarioPassedEvent

class SlowTestPlugin(Plugin):
    def subscribe(self, dispatcher: Dispatcher):
        dispatcher.listen(ScenarioPassedEvent, self.on_scenario_end)
        dispatcher.listen(ScenarioFailedEvent, self.on_scenario_end)

    def on_scenario_end(self, event: ScenarioPassedEvent | ScenarioFailedEvent):
        elapsed = event.scenario_result.elapsed
        if elapsed > 1.0:
            event.scenario_result.add_extra_details("⚠️ Slow test!")

class SlowTestPluginConfig(PluginConfig):
    plugin = SlowTestPlugin
Enter fullscreen mode Exit fullscreen mode

This approach works, but creating a full-fledged plugin involves more setup and additional boilerplate. It’s great for reusable solutions but can feel cumbersome for quick experimentation.

Simplifying with Hooks

With vedro-hooks, you can achieve the same functionality with just a few lines of code:

from vedro_hooks import on_scenario_passed, on_scenario_failed

@on_scenario_passed
@on_scenario_failed
def highlight_slow_tests(event):
    elapsed = event.scenario_result.elapsed
    if elapsed > 1.0:
        event.scenario_result.add_extra_details("⚠️ Slow test!")
Enter fullscreen mode Exit fullscreen mode

This code uses decorators to register a function that will be called when a scenario passes or fails. It checks the elapsed time and adds extra details if the scenario took longer than 1 second.

Scenarios
*
 ✔ retrieve user info (0.52s)
 ✔ retrieve user repos (1.02s)
   |> ⚠️ Slow test!

# 2 scenarios, 2 passed, 0 failed, 0 skipped (1.54s)
Enter fullscreen mode Exit fullscreen mode

Managing Hooks: Downsides and Solutions

One downside of using hooks in this way is that they can be registered from anywhere in your project, which might make them harder to track down later. In contrast, plugins in Vedro are registered in the vedro.cfg.py file, providing a centralized location for all your plugin configurations.

To help mitigate the downside of hooks being registered throughout your codebase, vedro-hooks provides the --hooks-show command-line argument. When enabled, after the testing process completes, a summary of all registered hooks along with their source locations will be displayed. This is useful for debugging and verifying which hooks are active.

Scenarios
*
 ✔ retrieve user repos

# [vedro-hooks] Hooks:
#  - 'highlight_slow_tests' (ScenarioFailedEvent) vedro.cfg.py:26
#  - 'highlight_slow_tests' (ScenarioPassedEvent) vedro.cfg.py:26
# 1 scenario, 1 passed, 0 failed, 0 skipped (0.55s)
Enter fullscreen mode Exit fullscreen mode

While --hooks-show is helpful, you need to remember to use it during debugging. It's still best practice to register your hooks in a central location like vedro.cfg.py to maintain clarity and consistency with plugins configurations.

Conclusion

vedro-hooks is a fantastic tool for enhancing your Vedro tests without the overhead of creating a custom plugin. It shines when you need a quick, focused solution for extending functionality. By using it wisely and keeping your configuration organized, you can enjoy the best of both worlds: simplicity and maintainability.

Top comments (0)