Lua Scripting
This guide introduces Lua basics and shows how to use Lua scripts with Drift. Drift embeds a Lua 5.4 runtime, so you can write small scripts for setup, teardown, or dynamic data.
Why Lua?
Lua is an excellent choice for embedded scripting
Lightweight and fast. Lua is one of the fastest scripting languages and has minimal overhead, making it ideal for performance-sensitive testing workflows.
Designed for Embedding. Lua was built to be embedded in other applications, not run standalone - perfect for integrating test automation logic.
Simple Syntax. Easy to learn, even for those unfamiliar with it. No complex type system or heavy boilerplate.
Small Footprint. The entire runtime is small and self-contained, with no external dependencies.
Event-Driven. Naturally suited for hook-based systems like Drift's lifecycle events.
With Lua, you get an automation layer without the complexity or overhead of larger scripting ecosystems.
If declarative YAML already covers your use case, you may not need Lua for your test suite.
Hello World (and Drift Context)
A minimal Lua script:
print("Hello, Drift!")In Drift, your Lua file typically returns an export table (even if it only prints), so keep this structure in mind:
local exports = {
event_handlers = {
["operation:started"] = function(event, data)
print("Hello from operation:started")
end
},
exported_functions = {
-- e.g. bearer_token = bearer_token
}
}
return exportsKey Lua Syntax (quick intro)
-- Comments start with two dashes
local message = "hello" -- local variable
local function greet(name)
return "Hello, " .. name
end
local t = {
name = "drift",
numbers = {1, 2, 3}
}
print(greet(t.name))For the full language reference, see the Lua 5.4 Manual.
Using LuaRocks Modules
Pure Lua modules dramatically expand your scripting capabilities. With LuaRocks, you can install third-party Lua packages for JSON handling, date manipulation, string utilities, HTTP requests, and more -all without native dependencies.
Installation and Usage
luarocks install dkjson
local json = require("dkjson")
local payload = {status = "ok"}
print(json.encode(payload))Useful Pure-Lua Modules
Here are some commonly used pure-Lua modules that work well in Drift:
Note
Built-in HTTP Drift provides a native http() client that automatically handles JSON and authentication. See the Lua API reference for details.
For a full directory of pure-Lua modules, browse LuaRocks.org and filter by modules without native dependencies.
Example: Data Transformation in a Test Hook
local json = require("dkjson")
local exports = {
event_handlers = {
["operation:started"] = function(event, data)
-- Transform or validate test data before the request
if data.parameters and data.parameters.request then
local payload = data.parameters.request.body
if payload then
print("Sending: " .. json.encode(payload))
end
end
end
}
}
return exportsMaking Modules Available to Drift
Install LuaRocks modules into the same environment used by Drift, or point Drift to the LuaRocks tree by setting LUA_PATH and LUA_CPATH.
# Example: add a LuaRocks tree to the search path export LUA_PATH="$HOME/.luarocks/share/lua/5.4/?.lua;$HOME/.luarocks/share/lua/5.4/?/init.lua;;" export LUA_CPATH="$HOME/.luarocks/lib/lua/5.4/?.so;;"
Limitations (and Workarounds)
Native dependencies. Lua modules that require native libraries (e.g., .so, .dll) are not supported in all environments and can fail to load.
Workaround: Use pure-Lua modules where possible.
Heavy runtime logic. Drift’s embedded Lua is intended for lightweight automation.
Workaround: Push complex logic into a separate service or script, then call it over HTTP from Lua.
External tooling. If you need Node.js or Python libraries, run them outside of Drift and invoke them via your CI scripts or local tooling.
Example: generate tokens or test data with Node/Python, then pass values to Drift as environment variables or datasets.
Best Practices
Keep scripts small: Use Lua as glue, not as a full application layer.
Prefer datasets: Store structured data in datasets instead of generating large objects in Lua.
Use event hooks sparingly: Only add logic at operation:started or operation:finished when necessary.
Avoid hidden state: Keep logic deterministic and easy to debug.
For larger workflows and integration patterns, see: